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

@ngsk2784-lab/core

v0.1.0

Published

Framework/platform-agnostic client-side logic shared across ngsk2784-lab apps (auth session, http wrapper, validation, utils, storage adapters). See docs/architecture.md.

Readme

@ngsk2784-lab/core

공유 클라이언트 로직 라이브러리. 웹·데스크탑·모바일·웹게임 전 플랫폼에서 코드를 재사용하려는 목적으로, 프레임워크·플랫폼 무관 TypeScript로 작성된 순수 로직을 제공합니다.

대상: login-hub 생태계에 속한 모든 컨슈머 앱 (React/Next, React Native, Electron, Phaser 등)

설치

npm install @ngsk2784-lab/core

Optional Peer Dependencies

모듈에 따라 선택적 peer를 설치하세요:

# @core/auth 사용
npm install login-hub-sdk

# @core/api 사용
npm install ky

# @core/validation 사용
npm install zod

# React Native storage adapter 사용
npm install @react-native-async-storage/async-storage

빠른 시작 (공개 클라이언트 PKCE 로그인)

1. 세션 초기화

import { createAuthSession, createStorage } from '@ngsk2784-lab/core';
import { webStorage } from '@ngsk2784-lab/core/storage/web';

const auth = createAuthSession({
  config: {
    clientId: process.env.CLIENT_ID,
    hubUrl: process.env.HUB_URL,
  },
  storage: webStorage,
});

2. 로그인 URL 생성 & 리다이렉트

const loginUrl = await auth.createLoginUrl(
  'https://myapp.example.com/auth/callback'
);
window.location.href = loginUrl;

3. 콜백 라우트에서 code 교환

const searchParams = new URLSearchParams(window.location.search);
const code = searchParams.get('code');
const state = searchParams.get('state');

try {
  const session = await auth.exchange(code, 'https://myapp.example.com/auth/callback', state);
  console.log('로그인 성공:', session.user.nickname);
} catch (error) {
  console.error('로그인 실패:', error.message);
}

4. API 호출 시 토큰 자동 주입

import { createApiClient } from '@ngsk2784-lab/core/api';

const api = createApiClient({
  baseUrl: 'https://api.example.com',
  getAccessToken: async () => {
    const token = await auth.getAccessToken();
    return token;
  },
  onAuthFailure: () => {
    // 재로그인 필요
    window.location.href = '/login';
  },
});

// Authorization 헤더는 자동으로 붙습니다
const data = await api.get('me').json();

모듈 가이드

@core/auth — 세션 매니저

공개 클라이언트(PKCE) OAUTH2 로그인 흐름을 구현합니다. 토큰은 클라이언트가 직접 보유하며, 주입된 StorageAdapter에 저장됩니다.

API: createAuthSession(options) → AuthSession

const auth = createAuthSession({
  config: {
    clientId: 'YOUR_CLIENT_ID',
    hubUrl: 'https://login.example.com',
  },
  storage: webStorage, // 아래의 storage adapters 참고
  refreshTokenStorage: 'persistent', // 기본값. 'memory'로 설정하면 페이지 새로고침 후 재로그인 필요
});

// PKCE 리다이렉트 흐름
const loginUrl = await auth.createLoginUrl(redirectUri);
const session = await auth.exchange(code, redirectUri, state);
const token = await auth.getAccessToken(); // 만료 시 자동 refresh
await auth.logout();

주의사항 (웹 SPA):

  • login-hub-sdk/next를 사용하면 (httpOnly 쿠키, BFF 모델) 이 패키지는 불필요합니다.
  • 순수 SPA에서 이 패키지를 사용한다면, refreshTokenStorage: 'memory'로 설정 권장 (XSS 위험 감소). 단, 페이지 새로고침 후 토큰이 지워지므로 재로그인이 필요합니다.

@core/api — HTTP 클라이언트

ky 기반 HTTP 래퍼. 자동 401 refreshe, 타임아웃, 에러 정규화를 제공합니다.

API: createApiClient(options) → KyInstance

import { createApiClient } from '@ngsk2784-lab/core/api';

const api = createApiClient({
  baseUrl: 'https://api.example.com',
  timeoutMs: 15000,
  getAccessToken: async () => {
    const session = await auth.getSession();
    return session?.accessToken ?? null;
  },
  onRefresh: async () => {
    // 토큰 refresh 로직. true 반환하면 원래 요청을 재시도합니다
    const refreshed = await auth.getAccessToken();
    return !!refreshed;
  },
  onAuthFailure: () => {
    // 재로그인 필요
    window.location.href = '/login';
  },
});

