npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@iyulab/enterprise

v0.10.2

Published

Enterprise utilities and components for iyulab framework

Readme

@iyulab/enterprise

iyulab 프레임워크의 엔터프라이즈 통합 패키지. 폼 레이아웃 컴포넌트·API 설정·도메인 헬퍼를 제공합니다.

Installation

npm install @iyulab/enterprise

무엇을 제공하나

1. 고유 export (enterprise에서만 제공)

| Export | 종류 | 용도 | |--------|------|------| | FormSection | React | 제목 + 세로 스택 폼 섹션 | | FormRow | React | 2컬럼 그리드 폼 행(full로 1컬럼) | | ApiConfig | class | baseUrl/OData·API prefix·dev 판별 중앙 설정 | | createODataService | factory | OData v4 + custom REST CRUD 서비스(401·토스트·에러파싱) | | ApiError | class | HTTP status 를 실은 API 호출 실패 에러 | | createAuthClient | factory | 쿠키 세션 인증(fetchMe/login/logout) — 제네릭 user/자격증명 | | createPermissionStore · hasPermission 외 | store | 권한 스냅샷 store + 판정 free 함수 | | CurrencyHelper | class | 통화 포맷(formatKRW 등) | | DateHelper | class | 날짜 포맷/파싱 | | ProgressHelper | class | 진행률 계산 | | UrgencyHelper | class | 긴급도 계산 |

2. 심볼 출처 (v0.3.0부터 하위 패키지 재노출 제거됨)

@iyulab/enterprise자기 고유 export만 제공합니다(위 표). @iyulab/components(컴포넌트), @iyulab/data-components(데이터 그리드/시트), @iyulab/modern-app(앱 프레임워크, 라우팅)은 각 패키지에서 직접 import하세요.

v0.2.x까지는 위 3개 패키지를 export *로 재노출했으나, 심볼 출처 혼란과 exact-pin(v0.2.2 이전) 조합 시 이중 인스턴스 위험 때문에 v0.3.0에서 제거했습니다. 재노출에 의존하던 코드는 @iyulab/enterprise가 아닌 각 하위 패키지에서 직접 import하도록 수정해야 합니다.

Usage

폼 레이아웃 (React)

import { FormSection, FormRow } from '@iyulab/enterprise'

<FormSection title="기본 정보">
  <FormRow>
    <u-input label="이름" />
    <u-input label="코드" />
  </FormRow>
  <FormRow full>
    <u-textarea label="비고" />
  </FormRow>
</FormSection>
  • FormRow는 기본 2컬럼 그리드입니다. 한 칸을 차지하려면 full을, 다른 열 수가 필요하면 columns를 씁니다.
  • 두 컴포넌트 모두 className·style을 받아 기본값 뒤에 병합합니다 — 블록을 복제하지 않고 조정하는 정규 경로입니다. FormSection은 제목 줄만 바꾸는 titleStyle도 받습니다.
<FormRow columns={3}>…</FormRow>
<FormSection title="기본 정보" style={{ marginBottom: 32 }}>…</FormSection>

이 계층이 무엇을 소유하고 무엇을 소유하지 않는지, 새 패턴이 언제 추가되는지는 LOB 계층 헌장 이 정합니다. 패턴을 제안하기 전에 읽어 주세요.

API 설정

import { ApiConfig } from '@iyulab/enterprise'

ApiConfig.initialize({ baseUrl: '/', odataPrefix: '$data', apiPrefix: 'api' })

ApiConfig.getODataUrl('Orders')          // → /$data/Orders
ApiConfig.getApiUrl('auth/me')           // → /api/auth/me
ApiConfig.getUrlWithParams('report', { year: 2026, active: true })
ApiConfig.isDevelopment                   // 환경 판별

OData 서비스 (createODataService)

OData v4 + custom REST CRUD 를 한 번에 구성한다. 401 세션 처리·에러 메시지 추출·성공 토스트·204 빈 바디 안전 파싱이 내장돼 있고, 도메인/로케일 요소는 전부 주입으로 앱 adapter 에 남긴다.

import { createODataService } from '@iyulab/enterprise'
import { app } from '@iyulab/modern-app'

