{"_id":"@airsoko/oauth-client","name":"@airsoko/oauth-client","dist-tags":{"latest":"0.1.0"},"versions":{"0.1.0":{"name":"@airsoko/oauth-client","version":"0.1.0","description":"Client SDK for Airsoko OAuth — sign in customers with your shop OAuth client in Next.js apps","license":"MIT","private":false,"main":"./dist/index.js","types":"./dist/index.d.ts","exports":{".":{"types":"./dist/index.d.ts","default":"./dist/index.js"},"./next/pages":{"types":"./dist/next/page.d.ts","default":"./dist/next/page.js"},"./next/api":{"types":"./dist/next/handler.d.ts","default":"./dist/next/handler.js"},"./next/app":{"types":"./dist/next/app-route.d.ts","default":"./dist/next/app-route.js"},"./next/middleware":{"types":"./dist/next/middleware.d.ts","default":"./dist/next/middleware.js"},"./react":{"types":"./dist/react-entry.d.ts","default":"./dist/react-entry.js"}},"scripts":{"build":"tsc --build --force --verbose && node -e \"console.log('@airsoko/oauth-client: build complete → dist/')\"","rebuild":"npm run clean && npm run build","clean":"tsc --build --clean","typecheck":"tsc --noEmit","prepublishOnly":"npm run build","prepack":"npm run build"},"peerDependencies":{"next":">=12.0.0","react":">=17.0.0"},"peerDependenciesMeta":{"next":{"optional":true},"react":{"optional":true}},"devDependencies":{"@macive/tsconfig":"*","@types/node":"18.11.18","@types/react":"18.0.26","next":"13.5.6","react":"18.2.0","typescript":"^4.9.5"},"keywords":["airsoko","oauth","nextjs","authentication","pkce"],"repository":{"type":"git","url":"git+https://github.com/airsoko/airsoko-oauth.git","directory":"packages/airsoko-oauth-client"},"bugs":{"url":"https://github.com/airsoko/airsoko-oauth/issues"},"homepage":"https://github.com/airsoko/airsoko-oauth/tree/main/packages/airsoko-oauth-client#readme","publishConfig":{"access":"public"},"_id":"@airsoko/oauth-client@0.1.0","gitHead":"0821f8474c0d8ee5ed47eaefabd3b6298064af39","_nodeVersion":"22.22.3","_npmVersion":"10.9.8","dist":{"integrity":"sha512-D0+vnTx1mK6ZPG3EoCRIrqEKFWe5fZESbglVjOOiFk0DuBomlAsKbyakBJN0lmwFb8NZTw04nKQFEVcf/FD8sQ==","shasum":"5198fd4c433d0a93c5eeb1863ef55bbff3c3a0af","tarball":"https://registry.npmjs.org/@airsoko/oauth-client/-/oauth-client-0.1.0.tgz","fileCount":52,"unpackedSize":82243,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIBEWR4zjorqm0+R9fu1NFJ7NpTK0+sPbmqIIeqsBqsJPAiEAstxTS2d4LF+b70reDbwPiIRFWbY/tYBR8dN0H74VBFc="}]},"_npmUser":{"name":"cluewax","email":"cluewaxing@gmail.com"},"directories":{},"maintainers":[{"name":"cluewax","email":"cluewaxing@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/oauth-client_0.1.0_1780605754982_0.026496835752557457"},"_hasShrinkwrap":false}},"time":{"created":"2026-06-04T20:42:34.766Z","0.1.0":"2026-06-04T20:42:35.141Z","modified":"2026-06-04T20:42:35.753Z"},"maintainers":[{"name":"cluewax","email":"cluewaxing@gmail.com"}],"description":"Client SDK for Airsoko OAuth — sign in customers with your shop OAuth client in Next.js apps","homepage":"https://github.com/airsoko/airsoko-oauth/tree/main/packages/airsoko-oauth-client#readme","keywords":["airsoko","oauth","nextjs","authentication","pkce"],"repository":{"type":"git","url":"git+https://github.com/airsoko/airsoko-oauth.git","directory":"packages/airsoko-oauth-client"},"bugs":{"url":"https://github.com/airsoko/airsoko-oauth/issues"},"license":"MIT","readme":"# @airsoko/oauth-client\n\nPublic client SDK for **Airsoko merchant shop OAuth** — let customers sign in to your app with Airsoko consent.\n\nZero runtime dependencies. Works in any JavaScript environment; Next.js helpers are optional peer imports.\n\n## Install\n\n```bash\nnpm install @airsoko/oauth-client\n```\n\n## Create an OAuth client (merchant admin)\n\nBefore wiring this package, register your app as an OAuth client in the **Airsoko Merchant Admin** panel:\n\n1. Sign in to your shop dashboard (Merchant Admin), e.g. `https://admin.airsoko.com`.\n2. Open **Settings → OAuth clients** (`/settings/oauth-clients`).\n3. Click **Create client** and fill in:\n   - **Name** — your app name (shown on the consent screen).\n   - **Redirect URIs** — one per line; must match your app exactly, e.g.  \n     `https://your-app.com/auth/airsoko/callback`\n   - **Allowed scopes** — typically `profile,email,customer:read` (see the scope hint in the UI).\n   - **Client type** — `confidential` for server-side apps (recommended).\n4. Save the **client ID** and **client secret** when shown (secret is only displayed once; use **Rotate secret** if you lose it).\n5. Register the same redirect URI(s) you use in your app — mismatches will fail at callback.\n\nRequires merchant permission **Settings edit** (`SETTINGS_EDIT`).\n\n## Environment\n\nPaste credentials from the admin UI into your app:\n\n```env\nNEXT_PUBLIC_AIRSOKO_API_BASE=https://api.airsoko.com\nNEXT_PUBLIC_AIRSOKO_OAUTH_CLIENT_ID=your_client_id\nAIRSOKO_OAUTH_CLIENT_SECRET=your_client_secret\nNEXT_PUBLIC_AIRSOKO_OAUTH_REDIRECT_URI=https://your-app.com/auth/airsoko/callback\nNEXT_PUBLIC_AIRSOKO_OAUTH_SCOPES=profile,email,customer:read\n```\n\n`AIRSOKO_OAUTH_CLIENT_SECRET` is **server-only** — never expose it in client bundles.\n\n## Next.js — one catch-all page (recommended)\n\nCreate a single file; login and callback are handled automatically:\n\n```tsx\n// pages/auth/airsoko/[[...slug]].tsx\nexport { default, getServerSideProps } from '@airsoko/oauth-client/next/pages'\n```\n\n| URL | Action |\n|-----|--------|\n| `/auth/airsoko/login` | Starts OAuth (redirects to Airsoko consent) |\n| `/auth/airsoko/callback?code=…` | Exchanges code, sets session cookie, redirects home |\n| `/auth/airsoko?code=…` | Callback when redirect URI is the base path |\n\nRegister **`https://your-app.com/auth/airsoko/callback`** in the OAuth client redirect URIs in Merchant Admin.\n\n### Custom options\n\n```tsx\nimport { createAirsokoAuthPageHandlers } from '@airsoko/oauth-client/next/pages'\n\nexport const { default, getServerSideProps } = createAirsokoAuthPageHandlers({\n  basePath: '/auth/airsoko',\n  tokenCookieName: 'airsoko_access_token',\n  defaultRedirectPath: '/account',\n})\n```\n\n## Next.js — API catch-all\n\n```ts\n// pages/api/auth/airsoko/[[...slug]].ts\nimport { createAirsokoAuthHandler } from '@airsoko/oauth-client/next/api'\n\nexport default createAirsokoAuthHandler({ basePath: '/auth/airsoko' })\n```\n\nSet `NEXT_PUBLIC_AIRSOKO_OAUTH_REDIRECT_URI` to `https://your-app.com/api/auth/airsoko/callback` and add that URI in Merchant Admin.\n\n## Next.js App Router\n\n```ts\n// app/auth/airsoko/[...slug]/route.ts\nimport { createAirsokoAuthAppRouteHandlers } from '@airsoko/oauth-client/next/app'\n\nexport const { GET } = createAirsokoAuthAppRouteHandlers({ basePath: '/auth/airsoko' })\n```\n\n## Next.js middleware (protect routes)\n\nGate routes like `/account` or `/author` — unauthenticated visitors are redirected to `/auth/airsoko/login` and return after OAuth callback.\n\n```ts\n// middleware.ts (project root)\nimport { createAirsokoAuthMiddleware } from '@airsoko/oauth-client/next/middleware'\n\nconst { middleware, config: middlewareConfig } = createAirsokoAuthMiddleware({\n  protectedPaths: ['/account', '/author'],\n})\n\nexport { middleware }\nexport const config = middlewareConfig\n```\n\nOr split exports:\n\n```ts\nimport { withAirsokoAuth, airsokoAuthMiddlewareConfig } from '@airsoko/oauth-client/next/middleware'\n\nexport const middleware = withAirsokoAuth({\n  protectedPaths: ['/account', '/author'],\n})\n\nexport const config = airsokoAuthMiddlewareConfig({\n  protectedPaths: ['/account', '/author'],\n})\n```\n\nThe middleware checks the `airsoko_access_token` cookie (set by the callback route). OAuth paths under `/auth/airsoko` stay public.\n\n## Sign-in button (React)\n\nUse the built-in client button — click starts login, callback sets the cookie, user lands back on `destinationUrl`:\n\n```tsx\n'use client' // App Router only\n\nimport { SignInWithAirsokoButton } from '@airsoko/oauth-client/react'\n\nexport function LoginCard() {\n  return (\n    <SignInWithAirsokoButton className='btn' destinationUrl='/account'>\n      Sign in with Airsoko\n    </SignInWithAirsokoButton>\n  )\n}\n```\n\nOr call the helper directly:\n\n```tsx\nimport { signInWithAirsoko } from '@airsoko/oauth-client'\n\n<button type='button' onClick={() => signInWithAirsoko({ basePath: '/auth/airsoko' })}>\n  Sign in with Airsoko\n</button>\n```\n\nRequires the catch-all auth page (`pages/auth/airsoko/[[...slug]].tsx`) for login + callback.\n\n## Manual integration (any Node / server)\n\n```ts\nimport {\n  buildAirsokoAuthorizeUrl,\n  createPkcePair,\n  createOAuthState,\n  exchangeAirsokoOAuthCode,\n  assertAirsokoOAuthServerConfig,\n} from '@airsoko/oauth-client'\n\nconst config = assertAirsokoOAuthServerConfig()\nconst state = createOAuthState()\nconst pkce = await createPkcePair()\n\nconst authorizeUrl = buildAirsokoAuthorizeUrl({\n  ...config,\n  state,\n  codeChallenge: pkce.codeChallenge,\n  codeChallengeMethod: pkce.codeChallengeMethod,\n})\n\n// After callback:\nconst token = await exchangeAirsokoOAuthCode({\n  code,\n  clientId: config.clientId,\n  clientSecret: config.clientSecret,\n  redirectUri: config.redirectUri,\n  apiBase: config.apiBase,\n  state,\n  codeVerifier: pkce.codeVerifier,\n})\n```\n\n## Templates\n\nCopy-ready examples ship in `templates/`:\n\n- `templates/pages-auth-airsoko-catch-all.page.tsx`\n- `templates/pages-auth-airsoko-catch-all.api.ts`\n- `templates/app-auth-airsoko-route.ts`\n- `templates/middleware.ts`\n\n## Publish / build\n\n```bash\nnpm run build    # compile → dist/ (prints confirmation when done)\nnpm run rebuild  # clean + full compile\nnpm publish --access public   # prepublishOnly runs build first\n```\n\n`dist/` is gitignored but included in the npm tarball via the `files` field.\n\n### First publish (`@airsoko` scope)\n\nIf publish fails with **`404 Not Found - PUT @airsoko/oauth-client`**, the `@airsoko` npm organization does not exist yet or your account is not a member:\n\n1. Log in: `npm login`\n2. Create the org: [npmjs.com/org/create](https://www.npmjs.com/org/create) → name **`airsoko`**\n3. Add your npm user as an owner/member of `@airsoko`\n4. Publish again from this package directory:\n\n   ```bash\n   cd packages/airsoko-oauth-client\n   npm publish --access public\n   ```\n\nVerify login: `npm whoami`\n\n## License\n\nMIT — see [LICENSE](./LICENSE).\n","readmeFilename":"README.md","_rev":"1-db107809456815cebd8e57c82a2ba83b"}