// ky 인스턴스처럼 사용
const data = await api.get('users/me').json();

@core/storage/* — Storage 어댑터

토큰/세션 저장 위치를 선택합니다.

웹 (localStorage / sessionStorage)

import { webStorage } from '@ngsk2784-lab/core/storage/web';

const auth = createAuthSession({
  config: { /* ... */ },
  storage: webStorage,
});

인메모리 (테스트, SSR, 단기 수명)

import { memoryStorage } from '@ngsk2784-lab/core/storage/memory';

const auth = createAuthSession({
  config: { /* ... */ },
  storage: memoryStorage,
});

React Native (AsyncStorage)

import { rnStorage } from '@ngsk2784-lab/core/storage/rn';

const auth = createAuthSession({
  config: { /* ... */ },
  storage: rnStorage,
});

@core/validation — 검증 스키마

zod 기반 공통 필드 스키마 + safeValidate 래퍼.

제공 스키마:

  • emailSchema — RFC 형식 이메일
  • passwordSchema — 8~72자, 영문+숫자 필수
  • koreanPhoneSchema — 010-XXXX-XXXX (자동 정규화)
  • nicknameSchema — 2~20자, 한글/영문/숫자/언더스코어/하이픈
import { safeValidate, emailSchema, nicknameSchema } from '@ngsk2784-lab/core/validation';

const result = safeValidate(emailSchema, userInput);
if (!result.success) {
  console.error(result.error.message);
  console.error(result.error.issues); // [{ path: string, message: string }, ...]
}

@core/utils — 환경변수 & 유틸

환경변수 정규화 헬퍼.

import { required, optional, clean } from '@ngsk2784-lab/core/utils';

const apiUrl = required(process.env.API_URL, 'API_URL');
const timeout = optional(process.env.TIMEOUT_MS, '10000');

// clean(): 따옴표·공백 제거 (Infisical/Railway 주입값 처리)
const key = clean(process.env.SECRET_KEY);

비-JS 플랫폼 (Godot / Unity)

core는 JavaScript만 지원합니다. Godot(GDScript)이나 Unity(C#)는 login-hub HTTP 프로토콜을 직접 구현해야 합니다.

자세한 내용은 login-hub/docs/api-contract.md를 참고하세요.

필요한 엔드포인트:

  • GET /authorize — 로그인 시작 (PKCE code_challenge 필수)
  • POST /token — code 교환 (code_verifier 필수)
  • POST /token (grant_type=refresh_token) — 토큰 갱신
  • POST /logout — 로그아웃
  • GET /.well-known/jwks.json — 토큰 검증용 공개키

구조

@ngsk2784-lab/core
├── ./auth       세션 매니저 (login-hub-sdk 래핑)
├── ./api        HTTP 클라이언트 래퍼 (ky)
├── ./validation zod 스키마 + safeValidate
├── ./utils      env 헬퍼
├── ./storage/web      localStorage 어댑터
├── ./storage/memory   인메모리 어댑터
├── ./storage/rn       AsyncStorage 어댑터 (React Native)
└── .             공통 타입 (User, Session, ApiError) + 배럴

각 모듈은 독립적으로 tree-shake됩니다. 쓰는 것만 번들에 포함됩니다.


API 참고

AuthSession 메서드

| 메서드 | 반환값 | 설명 | |--------|--------|------| | createLoginUrl(redirectUri) | Promise<string> | 로그인 URL 생성 (state + PKCE 자동 저장) | | exchange(code, redirectUri, state) | Promise<Session> | authorization code 교환 (CSRF 검증 포함) | | getAccessToken() | Promise<string \| null> | 현재 access token (만료 시 자동 refresh) | | getSession() | Promise<Session \| null> | 현재 세션 (claims + user) | | logout() | Promise<void> | 로그아웃 (허브 revoke + 로컬 스토리지 정리) |

Session 타입

{
  accessToken: string;           // JWT, 15분 만료
  refreshToken: string;          // opaque, 30일 만료
  claims: {
    sub: string;                 // user ID
    exp: number;                 // 만료 timestamp (sec)
    email: string | null;
    nickname: string;
    avatarUrl: string | null;
    provider: 'google' | 'naver' | 'kakao';
  };
  user: {
    id: string;
    provider: 'google' | 'naver' | 'kakao';
    email: string | null;
    nickname: string;
    avatarUrl: string | null;
  };
}

라이선스

MIT — docs/architecture.md 참고


문서 & 설계: docs/architecture.md
login-hub API 계약: login-hub/docs/api-contract.md
GitHub: https://github.com/ngsk2784-lab/core