// 앱 adapter (예: src/lib/odata.ts) — 라이브러리는 이 배선만 받는다.
export const svc = createODataService({
  baseUrl: window.location.origin,
  onUnauthorized: () => { window.location.href = '/' },        // 세션 만료 리다이렉트는 앱이 결정
  notify: { success: (m) => app.success(m), error: (m) => app.error(m) },
  messages: {                                                   // 기본은 영어 — 로케일 오버라이드
    saved: '저장되었습니다', updated: '수정되었습니다', deleted: '삭제되었습니다',
    sessionExpired: '세션이 만료되었습니다. 다시 로그인하세요.',
  },
})

await svc.odataGet<Order>('Orders', { $top: '20' })   // value 배열 언랩
await svc.odataPost<Order>('Orders', { name: 'A', note: '' })  // '' → null 정규화 + 성공 토스트
svc.odataUrl('Orders')                                 // flex-table useODataSource 엔드포인트
svc.sourceDefaults                                     // { baseUrl, onUnauthorized } 주입용

// custom REST — GET/POST/PUT/PATCH/DELETE 전부, 204 빈 바디 안전 파싱 포함
await svc.apiGet<Order>('reports/summary')
await svc.apiPost<Order>('orders', { name: 'A' })
await svc.apiPut<Order>('orders/7', { name: 'A (revised)' })    // 리소스 전체 교체
await svc.apiPatch<Order>('orders/7', { note: 'urgent' })
await svc.apiDelete('orders/7')                                 // 204 안전

// body가 FormData 인스턴스면 그대로(직렬화 없이) 멀티파트로 전송된다 —
// Content-Type은 브라우저가 boundary와 함께 자동 설정한다. apiPost/apiPut/apiPatch 전부 동일.
const form = new FormData()
form.append('file', file)
await svc.apiPost<Order>('orders/7/attachments', form)

주입 항목:

| config | 용도 | |--------|------| | baseUrl | 모든 요청의 오리진 (필수) | | odataPrefix / apiPrefix | 엔드포인트 prefix (기본 $data / api) | | onUnauthorized(status) | 401 시 호출 — 리다이렉트/재진입 가드는 앱이 처리 | | notify.success/error | 토스트 훅 (생략 시 토스트 없음 — 순수) | | messages | 사용자 대면 문구 (기본 영어, 지정 키만 대체) | | formatError(info) | 에러 메시지 포매팅 오버라이드 (앱별 정책) |

도메인 액션(상태 전이 등)·엔티티 목록·권한 코드는 라이브러리에 넣지 말고 앱 adapter 에 둔다.

인증 + 권한 (createAuthClient · 권한 store)

쿠키 세션 인증 흐름과 권한 스냅샷을 승격. 사용자·자격증명 형태는 앱이 제네릭으로 정의하고, 권한 코드는 불투명 문자열로만 다룬다. getPermissions 를 주면 로그인/세션 조회 성공 시 권한 store 가 자동 갱신된다.

import { createAuthClient, hasPermission, setPermissions } from '@iyulab/enterprise'

interface User { Id: string; Permissions: string[] }   // 도메인 형태 = 앱 소유

export const auth = createAuthClient<User, { Username: string; Password: string }>({
  meUrl: '/api/auth/me', loginUrl: '/api/auth/login', logoutUrl: '/api/auth/logout',
  getPermissions: (u) => u.Permissions,                 // 성공 시 권한 store 자동 set
  messages: { invalidCredentials: '사용자명 또는 비밀번호가 올바르지 않습니다.' },
})

// 부팅 게이트
const user = await auth.fetchMe()   // null → 미인증(로그인 화면)

// 어디서나 권한 판정(부팅 스냅샷)
if (hasPermission('orders.write')) { /* 저장 버튼 노출 */ }
  • fetchMe() 는 401/네트워크 오류 시 null — 이 신호가 로그인 게이트를 구동한다(라이브러리가 리다이렉트하지 않음).
  • 격리가 필요하면 createPermissionStore() 로 별도 store 를 만들어 permissionStore 로 주입한다.
  • 도메인 판정(isPortalUser 등)·권한 코드 상수는 라이브러리가 아니라 앱 adapter 에 둔다.

도메인 헬퍼

import { CurrencyHelper, DateHelper } from '@iyulab/enterprise'

CurrencyHelper.formatKRW(1234000)   // ₩1,234,000

Development

npm run build

License

MIT