workos 0.11.1 → 0.12.0-beta.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +163 -6
- package/dist/bin.js +22 -2
- package/dist/bin.js.map +1 -1
- package/dist/check-coverage.ts +237 -0
- package/dist/commands/dev.d.ts +23 -0
- package/dist/commands/dev.js +139 -0
- package/dist/commands/dev.js.map +1 -0
- package/dist/commands/emulate.d.ts +6 -0
- package/dist/commands/emulate.js +64 -0
- package/dist/commands/emulate.js.map +1 -0
- package/dist/commands/seed.d.ts +2 -0
- package/dist/commands/seed.js +60 -1
- package/dist/commands/seed.js.map +1 -1
- package/dist/emulate/core/id.d.ts +33 -0
- package/dist/emulate/core/id.js +58 -0
- package/dist/emulate/core/id.js.map +1 -0
- package/dist/emulate/core/index.d.ts +8 -0
- package/dist/emulate/core/index.js +8 -0
- package/dist/emulate/core/index.js.map +1 -0
- package/dist/emulate/core/jwt.d.ts +28 -0
- package/dist/emulate/core/jwt.js +78 -0
- package/dist/emulate/core/jwt.js.map +1 -0
- package/dist/emulate/core/middleware/auth.d.ts +18 -0
- package/dist/emulate/core/middleware/auth.js +28 -0
- package/dist/emulate/core/middleware/auth.js.map +1 -0
- package/dist/emulate/core/middleware/error-handler.d.ts +22 -0
- package/dist/emulate/core/middleware/error-handler.js +72 -0
- package/dist/emulate/core/middleware/error-handler.js.map +1 -0
- package/dist/emulate/core/pagination.d.ts +21 -0
- package/dist/emulate/core/pagination.js +35 -0
- package/dist/emulate/core/pagination.js.map +1 -0
- package/dist/emulate/core/plugin.d.ts +15 -0
- package/dist/emulate/core/plugin.js +2 -0
- package/dist/emulate/core/plugin.js.map +1 -0
- package/dist/emulate/core/server.d.ts +17 -0
- package/dist/emulate/core/server.js +116 -0
- package/dist/emulate/core/server.js.map +1 -0
- package/dist/emulate/core/store.d.ts +42 -0
- package/dist/emulate/core/store.js +148 -0
- package/dist/emulate/core/store.js.map +1 -0
- package/dist/emulate/index.d.ts +25 -0
- package/dist/emulate/index.js +47 -0
- package/dist/emulate/index.js.map +1 -0
- package/dist/emulate/workos/entities.d.ts +360 -0
- package/dist/emulate/workos/entities.js +2 -0
- package/dist/emulate/workos/entities.js.map +1 -0
- package/dist/emulate/workos/event-bus.d.ts +12 -0
- package/dist/emulate/workos/event-bus.js +45 -0
- package/dist/emulate/workos/event-bus.js.map +1 -0
- package/dist/emulate/workos/helpers.d.ts +63 -0
- package/dist/emulate/workos/helpers.js +518 -0
- package/dist/emulate/workos/helpers.js.map +1 -0
- package/dist/emulate/workos/index.d.ts +91 -0
- package/dist/emulate/workos/index.js +319 -0
- package/dist/emulate/workos/index.js.map +1 -0
- package/dist/emulate/workos/routes/api-keys.d.ts +2 -0
- package/dist/emulate/workos/routes/api-keys.js +35 -0
- package/dist/emulate/workos/routes/api-keys.js.map +1 -0
- package/dist/emulate/workos/routes/audit-logs.d.ts +2 -0
- package/dist/emulate/workos/routes/audit-logs.js +107 -0
- package/dist/emulate/workos/routes/audit-logs.js.map +1 -0
- package/dist/emulate/workos/routes/auth-challenges.d.ts +2 -0
- package/dist/emulate/workos/routes/auth-challenges.js +51 -0
- package/dist/emulate/workos/routes/auth-challenges.js.map +1 -0
- package/dist/emulate/workos/routes/auth-factors.d.ts +2 -0
- package/dist/emulate/workos/routes/auth-factors.js +51 -0
- package/dist/emulate/workos/routes/auth-factors.js.map +1 -0
- package/dist/emulate/workos/routes/auth.d.ts +2 -0
- package/dist/emulate/workos/routes/auth.js +349 -0
- package/dist/emulate/workos/routes/auth.js.map +1 -0
- package/dist/emulate/workos/routes/authorization-checks.d.ts +10 -0
- package/dist/emulate/workos/routes/authorization-checks.js +135 -0
- package/dist/emulate/workos/routes/authorization-checks.js.map +1 -0
- package/dist/emulate/workos/routes/authorization-org-roles.d.ts +2 -0
- package/dist/emulate/workos/routes/authorization-org-roles.js +206 -0
- package/dist/emulate/workos/routes/authorization-org-roles.js.map +1 -0
- package/dist/emulate/workos/routes/authorization-permissions.d.ts +2 -0
- package/dist/emulate/workos/routes/authorization-permissions.js +78 -0
- package/dist/emulate/workos/routes/authorization-permissions.js.map +1 -0
- package/dist/emulate/workos/routes/authorization-resources.d.ts +2 -0
- package/dist/emulate/workos/routes/authorization-resources.js +128 -0
- package/dist/emulate/workos/routes/authorization-resources.js.map +1 -0
- package/dist/emulate/workos/routes/authorization-roles.d.ts +2 -0
- package/dist/emulate/workos/routes/authorization-roles.js +136 -0
- package/dist/emulate/workos/routes/authorization-roles.js.map +1 -0
- package/dist/emulate/workos/routes/config.d.ts +2 -0
- package/dist/emulate/workos/routes/config.js +56 -0
- package/dist/emulate/workos/routes/config.js.map +1 -0
- package/dist/emulate/workos/routes/connect.d.ts +2 -0
- package/dist/emulate/workos/routes/connect.js +69 -0
- package/dist/emulate/workos/routes/connect.js.map +1 -0
- package/dist/emulate/workos/routes/connections.d.ts +2 -0
- package/dist/emulate/workos/routes/connections.js +77 -0
- package/dist/emulate/workos/routes/connections.js.map +1 -0
- package/dist/emulate/workos/routes/data-integrations.d.ts +2 -0
- package/dist/emulate/workos/routes/data-integrations.js +55 -0
- package/dist/emulate/workos/routes/data-integrations.js.map +1 -0
- package/dist/emulate/workos/routes/directories.d.ts +2 -0
- package/dist/emulate/workos/routes/directories.js +106 -0
- package/dist/emulate/workos/routes/directories.js.map +1 -0
- package/dist/emulate/workos/routes/email-verification.d.ts +2 -0
- package/dist/emulate/workos/routes/email-verification.js +49 -0
- package/dist/emulate/workos/routes/email-verification.js.map +1 -0
- package/dist/emulate/workos/routes/events.d.ts +2 -0
- package/dist/emulate/workos/routes/events.js +21 -0
- package/dist/emulate/workos/routes/events.js.map +1 -0
- package/dist/emulate/workos/routes/feature-flags.d.ts +2 -0
- package/dist/emulate/workos/routes/feature-flags.js +131 -0
- package/dist/emulate/workos/routes/feature-flags.js.map +1 -0
- package/dist/emulate/workos/routes/invitations.d.ts +2 -0
- package/dist/emulate/workos/routes/invitations.js +125 -0
- package/dist/emulate/workos/routes/invitations.js.map +1 -0
- package/dist/emulate/workos/routes/legacy-mfa.d.ts +2 -0
- package/dist/emulate/workos/routes/legacy-mfa.js +75 -0
- package/dist/emulate/workos/routes/legacy-mfa.js.map +1 -0
- package/dist/emulate/workos/routes/magic-auth.d.ts +2 -0
- package/dist/emulate/workos/routes/magic-auth.js +32 -0
- package/dist/emulate/workos/routes/magic-auth.js.map +1 -0
- package/dist/emulate/workos/routes/memberships.d.ts +2 -0
- package/dist/emulate/workos/routes/memberships.js +118 -0
- package/dist/emulate/workos/routes/memberships.js.map +1 -0
- package/dist/emulate/workos/routes/organization-domains.d.ts +2 -0
- package/dist/emulate/workos/routes/organization-domains.js +58 -0
- package/dist/emulate/workos/routes/organization-domains.js.map +1 -0
- package/dist/emulate/workos/routes/organizations.d.ts +2 -0
- package/dist/emulate/workos/routes/organizations.js +133 -0
- package/dist/emulate/workos/routes/organizations.js.map +1 -0
- package/dist/emulate/workos/routes/password-reset.d.ts +2 -0
- package/dist/emulate/workos/routes/password-reset.js +61 -0
- package/dist/emulate/workos/routes/password-reset.js.map +1 -0
- package/dist/emulate/workos/routes/pipes.d.ts +2 -0
- package/dist/emulate/workos/routes/pipes.js +86 -0
- package/dist/emulate/workos/routes/pipes.js.map +1 -0
- package/dist/emulate/workos/routes/portal.d.ts +2 -0
- package/dist/emulate/workos/routes/portal.js +18 -0
- package/dist/emulate/workos/routes/portal.js.map +1 -0
- package/dist/emulate/workos/routes/radar.d.ts +2 -0
- package/dist/emulate/workos/routes/radar.js +45 -0
- package/dist/emulate/workos/routes/radar.js.map +1 -0
- package/dist/emulate/workos/routes/sessions.d.ts +2 -0
- package/dist/emulate/workos/routes/sessions.js +51 -0
- package/dist/emulate/workos/routes/sessions.js.map +1 -0
- package/dist/emulate/workos/routes/sso.d.ts +2 -0
- package/dist/emulate/workos/routes/sso.js +160 -0
- package/dist/emulate/workos/routes/sso.js.map +1 -0
- package/dist/emulate/workos/routes/user-features.d.ts +2 -0
- package/dist/emulate/workos/routes/user-features.js +50 -0
- package/dist/emulate/workos/routes/user-features.js.map +1 -0
- package/dist/emulate/workos/routes/users.d.ts +2 -0
- package/dist/emulate/workos/routes/users.js +133 -0
- package/dist/emulate/workos/routes/users.js.map +1 -0
- package/dist/emulate/workos/routes/webhook-endpoints.d.ts +2 -0
- package/dist/emulate/workos/routes/webhook-endpoints.js +70 -0
- package/dist/emulate/workos/routes/webhook-endpoints.js.map +1 -0
- package/dist/emulate/workos/routes/widgets.d.ts +2 -0
- package/dist/emulate/workos/routes/widgets.js +27 -0
- package/dist/emulate/workos/routes/widgets.js.map +1 -0
- package/dist/emulate/workos/store.d.ts +48 -0
- package/dist/emulate/workos/store.js +93 -0
- package/dist/emulate/workos/store.js.map +1 -0
- package/dist/emulate/workos/webhook-signer.d.ts +1 -0
- package/dist/emulate/workos/webhook-signer.js +8 -0
- package/dist/emulate/workos/webhook-signer.js.map +1 -0
- package/dist/gen-routes-lib.spec.ts +659 -0
- package/dist/gen-routes-lib.ts +647 -0
- package/dist/gen-routes.ts +96 -0
- package/dist/lib/dev-command.d.ts +26 -0
- package/dist/lib/dev-command.js +122 -0
- package/dist/lib/dev-command.js.map +1 -0
- package/dist/utils/help-json.js +31 -0
- package/dist/utils/help-json.js.map +1 -1
- package/package.json +20 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/commands/seed.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'node:fs';\nimport chalk from 'chalk';\nimport { parse as parseYaml } from 'yaml';\nimport type { DomainData } from '@workos-inc/node';\nimport { createWorkOSClient, type WorkOSCLIClient } from '../lib/workos-client.js';\nimport { outputJson, outputSuccess, isJsonMode, exitWithError } from '../utils/output.js';\n\nconst STATE_FILE = '.workos-seed-state.json';\n\ninterface SeedConfig {\n organizations?: Array<{ name: string; domains?: string[] }>;\n permissions?: Array<{ name: string; slug: string; description?: string }>;\n roles?: Array<{ name: string; slug: string; description?: string; permissions?: string[] }>;\n config?: {\n redirect_uris?: string[];\n cors_origins?: string[];\n homepage_url?: string;\n };\n}\n\ninterface SeedState {\n permissions: Array<{ slug: string }>;\n roles: Array<{ slug: string }>;\n organizations: Array<{ id: string; name: string }>;\n createdAt: string;\n}\n\nfunction loadState(): SeedState | null {\n if (!existsSync(STATE_FILE)) return null;\n try {\n return JSON.parse(readFileSync(STATE_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction saveState(state: SeedState): void {\n writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));\n}\n\nexport async function runSeed(\n options: { file?: string; clean?: boolean },\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n if (options.clean) {\n await runSeedClean(apiKey, baseUrl);\n return;\n }\n\n if (!options.file) {\n return exitWithError({\n code: 'missing_args',\n message: 'Provide a seed file: workos seed --file=workos-seed.yml',\n });\n }\n\n if (!existsSync(options.file)) {\n return exitWithError({\n code: 'file_not_found',\n message: `Seed file not found: ${options.file}. Create workos-seed.yml or run \\`workos seed\\` without --file for interactive mode.`,\n });\n }\n\n const raw = readFileSync(options.file, 'utf-8');\n let seedConfig: SeedConfig;\n try {\n seedConfig = parseYaml(raw) as SeedConfig;\n } catch (error) {\n exitWithError({\n code: 'invalid_yaml',\n message: `Failed to parse seed file: ${error instanceof Error ? error.message : 'Invalid YAML'}`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n const state: SeedState = { permissions: [], roles: [], organizations: [], createdAt: new Date().toISOString() };\n\n try {\n // 1. Create permissions\n if (seedConfig.permissions) {\n for (const perm of seedConfig.permissions) {\n try {\n await client.sdk.authorization.createPermission({\n slug: perm.slug,\n name: perm.name,\n ...(perm.description && { description: perm.description }),\n });\n state.permissions.push({ slug: perm.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created permission: ${perm.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Permission exists: ${perm.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 2. Create roles + assign permissions\n if (seedConfig.roles) {\n for (const role of seedConfig.roles) {\n try {\n await client.sdk.authorization.createEnvironmentRole({\n slug: role.slug,\n name: role.name,\n ...(role.description && { description: role.description }),\n });\n state.roles.push({ slug: role.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created role: ${role.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Role exists: ${role.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n\n if (role.permissions?.length) {\n try {\n await client.sdk.authorization.setEnvironmentRolePermissions(role.slug, {\n permissions: role.permissions,\n });\n if (!isJsonMode())\n console.log(chalk.green(` Set permissions on ${role.slug}: ${role.permissions.join(', ')}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Failed to set permissions on ${role.slug}`));\n }\n }\n }\n }\n\n // 3. Create organizations\n if (seedConfig.organizations) {\n for (const org of seedConfig.organizations) {\n try {\n const created = await client.sdk.organizations.createOrganization({\n name: org.name,\n ...(org.domains?.length && {\n domainData: org.domains.map((d) => ({ domain: d, state: 'verified' as DomainData['state'] })),\n }),\n });\n state.organizations.push({ id: created.id, name: created.name });\n if (!isJsonMode()) console.log(chalk.green(` Created org: ${created.name} (${created.id})`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Org may exist: ${org.name} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 4. Configure redirect URIs, CORS, homepage\n if (seedConfig.config) {\n await applyConfig(client, seedConfig.config);\n }\n\n saveState(state);\n\n if (isJsonMode()) {\n outputJson({ status: 'ok', message: 'Seed complete', state });\n } else {\n console.log(chalk.green('\\nSeed complete.'));\n console.log(chalk.dim(`State saved to ${STATE_FILE}`));\n }\n } catch (error) {\n // Partial failure — save what was created so --clean can tear down\n saveState(state);\n exitWithError({\n code: 'seed_failed',\n message: `Seed failed: ${error instanceof Error ? error.message : 'Unknown error'}. Partial state saved to ${STATE_FILE}. Run \\`workos seed --clean\\` to tear down.`,\n details: state,\n });\n }\n}\n\nasync function runSeedClean(apiKey: string, baseUrl?: string): Promise<void> {\n const state = loadState();\n if (!state) {\n return exitWithError({\n code: 'no_state',\n message: `No seed state found (${STATE_FILE}). Nothing to clean.`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n\n // Delete in reverse order: orgs → roles → permissions\n for (const org of state.organizations.reverse()) {\n try {\n await client.sdk.organizations.deleteOrganization(org.id);\n if (!isJsonMode()) console.log(chalk.green(` Deleted org: ${org.name} (${org.id})`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete org ${org.id}`));\n }\n }\n\n for (const role of state.roles.reverse()) {\n try {\n // Env roles can't be deleted via SDK — skip silently\n if (!isJsonMode()) console.log(chalk.dim(` Env role ${role.slug}: skipped (env roles cannot be deleted)`));\n } catch {\n // ignore\n }\n }\n\n for (const perm of state.permissions.reverse()) {\n try {\n await client.sdk.authorization.deletePermission(perm.slug);\n if (!isJsonMode()) console.log(chalk.green(` Deleted permission: ${perm.slug}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete permission ${perm.slug}`));\n }\n }\n\n unlinkSync(STATE_FILE);\n outputSuccess('Seed cleanup complete', { stateFile: STATE_FILE });\n}\n\nasync function applyConfig(client: WorkOSCLIClient, config: NonNullable<SeedConfig['config']>): Promise<void> {\n if (config.redirect_uris) {\n for (const uri of config.redirect_uris) {\n const result = await client.redirectUris.add(uri);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` Redirect URI exists: ${uri}`)\n : chalk.green(` Added redirect URI: ${uri}`),\n );\n }\n }\n }\n\n if (config.cors_origins) {\n for (const origin of config.cors_origins) {\n const result = await client.corsOrigins.add(origin);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` CORS origin exists: ${origin}`)\n : chalk.green(` Added CORS origin: ${origin}`),\n );\n }\n }\n }\n\n if (config.homepage_url) {\n await client.homepageUrl.set(config.homepage_url);\n if (!isJsonMode()) console.log(chalk.green(` Set homepage URL: ${config.homepage_url}`));\n }\n}\n\nfunction isAlreadyExists(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n return msg.includes('already exists') || msg.includes('conflict') || msg.includes('duplicate');\n}\n"]}
|
|
1
|
+
{"version":3,"file":"seed.js","sourceRoot":"","sources":["../../src/commands/seed.ts"],"names":[],"mappings":"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","sourcesContent":["import { readFileSync, writeFileSync, existsSync, unlinkSync } from 'node:fs';\nimport chalk from 'chalk';\nimport { parse as parseYaml } from 'yaml';\nimport type { DomainData } from '@workos-inc/node';\nimport { createWorkOSClient, type WorkOSCLIClient } from '../lib/workos-client.js';\nimport { outputJson, outputSuccess, isJsonMode, exitWithError } from '../utils/output.js';\n\nconst STATE_FILE = '.workos-seed-state.json';\n\ninterface SeedConfig {\n organizations?: Array<{ name: string; domains?: string[] }>;\n permissions?: Array<{ name: string; slug: string; description?: string }>;\n roles?: Array<{ name: string; slug: string; description?: string; permissions?: string[] }>;\n config?: {\n redirect_uris?: string[];\n cors_origins?: string[];\n homepage_url?: string;\n };\n}\n\ninterface SeedState {\n permissions: Array<{ slug: string }>;\n roles: Array<{ slug: string }>;\n organizations: Array<{ id: string; name: string }>;\n createdAt: string;\n}\n\nfunction loadState(): SeedState | null {\n if (!existsSync(STATE_FILE)) return null;\n try {\n return JSON.parse(readFileSync(STATE_FILE, 'utf-8'));\n } catch {\n return null;\n }\n}\n\nfunction saveState(state: SeedState): void {\n writeFileSync(STATE_FILE, JSON.stringify(state, null, 2));\n}\n\nconst DEFAULT_SEED_FILE = 'workos-seed.yml';\n\nconst SEED_TEMPLATE = `# WorkOS seed file — provision resources with \\`workos seed --file=${DEFAULT_SEED_FILE}\\`\n# Resources are created in dependency order: permissions → roles → organizations → config.\n# Existing resources are skipped (idempotent). Run \\`workos seed --clean\\` to tear down.\n\npermissions:\n - name: Read Posts\n slug: posts:read\n - name: Write Posts\n slug: posts:write\n description: Create and edit posts\n\nroles:\n - name: Admin\n slug: admin\n description: Full access\n permissions:\n - posts:read\n - posts:write\n - name: Viewer\n slug: viewer\n permissions:\n - posts:read\n\norganizations:\n - name: Acme Corp\n domains:\n - acme.com\n\nconfig:\n redirect_uris:\n - http://localhost:3000/auth/callback\n cors_origins:\n - http://localhost:3000\n homepage_url: http://localhost:3000\n`;\n\nexport function runSeedInit(): void {\n if (existsSync(DEFAULT_SEED_FILE)) {\n if (isJsonMode()) {\n outputJson({ status: 'exists', message: `${DEFAULT_SEED_FILE} already exists`, file: DEFAULT_SEED_FILE });\n } else {\n console.log(chalk.yellow(`${DEFAULT_SEED_FILE} already exists — not overwriting.`));\n }\n return;\n }\n\n writeFileSync(DEFAULT_SEED_FILE, SEED_TEMPLATE);\n\n if (isJsonMode()) {\n outputJson({ status: 'ok', message: `Created ${DEFAULT_SEED_FILE}`, file: DEFAULT_SEED_FILE });\n } else {\n console.log(chalk.green(`Created ${DEFAULT_SEED_FILE}`));\n console.log(chalk.dim('Edit the file, then run: workos seed --file=workos-seed.yml'));\n }\n}\n\nexport async function runSeed(\n options: { file?: string; clean?: boolean; init?: boolean },\n apiKey: string,\n baseUrl?: string,\n): Promise<void> {\n if (options.init) {\n runSeedInit();\n return;\n }\n\n if (options.clean) {\n await runSeedClean(apiKey, baseUrl);\n return;\n }\n\n if (!options.file) {\n return exitWithError({\n code: 'missing_args',\n message:\n 'Provide a seed file: workos seed --file=workos-seed.yml\\nRun workos seed --init to create an example seed file.',\n });\n }\n\n if (!existsSync(options.file)) {\n return exitWithError({\n code: 'file_not_found',\n message: `Seed file not found: ${options.file}. Create workos-seed.yml or run \\`workos seed\\` without --file for interactive mode.`,\n });\n }\n\n const raw = readFileSync(options.file, 'utf-8');\n let seedConfig: SeedConfig;\n try {\n seedConfig = parseYaml(raw) as SeedConfig;\n } catch (error) {\n exitWithError({\n code: 'invalid_yaml',\n message: `Failed to parse seed file: ${error instanceof Error ? error.message : 'Invalid YAML'}`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n const state: SeedState = { permissions: [], roles: [], organizations: [], createdAt: new Date().toISOString() };\n\n try {\n // 1. Create permissions\n if (seedConfig.permissions) {\n for (const perm of seedConfig.permissions) {\n try {\n await client.sdk.authorization.createPermission({\n slug: perm.slug,\n name: perm.name,\n ...(perm.description && { description: perm.description }),\n });\n state.permissions.push({ slug: perm.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created permission: ${perm.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Permission exists: ${perm.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 2. Create roles + assign permissions\n if (seedConfig.roles) {\n for (const role of seedConfig.roles) {\n try {\n await client.sdk.authorization.createEnvironmentRole({\n slug: role.slug,\n name: role.name,\n ...(role.description && { description: role.description }),\n });\n state.roles.push({ slug: role.slug });\n if (!isJsonMode()) console.log(chalk.green(` Created role: ${role.slug}`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Role exists: ${role.slug} (skipped)`));\n } else {\n throw error;\n }\n }\n\n if (role.permissions?.length) {\n try {\n await client.sdk.authorization.setEnvironmentRolePermissions(role.slug, {\n permissions: role.permissions,\n });\n if (!isJsonMode())\n console.log(chalk.green(` Set permissions on ${role.slug}: ${role.permissions.join(', ')}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Failed to set permissions on ${role.slug}`));\n }\n }\n }\n }\n\n // 3. Create organizations\n if (seedConfig.organizations) {\n for (const org of seedConfig.organizations) {\n try {\n const created = await client.sdk.organizations.createOrganization({\n name: org.name,\n ...(org.domains?.length && {\n domainData: org.domains.map((d) => ({ domain: d, state: 'verified' as DomainData['state'] })),\n }),\n });\n state.organizations.push({ id: created.id, name: created.name });\n if (!isJsonMode()) console.log(chalk.green(` Created org: ${created.name} (${created.id})`));\n } catch (error: unknown) {\n if (isAlreadyExists(error)) {\n if (!isJsonMode()) console.log(chalk.dim(` Org may exist: ${org.name} (skipped)`));\n } else {\n throw error;\n }\n }\n }\n }\n\n // 4. Configure redirect URIs, CORS, homepage\n if (seedConfig.config) {\n await applyConfig(client, seedConfig.config);\n }\n\n saveState(state);\n\n if (isJsonMode()) {\n outputJson({ status: 'ok', message: 'Seed complete', state });\n } else {\n console.log(chalk.green('\\nSeed complete.'));\n console.log(chalk.dim(`State saved to ${STATE_FILE}`));\n }\n } catch (error) {\n // Partial failure — save what was created so --clean can tear down\n saveState(state);\n exitWithError({\n code: 'seed_failed',\n message: `Seed failed: ${error instanceof Error ? error.message : 'Unknown error'}. Partial state saved to ${STATE_FILE}. Run \\`workos seed --clean\\` to tear down.`,\n details: state,\n });\n }\n}\n\nasync function runSeedClean(apiKey: string, baseUrl?: string): Promise<void> {\n const state = loadState();\n if (!state) {\n return exitWithError({\n code: 'no_state',\n message: `No seed state found (${STATE_FILE}). Nothing to clean.`,\n });\n }\n\n const client = createWorkOSClient(apiKey, baseUrl);\n\n // Delete in reverse order: orgs → roles → permissions\n for (const org of state.organizations.reverse()) {\n try {\n await client.sdk.organizations.deleteOrganization(org.id);\n if (!isJsonMode()) console.log(chalk.green(` Deleted org: ${org.name} (${org.id})`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete org ${org.id}`));\n }\n }\n\n for (const role of state.roles.reverse()) {\n try {\n // Env roles can't be deleted via SDK — skip silently\n if (!isJsonMode()) console.log(chalk.dim(` Env role ${role.slug}: skipped (env roles cannot be deleted)`));\n } catch {\n // ignore\n }\n }\n\n for (const perm of state.permissions.reverse()) {\n try {\n await client.sdk.authorization.deletePermission(perm.slug);\n if (!isJsonMode()) console.log(chalk.green(` Deleted permission: ${perm.slug}`));\n } catch {\n if (!isJsonMode()) console.log(chalk.yellow(` Warning: Could not delete permission ${perm.slug}`));\n }\n }\n\n unlinkSync(STATE_FILE);\n outputSuccess('Seed cleanup complete', { stateFile: STATE_FILE });\n}\n\nasync function applyConfig(client: WorkOSCLIClient, config: NonNullable<SeedConfig['config']>): Promise<void> {\n if (config.redirect_uris) {\n for (const uri of config.redirect_uris) {\n const result = await client.redirectUris.add(uri);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` Redirect URI exists: ${uri}`)\n : chalk.green(` Added redirect URI: ${uri}`),\n );\n }\n }\n }\n\n if (config.cors_origins) {\n for (const origin of config.cors_origins) {\n const result = await client.corsOrigins.add(origin);\n if (!isJsonMode()) {\n console.log(\n result.alreadyExists\n ? chalk.dim(` CORS origin exists: ${origin}`)\n : chalk.green(` Added CORS origin: ${origin}`),\n );\n }\n }\n }\n\n if (config.homepage_url) {\n await client.homepageUrl.set(config.homepage_url);\n if (!isJsonMode()) console.log(chalk.green(` Set homepage URL: ${config.homepage_url}`));\n }\n}\n\nfunction isAlreadyExists(error: unknown): boolean {\n if (!(error instanceof Error)) return false;\n const msg = error.message.toLowerCase();\n return msg.includes('already exists') || msg.includes('conflict') || msg.includes('duplicate');\n}\n"]}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
export declare function generateId(prefix: string): string;
|
|
2
|
+
export declare function resetIdState(): void;
|
|
3
|
+
export declare const ID_PREFIXES: {
|
|
4
|
+
readonly user: "user";
|
|
5
|
+
readonly organization: "org";
|
|
6
|
+
readonly organization_membership: "om";
|
|
7
|
+
readonly organization_domain: "org_domain";
|
|
8
|
+
readonly connection: "conn";
|
|
9
|
+
readonly connection_domain: "conn_domain";
|
|
10
|
+
readonly directory: "directory";
|
|
11
|
+
readonly directory_user: "directory_user";
|
|
12
|
+
readonly directory_group: "directory_grp";
|
|
13
|
+
readonly event: "event";
|
|
14
|
+
readonly invitation: "inv";
|
|
15
|
+
readonly session: "session";
|
|
16
|
+
readonly email_verification: "email_verification";
|
|
17
|
+
readonly password_reset: "password_reset";
|
|
18
|
+
readonly magic_auth: "magic_auth";
|
|
19
|
+
readonly authentication_factor: "auth_factor";
|
|
20
|
+
readonly authentication_challenge: "auth_challenge";
|
|
21
|
+
readonly api_key: "api_key";
|
|
22
|
+
readonly profile: "prof";
|
|
23
|
+
readonly pipe_connection: "pipe_conn";
|
|
24
|
+
readonly audit_log_action: "audit_action";
|
|
25
|
+
readonly audit_log_event: "audit_event";
|
|
26
|
+
readonly audit_log_export: "audit_export";
|
|
27
|
+
readonly feature_flag: "ff";
|
|
28
|
+
readonly flag_target: "ff_target";
|
|
29
|
+
readonly connect_application: "connect_app";
|
|
30
|
+
readonly client_secret: "client_secret";
|
|
31
|
+
readonly data_integration_auth: "di_auth";
|
|
32
|
+
readonly radar_attempt: "radar_attempt";
|
|
33
|
+
};
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
const ENCODING = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; // Crockford's Base32
|
|
2
|
+
const ENCODING_LEN = ENCODING.length; // 32
|
|
3
|
+
const TIME_LEN = 10; // 10 chars encodes 48-bit ms timestamp
|
|
4
|
+
const RANDOM_LEN = 16; // 16 chars of randomness
|
|
5
|
+
let lastTime = 0;
|
|
6
|
+
export function generateId(prefix) {
|
|
7
|
+
let now = Date.now();
|
|
8
|
+
if (now <= lastTime) {
|
|
9
|
+
now = lastTime + 1;
|
|
10
|
+
}
|
|
11
|
+
lastTime = now;
|
|
12
|
+
let timeStr = '';
|
|
13
|
+
let t = now;
|
|
14
|
+
for (let i = TIME_LEN - 1; i >= 0; i--) {
|
|
15
|
+
timeStr = ENCODING[t % ENCODING_LEN] + timeStr;
|
|
16
|
+
t = Math.floor(t / ENCODING_LEN);
|
|
17
|
+
}
|
|
18
|
+
let randStr = '';
|
|
19
|
+
for (let i = 0; i < RANDOM_LEN; i++) {
|
|
20
|
+
randStr += ENCODING[Math.floor(Math.random() * ENCODING_LEN)];
|
|
21
|
+
}
|
|
22
|
+
return `${prefix}_${timeStr}${randStr}`;
|
|
23
|
+
}
|
|
24
|
+
export function resetIdState() {
|
|
25
|
+
lastTime = 0;
|
|
26
|
+
}
|
|
27
|
+
export const ID_PREFIXES = {
|
|
28
|
+
user: 'user',
|
|
29
|
+
organization: 'org',
|
|
30
|
+
organization_membership: 'om',
|
|
31
|
+
organization_domain: 'org_domain',
|
|
32
|
+
connection: 'conn',
|
|
33
|
+
connection_domain: 'conn_domain',
|
|
34
|
+
directory: 'directory',
|
|
35
|
+
directory_user: 'directory_user',
|
|
36
|
+
directory_group: 'directory_grp',
|
|
37
|
+
event: 'event',
|
|
38
|
+
invitation: 'inv',
|
|
39
|
+
session: 'session',
|
|
40
|
+
email_verification: 'email_verification',
|
|
41
|
+
password_reset: 'password_reset',
|
|
42
|
+
magic_auth: 'magic_auth',
|
|
43
|
+
authentication_factor: 'auth_factor',
|
|
44
|
+
authentication_challenge: 'auth_challenge',
|
|
45
|
+
api_key: 'api_key',
|
|
46
|
+
profile: 'prof',
|
|
47
|
+
pipe_connection: 'pipe_conn',
|
|
48
|
+
audit_log_action: 'audit_action',
|
|
49
|
+
audit_log_event: 'audit_event',
|
|
50
|
+
audit_log_export: 'audit_export',
|
|
51
|
+
feature_flag: 'ff',
|
|
52
|
+
flag_target: 'ff_target',
|
|
53
|
+
connect_application: 'connect_app',
|
|
54
|
+
client_secret: 'client_secret',
|
|
55
|
+
data_integration_auth: 'di_auth',
|
|
56
|
+
radar_attempt: 'radar_attempt',
|
|
57
|
+
};
|
|
58
|
+
//# sourceMappingURL=id.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"id.js","sourceRoot":"","sources":["../../../src/emulate/core/id.ts"],"names":[],"mappings":"AAAA,MAAM,QAAQ,GAAG,kCAAkC,CAAC,CAAC,qBAAqB;AAC1E,MAAM,YAAY,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,KAAK;AAC3C,MAAM,QAAQ,GAAG,EAAE,CAAC,CAAC,uCAAuC;AAC5D,MAAM,UAAU,GAAG,EAAE,CAAC,CAAC,yBAAyB;AAEhD,IAAI,QAAQ,GAAG,CAAC,CAAC;AAEjB,MAAM,UAAU,UAAU,CAAC,MAAc;IACvC,IAAI,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IACrB,IAAI,GAAG,IAAI,QAAQ,EAAE,CAAC;QACpB,GAAG,GAAG,QAAQ,GAAG,CAAC,CAAC;IACrB,CAAC;IACD,QAAQ,GAAG,GAAG,CAAC;IAEf,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,IAAI,CAAC,GAAG,GAAG,CAAC;IACZ,KAAK,IAAI,CAAC,GAAG,QAAQ,GAAG,CAAC,EAAE,CAAC,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,OAAO,GAAG,QAAQ,CAAC,CAAC,GAAG,YAAY,CAAC,GAAG,OAAO,CAAC;QAC/C,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,GAAG,YAAY,CAAC,CAAC;IACnC,CAAC;IAED,IAAI,OAAO,GAAG,EAAE,CAAC;IACjB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,UAAU,EAAE,CAAC,EAAE,EAAE,CAAC;QACpC,OAAO,IAAI,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,EAAE,GAAG,YAAY,CAAC,CAAC,CAAC;IAChE,CAAC;IAED,OAAO,GAAG,MAAM,IAAI,OAAO,GAAG,OAAO,EAAE,CAAC;AAC1C,CAAC;AAED,MAAM,UAAU,YAAY;IAC1B,QAAQ,GAAG,CAAC,CAAC;AACf,CAAC;AAED,MAAM,CAAC,MAAM,WAAW,GAAG;IACzB,IAAI,EAAE,MAAM;IACZ,YAAY,EAAE,KAAK;IACnB,uBAAuB,EAAE,IAAI;IAC7B,mBAAmB,EAAE,YAAY;IACjC,UAAU,EAAE,MAAM;IAClB,iBAAiB,EAAE,aAAa;IAChC,SAAS,EAAE,WAAW;IACtB,cAAc,EAAE,gBAAgB;IAChC,eAAe,EAAE,eAAe;IAChC,KAAK,EAAE,OAAO;IACd,UAAU,EAAE,KAAK;IACjB,OAAO,EAAE,SAAS;IAClB,kBAAkB,EAAE,oBAAoB;IACxC,cAAc,EAAE,gBAAgB;IAChC,UAAU,EAAE,YAAY;IACxB,qBAAqB,EAAE,aAAa;IACpC,wBAAwB,EAAE,gBAAgB;IAC1C,OAAO,EAAE,SAAS;IAClB,OAAO,EAAE,MAAM;IACf,eAAe,EAAE,WAAW;IAC5B,gBAAgB,EAAE,cAAc;IAChC,eAAe,EAAE,aAAa;IAC9B,gBAAgB,EAAE,cAAc;IAChC,YAAY,EAAE,IAAI;IAClB,WAAW,EAAE,WAAW;IACxB,mBAAmB,EAAE,aAAa;IAClC,aAAa,EAAE,eAAe;IAC9B,qBAAqB,EAAE,SAAS;IAChC,aAAa,EAAE,eAAe;CACtB,CAAC","sourcesContent":["const ENCODING = '0123456789ABCDEFGHJKMNPQRSTVWXYZ'; // Crockford's Base32\nconst ENCODING_LEN = ENCODING.length; // 32\nconst TIME_LEN = 10; // 10 chars encodes 48-bit ms timestamp\nconst RANDOM_LEN = 16; // 16 chars of randomness\n\nlet lastTime = 0;\n\nexport function generateId(prefix: string): string {\n let now = Date.now();\n if (now <= lastTime) {\n now = lastTime + 1;\n }\n lastTime = now;\n\n let timeStr = '';\n let t = now;\n for (let i = TIME_LEN - 1; i >= 0; i--) {\n timeStr = ENCODING[t % ENCODING_LEN] + timeStr;\n t = Math.floor(t / ENCODING_LEN);\n }\n\n let randStr = '';\n for (let i = 0; i < RANDOM_LEN; i++) {\n randStr += ENCODING[Math.floor(Math.random() * ENCODING_LEN)];\n }\n\n return `${prefix}_${timeStr}${randStr}`;\n}\n\nexport function resetIdState(): void {\n lastTime = 0;\n}\n\nexport const ID_PREFIXES = {\n user: 'user',\n organization: 'org',\n organization_membership: 'om',\n organization_domain: 'org_domain',\n connection: 'conn',\n connection_domain: 'conn_domain',\n directory: 'directory',\n directory_user: 'directory_user',\n directory_group: 'directory_grp',\n event: 'event',\n invitation: 'inv',\n session: 'session',\n email_verification: 'email_verification',\n password_reset: 'password_reset',\n magic_auth: 'magic_auth',\n authentication_factor: 'auth_factor',\n authentication_challenge: 'auth_challenge',\n api_key: 'api_key',\n profile: 'prof',\n pipe_connection: 'pipe_conn',\n audit_log_action: 'audit_action',\n audit_log_event: 'audit_event',\n audit_log_export: 'audit_export',\n feature_flag: 'ff',\n flag_target: 'ff_target',\n connect_application: 'connect_app',\n client_secret: 'client_secret',\n data_integration_auth: 'di_auth',\n radar_attempt: 'radar_attempt',\n} as const;\n"]}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Store, Collection, type Entity, type InsertInput, type FilterFn, type SortFn, type CollectionHooks, } from './store.js';
|
|
2
|
+
export { generateId, resetIdState, ID_PREFIXES } from './id.js';
|
|
3
|
+
export { cursorPaginate, type CursorPaginationOptions, type CursorPaginatedResult } from './pagination.js';
|
|
4
|
+
export { JWTManager, type JWTPayload } from './jwt.js';
|
|
5
|
+
export { createServer, type ServerOptions } from './server.js';
|
|
6
|
+
export { type ServicePlugin, type RouteContext } from './plugin.js';
|
|
7
|
+
export { WorkOSApiError, createApiErrorHandler, requestIdMiddleware, notFound, validationError, unauthorized, forbidden, parseJsonBody, } from './middleware/error-handler.js';
|
|
8
|
+
export { authMiddleware, type WorkOSAppEnv, type WorkOSAuthContext, type ApiKeyMap } from './middleware/auth.js';
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
export { Store, Collection, } from './store.js';
|
|
2
|
+
export { generateId, resetIdState, ID_PREFIXES } from './id.js';
|
|
3
|
+
export { cursorPaginate } from './pagination.js';
|
|
4
|
+
export { JWTManager } from './jwt.js';
|
|
5
|
+
export { createServer } from './server.js';
|
|
6
|
+
export { WorkOSApiError, createApiErrorHandler, requestIdMiddleware, notFound, validationError, unauthorized, forbidden, parseJsonBody, } from './middleware/error-handler.js';
|
|
7
|
+
export { authMiddleware } from './middleware/auth.js';
|
|
8
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/emulate/core/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,EACL,UAAU,GAMX,MAAM,YAAY,CAAC;AACpB,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,WAAW,EAAE,MAAM,SAAS,CAAC;AAChE,OAAO,EAAE,cAAc,EAA4D,MAAM,iBAAiB,CAAC;AAC3G,OAAO,EAAE,UAAU,EAAmB,MAAM,UAAU,CAAC;AACvD,OAAO,EAAE,YAAY,EAAsB,MAAM,aAAa,CAAC;AAE/D,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,mBAAmB,EACnB,QAAQ,EACR,eAAe,EACf,YAAY,EACZ,SAAS,EACT,aAAa,GACd,MAAM,+BAA+B,CAAC;AACvC,OAAO,EAAE,cAAc,EAA6D,MAAM,sBAAsB,CAAC","sourcesContent":["export {\n Store,\n Collection,\n type Entity,\n type InsertInput,\n type FilterFn,\n type SortFn,\n type CollectionHooks,\n} from './store.js';\nexport { generateId, resetIdState, ID_PREFIXES } from './id.js';\nexport { cursorPaginate, type CursorPaginationOptions, type CursorPaginatedResult } from './pagination.js';\nexport { JWTManager, type JWTPayload } from './jwt.js';\nexport { createServer, type ServerOptions } from './server.js';\nexport { type ServicePlugin, type RouteContext } from './plugin.js';\nexport {\n WorkOSApiError,\n createApiErrorHandler,\n requestIdMiddleware,\n notFound,\n validationError,\n unauthorized,\n forbidden,\n parseJsonBody,\n} from './middleware/error-handler.js';\nexport { authMiddleware, type WorkOSAppEnv, type WorkOSAuthContext, type ApiKeyMap } from './middleware/auth.js';\n"]}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export interface JWTPayload {
|
|
2
|
+
sub: string;
|
|
3
|
+
sid?: string;
|
|
4
|
+
org_id?: string;
|
|
5
|
+
role?: string;
|
|
6
|
+
permissions?: string[];
|
|
7
|
+
iss: string;
|
|
8
|
+
aud: string;
|
|
9
|
+
exp: number;
|
|
10
|
+
iat: number;
|
|
11
|
+
}
|
|
12
|
+
interface SignOptions {
|
|
13
|
+
expiresIn?: number;
|
|
14
|
+
}
|
|
15
|
+
export declare class JWTManager {
|
|
16
|
+
private privateKey;
|
|
17
|
+
private publicKey;
|
|
18
|
+
private kid;
|
|
19
|
+
issuer: string;
|
|
20
|
+
constructor(issuer?: string);
|
|
21
|
+
sign(payload: Omit<JWTPayload, 'iss' | 'iat' | 'exp'>, options?: SignOptions): string;
|
|
22
|
+
verify(token: string): JWTPayload;
|
|
23
|
+
getJWKS(): {
|
|
24
|
+
keys: Record<string, unknown>[];
|
|
25
|
+
};
|
|
26
|
+
getPublicKeyPem(): string;
|
|
27
|
+
}
|
|
28
|
+
export {};
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
import { createSign, createVerify, generateKeyPairSync } from 'node:crypto';
|
|
2
|
+
function base64url(input) {
|
|
3
|
+
const buf = typeof input === 'string' ? Buffer.from(input) : input;
|
|
4
|
+
return buf.toString('base64url');
|
|
5
|
+
}
|
|
6
|
+
function base64urlDecode(input) {
|
|
7
|
+
return Buffer.from(input, 'base64url');
|
|
8
|
+
}
|
|
9
|
+
export class JWTManager {
|
|
10
|
+
privateKey;
|
|
11
|
+
publicKey;
|
|
12
|
+
kid;
|
|
13
|
+
issuer;
|
|
14
|
+
constructor(issuer = 'https://api.workos.com') {
|
|
15
|
+
this.issuer = issuer;
|
|
16
|
+
const { privateKey, publicKey } = generateKeyPairSync('rsa', {
|
|
17
|
+
modulusLength: 2048,
|
|
18
|
+
});
|
|
19
|
+
this.privateKey = privateKey;
|
|
20
|
+
this.publicKey = publicKey;
|
|
21
|
+
this.kid = `workos_emulate_${Date.now()}`;
|
|
22
|
+
}
|
|
23
|
+
sign(payload, options) {
|
|
24
|
+
const now = Math.floor(Date.now() / 1000);
|
|
25
|
+
const expiresIn = options?.expiresIn ?? 3600;
|
|
26
|
+
const fullPayload = {
|
|
27
|
+
...payload,
|
|
28
|
+
iss: this.issuer,
|
|
29
|
+
iat: now,
|
|
30
|
+
exp: now + expiresIn,
|
|
31
|
+
};
|
|
32
|
+
const header = { alg: 'RS256', typ: 'JWT', kid: this.kid };
|
|
33
|
+
const headerB64 = base64url(JSON.stringify(header));
|
|
34
|
+
const payloadB64 = base64url(JSON.stringify(fullPayload));
|
|
35
|
+
const signingInput = `${headerB64}.${payloadB64}`;
|
|
36
|
+
const signer = createSign('RSA-SHA256');
|
|
37
|
+
signer.update(signingInput);
|
|
38
|
+
const signature = signer.sign(this.privateKey, 'base64url');
|
|
39
|
+
return `${signingInput}.${signature}`;
|
|
40
|
+
}
|
|
41
|
+
verify(token) {
|
|
42
|
+
const parts = token.split('.');
|
|
43
|
+
if (parts.length !== 3) {
|
|
44
|
+
throw new Error('Invalid token format');
|
|
45
|
+
}
|
|
46
|
+
const [headerB64, payloadB64, signature] = parts;
|
|
47
|
+
const signingInput = `${headerB64}.${payloadB64}`;
|
|
48
|
+
const verifier = createVerify('RSA-SHA256');
|
|
49
|
+
verifier.update(signingInput);
|
|
50
|
+
const valid = verifier.verify(this.publicKey, signature, 'base64url');
|
|
51
|
+
if (!valid) {
|
|
52
|
+
throw new Error('Invalid token signature');
|
|
53
|
+
}
|
|
54
|
+
const payload = JSON.parse(base64urlDecode(payloadB64).toString('utf-8'));
|
|
55
|
+
const now = Math.floor(Date.now() / 1000);
|
|
56
|
+
if (payload.exp && payload.exp < now) {
|
|
57
|
+
throw new Error('Token has expired');
|
|
58
|
+
}
|
|
59
|
+
return payload;
|
|
60
|
+
}
|
|
61
|
+
getJWKS() {
|
|
62
|
+
const jwk = this.publicKey.export({ format: 'jwk' });
|
|
63
|
+
return {
|
|
64
|
+
keys: [
|
|
65
|
+
{
|
|
66
|
+
...jwk,
|
|
67
|
+
kid: this.kid,
|
|
68
|
+
alg: 'RS256',
|
|
69
|
+
use: 'sig',
|
|
70
|
+
},
|
|
71
|
+
],
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
getPublicKeyPem() {
|
|
75
|
+
return this.publicKey.export({ type: 'spki', format: 'pem' });
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
//# sourceMappingURL=jwt.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jwt.js","sourceRoot":"","sources":["../../../src/emulate/core/jwt.ts"],"names":[],"mappings":"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","sourcesContent":["import { createSign, createVerify, generateKeyPairSync, type KeyObject } from 'node:crypto';\n\nexport interface JWTPayload {\n sub: string;\n sid?: string;\n org_id?: string;\n role?: string;\n permissions?: string[];\n iss: string;\n aud: string;\n exp: number;\n iat: number;\n}\n\ninterface SignOptions {\n expiresIn?: number;\n}\n\nfunction base64url(input: Buffer | string): string {\n const buf = typeof input === 'string' ? Buffer.from(input) : input;\n return buf.toString('base64url');\n}\n\nfunction base64urlDecode(input: string): Buffer {\n return Buffer.from(input, 'base64url');\n}\n\nexport class JWTManager {\n private privateKey: KeyObject;\n private publicKey: KeyObject;\n private kid: string;\n issuer: string;\n\n constructor(issuer = 'https://api.workos.com') {\n this.issuer = issuer;\n const { privateKey, publicKey } = generateKeyPairSync('rsa', {\n modulusLength: 2048,\n });\n this.privateKey = privateKey;\n this.publicKey = publicKey;\n this.kid = `workos_emulate_${Date.now()}`;\n }\n\n sign(payload: Omit<JWTPayload, 'iss' | 'iat' | 'exp'>, options?: SignOptions): string {\n const now = Math.floor(Date.now() / 1000);\n const expiresIn = options?.expiresIn ?? 3600;\n\n const fullPayload: JWTPayload = {\n ...payload,\n iss: this.issuer,\n iat: now,\n exp: now + expiresIn,\n };\n\n const header = { alg: 'RS256', typ: 'JWT', kid: this.kid };\n const headerB64 = base64url(JSON.stringify(header));\n const payloadB64 = base64url(JSON.stringify(fullPayload));\n const signingInput = `${headerB64}.${payloadB64}`;\n\n const signer = createSign('RSA-SHA256');\n signer.update(signingInput);\n const signature = signer.sign(this.privateKey, 'base64url');\n\n return `${signingInput}.${signature}`;\n }\n\n verify(token: string): JWTPayload {\n const parts = token.split('.');\n if (parts.length !== 3) {\n throw new Error('Invalid token format');\n }\n\n const [headerB64, payloadB64, signature] = parts;\n const signingInput = `${headerB64}.${payloadB64}`;\n\n const verifier = createVerify('RSA-SHA256');\n verifier.update(signingInput);\n const valid = verifier.verify(this.publicKey, signature, 'base64url');\n\n if (!valid) {\n throw new Error('Invalid token signature');\n }\n\n const payload = JSON.parse(base64urlDecode(payloadB64).toString('utf-8')) as JWTPayload;\n\n const now = Math.floor(Date.now() / 1000);\n if (payload.exp && payload.exp < now) {\n throw new Error('Token has expired');\n }\n\n return payload;\n }\n\n getJWKS(): { keys: Record<string, unknown>[] } {\n const jwk = this.publicKey.export({ format: 'jwk' });\n return {\n keys: [\n {\n ...jwk,\n kid: this.kid,\n alg: 'RS256',\n use: 'sig',\n },\n ],\n };\n }\n\n getPublicKeyPem(): string {\n return this.publicKey.export({ type: 'spki', format: 'pem' }) as string;\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Context, Next } from 'hono';
|
|
2
|
+
export interface WorkOSAuthContext {
|
|
3
|
+
environment: string;
|
|
4
|
+
apiKey: string;
|
|
5
|
+
}
|
|
6
|
+
export type WorkOSAppEnv = {
|
|
7
|
+
Variables: {
|
|
8
|
+
auth?: WorkOSAuthContext;
|
|
9
|
+
requestId?: string;
|
|
10
|
+
};
|
|
11
|
+
};
|
|
12
|
+
export type ApiKeyMap = Record<string, {
|
|
13
|
+
environment: string;
|
|
14
|
+
}>;
|
|
15
|
+
export declare function authMiddleware(apiKeys: ApiKeyMap): (c: Context, next: Next) => Promise<(Response & import("hono").TypedResponse<{
|
|
16
|
+
message: string;
|
|
17
|
+
code: string;
|
|
18
|
+
}, 401, "json">) | undefined>;
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
export function authMiddleware(apiKeys) {
|
|
2
|
+
return async (c, next) => {
|
|
3
|
+
const authHeader = c.req.header('Authorization');
|
|
4
|
+
if (!authHeader) {
|
|
5
|
+
return c.json({
|
|
6
|
+
message: 'Unauthorized',
|
|
7
|
+
code: 'unauthorized',
|
|
8
|
+
}, 401);
|
|
9
|
+
}
|
|
10
|
+
const token = authHeader.replace(/^Bearer\s+/i, '').trim();
|
|
11
|
+
if (!token.startsWith('sk_')) {
|
|
12
|
+
return c.json({
|
|
13
|
+
message: 'Unauthorized',
|
|
14
|
+
code: 'unauthorized',
|
|
15
|
+
}, 401);
|
|
16
|
+
}
|
|
17
|
+
const keyInfo = apiKeys[token];
|
|
18
|
+
if (!keyInfo) {
|
|
19
|
+
return c.json({
|
|
20
|
+
message: 'Unauthorized',
|
|
21
|
+
code: 'unauthorized',
|
|
22
|
+
}, 401);
|
|
23
|
+
}
|
|
24
|
+
c.set('auth', { environment: keyInfo.environment, apiKey: token });
|
|
25
|
+
await next();
|
|
26
|
+
};
|
|
27
|
+
}
|
|
28
|
+
//# sourceMappingURL=auth.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auth.js","sourceRoot":"","sources":["../../../../src/emulate/core/middleware/auth.ts"],"names":[],"mappings":"AAgBA,MAAM,UAAU,cAAc,CAAC,OAAkB;IAC/C,OAAO,KAAK,EAAE,CAAU,EAAE,IAAU,EAAE,EAAE;QACtC,MAAM,UAAU,GAAG,CAAC,CAAC,GAAG,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QACjD,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,CAAC,CAAC,IAAI,CACX;gBACE,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,cAAc;aACrB,EACD,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,MAAM,KAAK,GAAG,UAAU,CAAC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;QAE3D,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,CAAC,IAAI,CACX;gBACE,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,cAAc;aACrB,EACD,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,CAAC;QAC/B,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,CAAC,IAAI,CACX;gBACE,OAAO,EAAE,cAAc;gBACvB,IAAI,EAAE,cAAc;aACrB,EACD,GAAG,CACJ,CAAC;QACJ,CAAC;QAED,CAAC,CAAC,GAAG,CAAC,MAAM,EAAE,EAAE,WAAW,EAAE,OAAO,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAA8B,CAAC,CAAC;QAC/F,MAAM,IAAI,EAAE,CAAC;IACf,CAAC,CAAC;AACJ,CAAC","sourcesContent":["import type { Context, Next } from 'hono';\n\nexport interface WorkOSAuthContext {\n environment: string;\n apiKey: string;\n}\n\nexport type WorkOSAppEnv = {\n Variables: {\n auth?: WorkOSAuthContext;\n requestId?: string;\n };\n};\n\nexport type ApiKeyMap = Record<string, { environment: string }>;\n\nexport function authMiddleware(apiKeys: ApiKeyMap) {\n return async (c: Context, next: Next) => {\n const authHeader = c.req.header('Authorization');\n if (!authHeader) {\n return c.json(\n {\n message: 'Unauthorized',\n code: 'unauthorized',\n },\n 401,\n );\n }\n\n const token = authHeader.replace(/^Bearer\\s+/i, '').trim();\n\n if (!token.startsWith('sk_')) {\n return c.json(\n {\n message: 'Unauthorized',\n code: 'unauthorized',\n },\n 401,\n );\n }\n\n const keyInfo = apiKeys[token];\n if (!keyInfo) {\n return c.json(\n {\n message: 'Unauthorized',\n code: 'unauthorized',\n },\n 401,\n );\n }\n\n c.set('auth', { environment: keyInfo.environment, apiKey: token } satisfies WorkOSAuthContext);\n await next();\n };\n}\n"]}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Context, ErrorHandler, MiddlewareHandler } from 'hono';
|
|
2
|
+
export declare class WorkOSApiError extends Error {
|
|
3
|
+
status: number;
|
|
4
|
+
code: string;
|
|
5
|
+
errors?: Array<{
|
|
6
|
+
field: string;
|
|
7
|
+
code: string;
|
|
8
|
+
message?: string;
|
|
9
|
+
}> | undefined;
|
|
10
|
+
constructor(status: number, message: string, code: string, errors?: Array<{
|
|
11
|
+
field: string;
|
|
12
|
+
code: string;
|
|
13
|
+
message?: string;
|
|
14
|
+
}> | undefined);
|
|
15
|
+
}
|
|
16
|
+
export declare function createApiErrorHandler(): ErrorHandler;
|
|
17
|
+
export declare function requestIdMiddleware(): MiddlewareHandler;
|
|
18
|
+
export declare function notFound(resource?: string): WorkOSApiError;
|
|
19
|
+
export declare function validationError(message: string, errors?: WorkOSApiError['errors']): WorkOSApiError;
|
|
20
|
+
export declare function unauthorized(): WorkOSApiError;
|
|
21
|
+
export declare function forbidden(): WorkOSApiError;
|
|
22
|
+
export declare function parseJsonBody(c: Context): Promise<Record<string, unknown>>;
|
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
export class WorkOSApiError extends Error {
|
|
2
|
+
status;
|
|
3
|
+
code;
|
|
4
|
+
errors;
|
|
5
|
+
constructor(status, message, code, errors) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.status = status;
|
|
8
|
+
this.code = code;
|
|
9
|
+
this.errors = errors;
|
|
10
|
+
this.name = 'WorkOSApiError';
|
|
11
|
+
}
|
|
12
|
+
}
|
|
13
|
+
export function createApiErrorHandler() {
|
|
14
|
+
return (err, c) => {
|
|
15
|
+
if (err instanceof WorkOSApiError) {
|
|
16
|
+
const body = {
|
|
17
|
+
message: err.message,
|
|
18
|
+
code: err.code,
|
|
19
|
+
};
|
|
20
|
+
if (err.errors) {
|
|
21
|
+
body.errors = err.errors;
|
|
22
|
+
}
|
|
23
|
+
return c.json(body, err.status);
|
|
24
|
+
}
|
|
25
|
+
const status = errorStatus(err);
|
|
26
|
+
return c.json({
|
|
27
|
+
message: 'Internal Server Error',
|
|
28
|
+
code: 'server_error',
|
|
29
|
+
}, status);
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
export function requestIdMiddleware() {
|
|
33
|
+
return async (c, next) => {
|
|
34
|
+
const requestId = c.req.header('X-Request-ID') ?? `req_${crypto.randomUUID()}`;
|
|
35
|
+
c.set('requestId', requestId);
|
|
36
|
+
c.header('X-Request-ID', requestId);
|
|
37
|
+
await next();
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
export function notFound(resource) {
|
|
41
|
+
return new WorkOSApiError(404, resource ? `${resource} not found` : 'Not Found', 'not_found');
|
|
42
|
+
}
|
|
43
|
+
export function validationError(message, errors) {
|
|
44
|
+
return new WorkOSApiError(422, message, 'unprocessable_entity', errors);
|
|
45
|
+
}
|
|
46
|
+
export function unauthorized() {
|
|
47
|
+
return new WorkOSApiError(401, 'Unauthorized', 'unauthorized');
|
|
48
|
+
}
|
|
49
|
+
export function forbidden() {
|
|
50
|
+
return new WorkOSApiError(403, 'Forbidden', 'forbidden');
|
|
51
|
+
}
|
|
52
|
+
export async function parseJsonBody(c) {
|
|
53
|
+
try {
|
|
54
|
+
const body = await c.req.json();
|
|
55
|
+
if (body && typeof body === 'object' && !Array.isArray(body)) {
|
|
56
|
+
return body;
|
|
57
|
+
}
|
|
58
|
+
return {};
|
|
59
|
+
}
|
|
60
|
+
catch {
|
|
61
|
+
throw new WorkOSApiError(400, 'Problems parsing JSON', 'invalid_request_body');
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
function errorStatus(err) {
|
|
65
|
+
if (err && typeof err === 'object' && 'status' in err) {
|
|
66
|
+
const s = err.status;
|
|
67
|
+
if (typeof s === 'number' && Number.isFinite(s))
|
|
68
|
+
return s;
|
|
69
|
+
}
|
|
70
|
+
return 500;
|
|
71
|
+
}
|
|
72
|
+
//# sourceMappingURL=error-handler.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"error-handler.js","sourceRoot":"","sources":["../../../../src/emulate/core/middleware/error-handler.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, ErrorHandler, MiddlewareHandler } from 'hono';\nimport type { ContentfulStatusCode } from 'hono/utils/http-status';\n\nexport class WorkOSApiError extends Error {\n constructor(\n public status: number,\n message: string,\n public code: string,\n public errors?: Array<{ field: string; code: string; message?: string }>,\n ) {\n super(message);\n this.name = 'WorkOSApiError';\n }\n}\n\nexport function createApiErrorHandler(): ErrorHandler {\n return (err, c) => {\n if (err instanceof WorkOSApiError) {\n const body: Record<string, unknown> = {\n message: err.message,\n code: err.code,\n };\n if (err.errors) {\n body.errors = err.errors;\n }\n return c.json(body, err.status as ContentfulStatusCode);\n }\n\n const status = errorStatus(err);\n return c.json(\n {\n message: 'Internal Server Error',\n code: 'server_error',\n },\n status as ContentfulStatusCode,\n );\n };\n}\n\nexport function requestIdMiddleware(): MiddlewareHandler {\n return async (c, next) => {\n const requestId = c.req.header('X-Request-ID') ?? `req_${crypto.randomUUID()}`;\n c.set('requestId', requestId);\n c.header('X-Request-ID', requestId);\n await next();\n };\n}\n\nexport function notFound(resource?: string): WorkOSApiError {\n return new WorkOSApiError(404, resource ? `${resource} not found` : 'Not Found', 'not_found');\n}\n\nexport function validationError(message: string, errors?: WorkOSApiError['errors']): WorkOSApiError {\n return new WorkOSApiError(422, message, 'unprocessable_entity', errors);\n}\n\nexport function unauthorized(): WorkOSApiError {\n return new WorkOSApiError(401, 'Unauthorized', 'unauthorized');\n}\n\nexport function forbidden(): WorkOSApiError {\n return new WorkOSApiError(403, 'Forbidden', 'forbidden');\n}\n\nexport async function parseJsonBody(c: Context): Promise<Record<string, unknown>> {\n try {\n const body = await c.req.json();\n if (body && typeof body === 'object' && !Array.isArray(body)) {\n return body as Record<string, unknown>;\n }\n return {};\n } catch {\n throw new WorkOSApiError(400, 'Problems parsing JSON', 'invalid_request_body');\n }\n}\n\nfunction errorStatus(err: unknown): number {\n if (err && typeof err === 'object' && 'status' in err) {\n const s = (err as { status: unknown }).status;\n if (typeof s === 'number' && Number.isFinite(s)) return s;\n }\n return 500;\n}\n"]}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
export interface Entity {
|
|
2
|
+
id: string;
|
|
3
|
+
created_at: string;
|
|
4
|
+
updated_at: string;
|
|
5
|
+
}
|
|
6
|
+
export interface CursorPaginationOptions<T> {
|
|
7
|
+
filter?: (item: T) => boolean;
|
|
8
|
+
sort?: (a: T, b: T) => number;
|
|
9
|
+
limit?: number;
|
|
10
|
+
order?: 'asc' | 'desc';
|
|
11
|
+
before?: string;
|
|
12
|
+
after?: string;
|
|
13
|
+
}
|
|
14
|
+
export interface CursorPaginatedResult<T> {
|
|
15
|
+
data: T[];
|
|
16
|
+
list_metadata: {
|
|
17
|
+
before: string | null;
|
|
18
|
+
after: string | null;
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
export declare function cursorPaginate<T extends Entity>(items: T[], options?: CursorPaginationOptions<T>): CursorPaginatedResult<T>;
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
export function cursorPaginate(items, options = {}) {
|
|
2
|
+
let filtered = options.filter ? items.filter(options.filter) : [...items];
|
|
3
|
+
const order = options.order ?? 'desc';
|
|
4
|
+
const defaultSort = (a, b) => order === 'desc'
|
|
5
|
+
? b.created_at.localeCompare(a.created_at) || b.id.localeCompare(a.id)
|
|
6
|
+
: a.created_at.localeCompare(b.created_at) || a.id.localeCompare(b.id);
|
|
7
|
+
filtered.sort(options.sort ?? defaultSort);
|
|
8
|
+
const limit = Math.max(1, Math.min(options.limit ?? 10, 100));
|
|
9
|
+
let startIndex = 0;
|
|
10
|
+
let endIndex = filtered.length;
|
|
11
|
+
if (options.after) {
|
|
12
|
+
const afterIndex = filtered.findIndex((item) => item.id === options.after);
|
|
13
|
+
if (afterIndex !== -1) {
|
|
14
|
+
startIndex = afterIndex + 1;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
if (options.before) {
|
|
18
|
+
const beforeIndex = filtered.findIndex((item) => item.id === options.before);
|
|
19
|
+
if (beforeIndex !== -1) {
|
|
20
|
+
endIndex = beforeIndex;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
const window = filtered.slice(startIndex, endIndex);
|
|
24
|
+
const page = window.slice(0, limit);
|
|
25
|
+
const hasMore = window.length > limit;
|
|
26
|
+
const hasPrev = startIndex > 0;
|
|
27
|
+
return {
|
|
28
|
+
data: page,
|
|
29
|
+
list_metadata: {
|
|
30
|
+
before: page.length > 0 && hasPrev ? page[0].id : null,
|
|
31
|
+
after: page.length > 0 && hasMore ? page[page.length - 1].id : null,
|
|
32
|
+
},
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
//# sourceMappingURL=pagination.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pagination.js","sourceRoot":"","sources":["../../../src/emulate/core/pagination.ts"],"names":[],"mappings":"AAuBA,MAAM,UAAU,cAAc,CAC5B,KAAU,EACV,UAAsC,EAAE;IAExC,IAAI,QAAQ,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,MAAM,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,CAAC,GAAG,KAAK,CAAC,CAAC;IAE1E,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,IAAI,MAAM,CAAC;IACtC,MAAM,WAAW,GAAG,CAAC,CAAI,EAAE,CAAI,EAAE,EAAE,CACjC,KAAK,KAAK,MAAM;QACd,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC;QACtE,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC,aAAa,CAAC,CAAC,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC,EAAE,CAAC,aAAa,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;IAE3E,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,WAAW,CAAC,CAAC;IAE3C,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,CAAC,EAAE,IAAI,CAAC,GAAG,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,EAAE,GAAG,CAAC,CAAC,CAAC;IAE9D,IAAI,UAAU,GAAG,CAAC,CAAC;IACnB,IAAI,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC;IAE/B,IAAI,OAAO,CAAC,KAAK,EAAE,CAAC;QAClB,MAAM,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,KAAK,CAAC,CAAC;QAC3E,IAAI,UAAU,KAAK,CAAC,CAAC,EAAE,CAAC;YACtB,UAAU,GAAG,UAAU,GAAG,CAAC,CAAC;QAC9B,CAAC;IACH,CAAC;IAED,IAAI,OAAO,CAAC,MAAM,EAAE,CAAC;QACnB,MAAM,WAAW,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,OAAO,CAAC,MAAM,CAAC,CAAC;QAC7E,IAAI,WAAW,KAAK,CAAC,CAAC,EAAE,CAAC;YACvB,QAAQ,GAAG,WAAW,CAAC;QACzB,CAAC;IACH,CAAC;IAED,MAAM,MAAM,GAAG,QAAQ,CAAC,KAAK,CAAC,UAAU,EAAE,QAAQ,CAAC,CAAC;IACpD,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;IAEpC,MAAM,OAAO,GAAG,MAAM,CAAC,MAAM,GAAG,KAAK,CAAC;IACtC,MAAM,OAAO,GAAG,UAAU,GAAG,CAAC,CAAC;IAE/B,OAAO;QACL,IAAI,EAAE,IAAI;QACV,aAAa,EAAE;YACb,MAAM,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;YACtD,KAAK,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC,IAAI,OAAO,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI;SACpE;KACF,CAAC;AACJ,CAAC","sourcesContent":["export interface Entity {\n id: string;\n created_at: string;\n updated_at: string;\n}\n\nexport interface CursorPaginationOptions<T> {\n filter?: (item: T) => boolean;\n sort?: (a: T, b: T) => number;\n limit?: number;\n order?: 'asc' | 'desc';\n before?: string;\n after?: string;\n}\n\nexport interface CursorPaginatedResult<T> {\n data: T[];\n list_metadata: {\n before: string | null;\n after: string | null;\n };\n}\n\nexport function cursorPaginate<T extends Entity>(\n items: T[],\n options: CursorPaginationOptions<T> = {},\n): CursorPaginatedResult<T> {\n let filtered = options.filter ? items.filter(options.filter) : [...items];\n\n const order = options.order ?? 'desc';\n const defaultSort = (a: T, b: T) =>\n order === 'desc'\n ? b.created_at.localeCompare(a.created_at) || b.id.localeCompare(a.id)\n : a.created_at.localeCompare(b.created_at) || a.id.localeCompare(b.id);\n\n filtered.sort(options.sort ?? defaultSort);\n\n const limit = Math.max(1, Math.min(options.limit ?? 10, 100));\n\n let startIndex = 0;\n let endIndex = filtered.length;\n\n if (options.after) {\n const afterIndex = filtered.findIndex((item) => item.id === options.after);\n if (afterIndex !== -1) {\n startIndex = afterIndex + 1;\n }\n }\n\n if (options.before) {\n const beforeIndex = filtered.findIndex((item) => item.id === options.before);\n if (beforeIndex !== -1) {\n endIndex = beforeIndex;\n }\n }\n\n const window = filtered.slice(startIndex, endIndex);\n const page = window.slice(0, limit);\n\n const hasMore = window.length > limit;\n const hasPrev = startIndex > 0;\n\n return {\n data: page,\n list_metadata: {\n before: page.length > 0 && hasPrev ? page[0].id : null,\n after: page.length > 0 && hasMore ? page[page.length - 1].id : null,\n },\n };\n}\n"]}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import type { Hono } from 'hono';
|
|
2
|
+
import type { Store } from './store.js';
|
|
3
|
+
import type { JWTManager } from './jwt.js';
|
|
4
|
+
import type { WorkOSAppEnv } from './middleware/auth.js';
|
|
5
|
+
export interface RouteContext {
|
|
6
|
+
app: Hono<WorkOSAppEnv>;
|
|
7
|
+
store: Store;
|
|
8
|
+
jwt: JWTManager;
|
|
9
|
+
baseUrl: string;
|
|
10
|
+
}
|
|
11
|
+
export interface ServicePlugin {
|
|
12
|
+
name: string;
|
|
13
|
+
register(ctx: RouteContext): void;
|
|
14
|
+
seed?(store: Store, baseUrl: string): void;
|
|
15
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"plugin.js","sourceRoot":"","sources":["../../../src/emulate/core/plugin.ts"],"names":[],"mappings":"","sourcesContent":["import type { Hono } from 'hono';\nimport type { Store } from './store.js';\nimport type { JWTManager } from './jwt.js';\nimport type { WorkOSAppEnv } from './middleware/auth.js';\n\nexport interface RouteContext {\n app: Hono<WorkOSAppEnv>;\n store: Store;\n jwt: JWTManager;\n baseUrl: string;\n}\n\nexport interface ServicePlugin {\n name: string;\n register(ctx: RouteContext): void;\n seed?(store: Store, baseUrl: string): void;\n}\n"]}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { Hono } from 'hono';
|
|
2
|
+
import { Store } from './store.js';
|
|
3
|
+
import { JWTManager } from './jwt.js';
|
|
4
|
+
import { type ApiKeyMap, type WorkOSAppEnv } from './middleware/auth.js';
|
|
5
|
+
import type { ServicePlugin } from './plugin.js';
|
|
6
|
+
export interface ServerOptions {
|
|
7
|
+
port?: number;
|
|
8
|
+
baseUrl?: string;
|
|
9
|
+
apiKeys?: ApiKeyMap;
|
|
10
|
+
}
|
|
11
|
+
export declare function createServer(plugin: ServicePlugin, options?: ServerOptions): {
|
|
12
|
+
app: Hono<WorkOSAppEnv, import("hono/types").BlankSchema, "/">;
|
|
13
|
+
store: Store;
|
|
14
|
+
jwt: JWTManager;
|
|
15
|
+
port: number;
|
|
16
|
+
baseUrl: string;
|
|
17
|
+
};
|