{"_id":"@chandu_ganji/aws-frontend-kit","_rev":"2-2141bb9de9c1210fb732cb5eaee8e342","name":"@chandu_ganji/aws-frontend-kit","dist-tags":{"latest":"1.0.1"},"versions":{"1.0.0":{"name":"@chandu_ganji/aws-frontend-kit","version":"1.0.0","keywords":["aws","cognito","api-gateway","react","nextjs","vue","angular","auth","frontend-kit","typescript"],"author":{"name":"aws-frontend-kit contributors"},"license":"MIT","_id":"@chandu_ganji/aws-frontend-kit@1.0.0","maintainers":[{"name":"chandu_ganji","email":"chandutillu8374@gmail.com"}],"homepage":"https://github.com/aws-frontend-kit/aws-frontend-kit#readme","bugs":{"url":"https://github.com/aws-frontend-kit/aws-frontend-kit/issues"},"dist":{"shasum":"5b9b154f97c8bb27524a3dfc98a9cf5a1152b0c3","tarball":"https://registry.npmjs.org/@chandu_ganji/aws-frontend-kit/-/aws-frontend-kit-1.0.0.tgz","fileCount":22,"integrity":"sha512-HvB7GcdlIr07VYdH+j70RpNvoHO2Rf/ptLUr9/evZ1v3HSoFgJCiQFzJomcaU+V3SLkkSQTOCj2snkrxHFTK8g==","signatures":[{"sig":"MEUCIBrvsnys/ihcoZD7CvcPvrQ3GN7oS2x8+/qPByk28McPAiEAvtqMA8PRzYBnEOxKR/8igWZKgas7zXaC9N0/cLFXjiM=","keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U"}],"unpackedSize":5522316},"main":"dist/index.js","types":"dist/index.d.ts","module":"dist/index.mjs","engines":{"node":">=18.0.0"},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./vue":{"types":"./dist/vue/index.d.ts","import":"./dist/vue/index.mjs","require":"./dist/vue/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.mjs","require":"./dist/react/index.js"},"./nextjs":{"types":"./dist/nextjs/index.d.ts","import":"./dist/nextjs/index.mjs","require":"./dist/nextjs/index.js"},"./angular":{"types":"./dist/angular/index.d.ts","import":"./dist/angular/index.mjs","require":"./dist/angular/index.js"}},"scripts":{"dev":"tsup --watch","lint":"tsc --noEmit","build":"tsup","prepublishOnly":"npm run build"},"_npmUser":{"name":"chandu_ganji","email":"chandutillu8374@gmail.com"},"repository":{"url":"git+https://github.com/aws-frontend-kit/aws-frontend-kit.git","type":"git"},"_npmVersion":"11.6.2","description":"Universal AWS frontend SDK — Cognito auth, API Gateway, session management. Works with React, Next.js, Vue, Angular, and plain JavaScript.","directories":{},"_nodeVersion":"24.11.1","dependencies":{"@aws-sdk/client-appconfigdata":"^3.1041.0","@aws-sdk/client-cognito-identity-provider":"^3.600.0"},"_hasShrinkwrap":false,"devDependencies":{"vue":"^3.5.33","rxjs":"^7.8.2","tsup":"^8.1.0","buffer":"^6.0.3","typescript":"^5.4.5","@types/node":"^20.14.0","@types/react":"^18.3.28","@angular/core":"^17.3.12","@angular/common":"^17.3.12","@angular/router":"^17.3.12"},"peerDependencies":{"vue":">=3.2.0","rxjs":">=7.0.0","react":">=17.0.0","@angular/core":">=15.0.0","@angular/common":">=15.0.0"},"peerDependenciesMeta":{"vue":{"optional":true},"rxjs":{"optional":true},"react":{"optional":true},"@angular/core":{"optional":true},"@angular/common":{"optional":true}},"_npmOperationalInternal":{"tmp":"tmp/aws-frontend-kit_1.0.0_1778131545514_0.29428074261190607","host":"s3://npm-registry-packages-npm-production"}},"1.0.1":{"name":"@chandu_ganji/aws-frontend-kit","version":"1.0.1","description":"Universal AWS frontend SDK — Cognito auth, API Gateway, session management. Works with React, Next.js, Vue, Angular, and plain JavaScript.","main":"dist/index.js","module":"dist/index.mjs","types":"dist/index.d.ts","scripts":{"build":"tsup","dev":"tsup --watch","lint":"tsc --noEmit","prepublishOnly":"npm run build"},"keywords":["aws","cognito","api-gateway","react","nextjs","vue","angular","auth","frontend-kit","typescript"],"author":{"name":"aws-frontend-kit contributors"},"license":"MIT","homepage":"https://github.com/aws-frontend-kit/aws-frontend-kit#readme","repository":{"type":"git","url":"git+https://github.com/aws-frontend-kit/aws-frontend-kit.git"},"bugs":{"url":"https://github.com/aws-frontend-kit/aws-frontend-kit/issues"},"engines":{"node":">=18.0.0"},"dependencies":{"@aws-sdk/client-appconfigdata":"^3.1041.0","@aws-sdk/client-cognito-identity-provider":"^3.600.0"},"devDependencies":{"@angular/common":"^17.3.12","@angular/core":"^17.3.12","@angular/router":"^17.3.12","@types/node":"^20.14.0","@types/react":"^18.3.28","buffer":"^6.0.3","rxjs":"^7.8.2","tsup":"^8.1.0","typescript":"^5.4.5","vue":"^3.5.33"},"peerDependencies":{"@angular/common":">=15.0.0","@angular/core":">=15.0.0","react":">=17.0.0","rxjs":">=7.0.0","vue":">=3.2.0"},"peerDependenciesMeta":{"react":{"optional":true},"vue":{"optional":true},"@angular/core":{"optional":true},"@angular/common":{"optional":true},"rxjs":{"optional":true}},"exports":{".":{"types":"./dist/index.d.ts","import":"./dist/index.mjs","require":"./dist/index.js"},"./react":{"types":"./dist/react/index.d.ts","import":"./dist/react/index.mjs","require":"./dist/react/index.js"},"./nextjs":{"types":"./dist/nextjs/index.d.ts","import":"./dist/nextjs/index.mjs","require":"./dist/nextjs/index.js"},"./vue":{"types":"./dist/vue/index.d.ts","import":"./dist/vue/index.mjs","require":"./dist/vue/index.js"},"./angular":{"types":"./dist/angular/index.d.ts","import":"./dist/angular/index.mjs","require":"./dist/angular/index.js"}},"_id":"@chandu_ganji/aws-frontend-kit@1.0.1","_nodeVersion":"24.11.1","_npmVersion":"11.6.2","dist":{"integrity":"sha512-dxrlwnay3TWzYEhoMik/t1jXXSY/sqzbiOIYanWVGywHaRJh8vTfIfKIjuL6v9e7OpnWTvk8Zu5DX3WughgPBQ==","shasum":"5ca645b63e9c8f70119b0d42f14766995689a2dc","tarball":"https://registry.npmjs.org/@chandu_ganji/aws-frontend-kit/-/aws-frontend-kit-1.0.1.tgz","fileCount":22,"unpackedSize":5522316,"signatures":[{"keyid":"SHA256:DhQ8wR5APBvFHLF/+Tc+AYvPOdTpcIDqOhxsBHRwC7U","sig":"MEUCIQCaDOV/g7i3+vkDH1IhgY30RSOAakPhE6gzbzPMik55qQIgBEp5FsnJJdCgHJtuY8bNtjpMo7lIck0/6BAU3uJKwxk="}]},"_npmUser":{"name":"chandu_ganji","email":"chandutillu8374@gmail.com"},"directories":{},"maintainers":[{"name":"chandu_ganji","email":"chandutillu8374@gmail.com"}],"_npmOperationalInternal":{"host":"s3://npm-registry-packages-npm-production","tmp":"tmp/aws-frontend-kit_1.0.1_1778134082966_0.37106163372886125"},"_hasShrinkwrap":false}},"time":{"created":"2026-05-07T05:25:45.387Z","modified":"2026-05-07T06:08:03.311Z","1.0.0":"2026-05-07T05:25:45.741Z","1.0.1":"2026-05-07T06:08:03.208Z"},"bugs":{"url":"https://github.com/aws-frontend-kit/aws-frontend-kit/issues"},"author":{"name":"aws-frontend-kit contributors"},"license":"MIT","homepage":"https://github.com/aws-frontend-kit/aws-frontend-kit#readme","keywords":["aws","cognito","api-gateway","react","nextjs","vue","angular","auth","frontend-kit","typescript"],"repository":{"type":"git","url":"git+https://github.com/aws-frontend-kit/aws-frontend-kit.git"},"description":"Universal AWS frontend SDK — Cognito auth, API Gateway, session management. Works with React, Next.js, Vue, Angular, and plain JavaScript.","maintainers":[{"name":"chandu_ganji","email":"chandutillu8374@gmail.com"}],"readme":"# aws-starter-kit\r\n\r\n> Plug-and-play npm library for **Amazon Cognito** authentication, **API Gateway** calls, and **session management** in React/Vite/plain-JS apps.\r\n\r\nReduce AWS setup boilerplate by 80%. Clean, developer-friendly API with full TypeScript support.\r\n\r\n---\r\n\r\n## Installation\r\n\r\n```bash\r\nnpm install aws-starter-kit\r\n```\r\n\r\n> **Peer dependency**: React ≥ 17 is optional — required only if you use `useAuth` or `ProtectedRoute`.\r\n\r\n---\r\n\r\n## Setup\r\n\r\n### 1. Create your `.env` file\r\n\r\nCopy `.env.example` to `.env` and fill in your values:\r\n\r\n```env\r\nVITE_AWS_REGION=ap-south-1\r\nVITE_USER_POOL_ID=ap-south-1_gjCWvB3ZF\r\nVITE_CLIENT_ID=4gop3t6vh0p0t3if1m90dasq4u\r\nVITE_API_BASE_URL=https://xxxxxxxxxx.execute-api.ap-south-1.amazonaws.com/prod\r\n\r\n# Social login (optional)\r\nVITE_COGNITO_DOMAIN=https://your-domain.auth.ap-south-1.amazoncognito.com\r\nVITE_REDIRECT_SIGN_IN=http://localhost:5173/callback\r\nVITE_REDIRECT_SIGN_OUT=http://localhost:5173/login\r\n```\r\n\r\n### 2. Initialize at app startup\r\n\r\n```ts\r\n// src/main.ts (or index.ts)\r\nimport { initAWS } from \"aws-starter-kit\";\r\n\r\ninitAWS({\r\n  region:     import.meta.env.VITE_AWS_REGION,\r\n  userPoolId: import.meta.env.VITE_USER_POOL_ID,\r\n  clientId:   import.meta.env.VITE_CLIENT_ID,\r\n  apiBaseUrl: import.meta.env.VITE_API_BASE_URL,\r\n  debug: import.meta.env.DEV, // enable debug logs in development\r\n\r\n  // Social login (optional)\r\n  domain:          import.meta.env.VITE_COGNITO_DOMAIN,\r\n  redirectSignIn:  import.meta.env.VITE_REDIRECT_SIGN_IN,\r\n  redirectSignOut: import.meta.env.VITE_REDIRECT_SIGN_OUT,\r\n});\r\n```\r\n\r\n---\r\n\r\n## Authentication\r\n\r\n```ts\r\nimport { login, logout, isAuthenticated, getCurrentUser, getAccessToken } from \"aws-starter-kit\";\r\n\r\n// Sign in\r\nconst { user, tokens } = await login(\"user@example.com\", \"Password123!\");\r\nconsole.log(user.username, user.email);\r\n\r\n// Check session\r\nif (isAuthenticated()) {\r\n  console.log(\"Logged in!\");\r\n}\r\n\r\n// Get the current user from Cognito\r\nconst user = await getCurrentUser();\r\n\r\n// Get the raw JWT (for manual use)\r\nconst token = await getAccessToken();\r\n\r\n// Sign out (global — invalidates all devices)\r\nawait logout();\r\n```\r\n\r\n---\r\n\r\n## API Client\r\n\r\n```ts\r\nimport { api } from \"aws-starter-kit\";\r\n\r\n// GET — JWT is attached automatically\r\nconst { data: todos } = await api.get<Todo[]>(\"/todos\");\r\n\r\n// POST\r\nconst { data: newTodo } = await api.post<Todo>(\"/todos\", { title: \"Buy milk\" });\r\n\r\n// PUT / PATCH / DELETE\r\nawait api.put(\"/todos/1\", { title: \"Updated\" });\r\nawait api.patch(\"/todos/1\", { done: true });\r\nawait api.delete(\"/todos/1\");\r\n```\r\n\r\n### Custom interceptors\r\n\r\n```ts\r\nimport { addRequestInterceptor, addResponseInterceptor } from \"aws-starter-kit\";\r\n\r\n// Log all requests\r\naddRequestInterceptor(async (url, options) => {\r\n  console.log(\"→\", options.method, url);\r\n  return { url, options };\r\n});\r\n\r\n// Log all responses\r\naddResponseInterceptor(async (response, url) => {\r\n  console.log(\"←\", response.status, url);\r\n  return response;\r\n});\r\n```\r\n\r\n---\r\n\r\n## Session Management\r\n\r\n```ts\r\nimport { startSession, getSession, touchSession, endSession, setIdleTimeout } from \"aws-starter-kit\";\r\n\r\n// Start a session after login\r\nstartSession(user.username);\r\n\r\n// Keep session alive on user activity\r\ndocument.addEventListener(\"click\", touchSession);\r\n\r\n// Configure idle timeout (default: 30 minutes)\r\nsetIdleTimeout(15 * 60 * 1000); // 15 minutes\r\n\r\n// Get current session info\r\nconst session = getSession();\r\nconsole.log(session?.startedAt, session?.lastActivityAt);\r\n\r\n// End session and sign out\r\nawait endSession();\r\n```\r\n\r\n---\r\n\r\n## React UI Helpers\r\n\r\n### `useAuth` hook\r\n\r\n```tsx\r\nimport { useAuth } from \"aws-starter-kit\";\r\n\r\nfunction App() {\r\n  const { user, loading, authenticated, login, logout } = useAuth();\r\n\r\n  if (loading) return <div>Loading...</div>;\r\n  if (!authenticated) return <LoginForm onLogin={login} />;\r\n\r\n  return (\r\n    <div>\r\n      <p>Hello, {user?.email}</p>\r\n      <button onClick={logout}>Sign Out</button>\r\n    </div>\r\n  );\r\n}\r\n```\r\n\r\n### `ProtectedRoute` (React Router v6)\r\n\r\n```tsx\r\nimport { ProtectedRoute } from \"aws-starter-kit\";\r\n\r\n// In your router:\r\n{\r\n  path: \"/dashboard\",\r\n  element: (\r\n    <ProtectedRoute redirectTo=\"/login\">\r\n      <Dashboard />\r\n    </ProtectedRoute>\r\n  ),\r\n}\r\n```\r\n\r\n### `createLoginHandler`\r\n\r\n```ts\r\nimport { createLoginHandler } from \"aws-starter-kit\";\r\n\r\nconst handleLogin = createLoginHandler({\r\n  onSuccess: (result) => navigate(\"/dashboard\"),\r\n  onError:   (err)    => setErrorMessage(String(err)),\r\n});\r\n\r\n// Call from your form submit:\r\nawait handleLogin(email, password);\r\n```\r\n\r\n### Role-based access\r\n\r\n```ts\r\nimport { hasRole } from \"aws-starter-kit\";\r\n\r\nif (await hasRole([\"admin\"])) {\r\n  showAdminPanel();\r\n}\r\n```\r\n\r\n---\r\n\r\n## Sign Up & Email Verification\r\n\r\n```ts\r\nimport { signUp, confirmSignUp, resendVerificationCode } from \"aws-starter-kit\";\r\n\r\n// 1. Create account — returns whether email verification is needed\r\nconst result = await signUp(\"user@example.com\", \"Password123!\");\r\n\r\nif (!result.confirmed) {\r\n  console.log(\"Check your email:\", result.codeDelivery?.destination);\r\n  // → navigate to verification screen\r\n}\r\n\r\n// 2. Verify email with the 6-digit code\r\nawait confirmSignUp(\"user@example.com\", \"123456\");\r\n\r\n// 3. Now the user can log in\r\nconst { user } = await login(\"user@example.com\", \"Password123!\");\r\n\r\n// Didn't get the code? Re-send it\r\nawait resendVerificationCode(\"user@example.com\");\r\n```\r\n\r\n**`signUp` with extra attributes:**\r\n\r\n```ts\r\nawait signUp(\"user@example.com\", \"Password123!\", {\r\n  attributes: {\r\n    phone_number: \"+15551234567\",\r\n    \"custom:plan\": \"free\",\r\n  },\r\n});\r\n```\r\n\r\n---\r\n\r\n## Forgot Password\r\n\r\n```ts\r\nimport { forgotPassword, confirmForgotPassword } from \"aws-starter-kit\";\r\n\r\n// 1. Request a reset code — Cognito emails it to the user\r\nconst { codeDelivery } = await forgotPassword(\"user@example.com\");\r\nconsole.log(\"Code sent to:\", codeDelivery.destination); // e.g. \"u***@example.com\"\r\n\r\n// 2. Submit the code + new password\r\nawait confirmForgotPassword(\"user@example.com\", \"123456\", \"NewPassword99!\");\r\n\r\n// 3. User can now log in with the new password\r\n```\r\n\r\n---\r\n\r\n## Error Handling\r\n\r\nAll auth functions throw a `CognitoAuthError` on failure with a consistent `code` and `message`:\r\n\r\n```ts\r\nimport { CognitoAuthError, signUp, login } from \"aws-starter-kit\";\r\n\r\ntry {\r\n  await signUp(email, password);\r\n} catch (err) {\r\n  if (err instanceof CognitoAuthError) {\r\n    switch (err.code) {\r\n      case \"USER_ALREADY_EXISTS\":\r\n        showMessage(\"An account with this email already exists.\");\r\n        break;\r\n      case \"INVALID_PASSWORD\":\r\n        showMessage(\"Password must be at least 8 characters.\");\r\n        break;\r\n      default:\r\n        showMessage(err.message);\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n**Error code reference:**\r\n\r\n| Code | Cognito exception | When it occurs |\r\n|---|---|---|\r\n| `USER_ALREADY_EXISTS` | `UsernameExistsException` | `signUp` — email taken |\r\n| `USER_NOT_CONFIRMED` | `UserNotConfirmedException` | `login` — email not verified |\r\n| `USER_NOT_FOUND` | `UserNotFoundException` | `login`, `forgotPassword` — no account |\r\n| `INVALID_CREDENTIALS` | `NotAuthorizedException` | `login` — wrong password |\r\n| `CODE_MISMATCH` | `CodeMismatchException` | `confirmSignUp`, `confirmForgotPassword` |\r\n| `CODE_EXPIRED` | `ExpiredCodeException` | `confirmSignUp`, `confirmForgotPassword` |\r\n| `INVALID_PASSWORD` | `InvalidPasswordException` | `signUp`, `confirmForgotPassword` |\r\n| `TOO_MANY_REQUESTS` | `LimitExceededException` | Any function — rate limited |\r\n| `INVALID_PARAMETER` | `InvalidParameterException` | Any function — bad input |\r\n| `UNKNOWN` | *(other)* | Unexpected Cognito error |\r\n\r\n---\r\n\r\n## Social Login (OAuth / Hosted UI)\r\n\r\nSign in with Google, Apple, or Facebook using Cognito Hosted UI and Authorization Code Flow with PKCE — no OAuth internals required.\r\n\r\n### 1. Add social config to `initAWS`\r\n\r\n```ts\r\ninitAWS({\r\n  region:         \"us-east-1\",\r\n  userPoolId:     \"us-east-1_XXXXXXXXX\",\r\n  clientId:       \"xxxxxxxxxxxxxxxxxxxxxxxxxx\",\r\n  apiBaseUrl:     \"https://api.example.com/prod\",\r\n\r\n  // Social login extras\r\n  domain:          \"https://your-domain.auth.us-east-1.amazoncognito.com\",\r\n  redirectSignIn:  \"http://localhost:5173/callback\",\r\n  redirectSignOut: \"http://localhost:5173/login\",\r\n});\r\n```\r\n\r\n> **Cognito console:** Register `redirectSignIn` under *App Integration → App Client → Allowed callback URLs*, `redirectSignOut` under *Allowed sign-out URLs*, and enable Google / Apple / Facebook under *Federation → Identity providers*.\r\n\r\n### 2. Trigger social login\r\n\r\n```ts\r\nimport { loginWithRedirect } from \"aws-starter-kit\";\r\n\r\n// Full-page redirect — no await needed\r\nloginWithRedirect(\"google\");\r\nloginWithRedirect(\"apple\");\r\nloginWithRedirect(\"facebook\");\r\n```\r\n\r\n### 3. Handle the callback\r\n\r\nCreate a `/callback` route and call `handleRedirectCallback()` once:\r\n\r\n```ts\r\nimport { handleRedirectCallback, SocialAuthError } from \"aws-starter-kit\";\r\n\r\ntry {\r\n  const { user, tokens } = await handleRedirectCallback();\r\n  console.log(\"Signed in as:\", user.email, \"via\", user.provider);\r\n  navigate(\"/dashboard\");\r\n} catch (err) {\r\n  if (err instanceof SocialAuthError) {\r\n    if (err.code === \"SOCIAL_STATE_MISMATCH\") {\r\n      navigate(\"/login\"); // possible CSRF — restart\r\n    } else {\r\n      showError(err.message);\r\n    }\r\n  }\r\n}\r\n```\r\n\r\n### 4. Social logout\r\n\r\n```ts\r\nimport { logoutSocial } from \"aws-starter-kit\";\r\n\r\n// Clears tokens + redirects to Cognito /logout → your redirectSignOut URL\r\nawait logoutSocial();\r\n\r\n// Clear local tokens only (no redirect)\r\nawait logoutSocial({ global: false });\r\n```\r\n\r\n### Social error codes\r\n\r\n| Code | When it occurs |\r\n|---|---|\r\n| `SOCIAL_CONFIG_MISSING` | `domain` or `redirectSignIn` not set in `initAWS` |\r\n| `SOCIAL_LOGIN_CANCELLED` | User closed the provider window |\r\n| `SOCIAL_STATE_MISMATCH` | CSRF state mismatch — do not proceed |\r\n| `SOCIAL_TOKEN_EXCHANGE` | Code-for-token exchange failed |\r\n| `SOCIAL_INVALID_CALLBACK` | No `code` in URL, or PKCE verifier missing |\r\n| `SOCIAL_TOKEN_PARSE` | Could not decode token response |\r\n\r\n---\r\n\r\n## Config reference\r\n\r\n| Option | Type | Required | Description |\r\n|---|---|---|---|\r\n| `region` | `string` | ✅ | AWS region (e.g. `\"us-east-1\"`) |\r\n| `userPoolId` | `string` | ✅ | Cognito User Pool ID |\r\n| `clientId` | `string` | ✅ | Cognito App Client ID |\r\n| `apiBaseUrl` | `string` | ✅ | API Gateway base URL |\r\n| `debug` | `boolean` | — | Enable console debug logs (default: `false`) |\r\n| `storage` | `\"localStorage\" \\| \"sessionStorage\" \\| \"memory\"` | — | Token storage (default: `\"localStorage\"`) |\r\n| `domain` | `string` | — | Cognito Hosted UI domain — required for social login |\r\n| `redirectSignIn` | `string` | — | OAuth callback URL (must be registered in Cognito) |\r\n| `redirectSignOut` | `string` | — | URL to redirect to after `logoutSocial()` |\r\n\r\n---\r\n\r\n## Full example\r\n\r\n```ts\r\nimport { initAWS, login, api } from \"aws-starter-kit\";\r\n\r\n// 1. Initialize once\r\ninitAWS({\r\n  region:     \"us-east-1\",\r\n  userPoolId: \"us-east-1_XXXXXXXXX\",\r\n  clientId:   \"xxxxxxxxxxxxxxxxxxxxxxxxxx\",\r\n  apiBaseUrl: \"https://api.example.com/prod\",\r\n});\r\n\r\n// 2. Authenticate\r\nconst { user } = await login(\"user@example.com\", \"Password123!\");\r\nconsole.log(\"Logged in as:\", user.username);\r\n\r\n// 3. Call your API — token is auto-attached\r\nconst { data: todos } = await api.get(\"/todos\");\r\nconsole.log(todos);\r\n```\r\n\r\n---\r\n\r\n## Building from source\r\n\r\n```bash\r\nnpm install\r\nnpm run build      # outputs to dist/\r\nnpm run dev        # watch mode\r\n```\r\n\r\n## Publishing\r\n\r\n```bash\r\nnpm run build\r\nnpm publish\r\n```\r\n\r\n---\r\n\r\n## License\r\n\r\nMIT\r\n","readmeFilename":"README.md"}