@payloadcms/figma 0.0.1-alpha.34 → 0.0.1-alpha.36

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.
Files changed (106) hide show
  1. package/dist/auth/oauth-flow.d.ts.map +1 -1
  2. package/dist/auth/oauth-flow.js +6 -5
  3. package/dist/auth/oauth-flow.js.map +1 -1
  4. package/dist/auth/refresh.d.ts.map +1 -1
  5. package/dist/auth/refresh.js +14 -9
  6. package/dist/auth/refresh.js.map +1 -1
  7. package/dist/cli.d.ts.map +1 -1
  8. package/dist/cli.js +19 -0
  9. package/dist/cli.js.map +1 -1
  10. package/dist/commands/build-lambda-zip.d.ts +5 -0
  11. package/dist/commands/build-lambda-zip.d.ts.map +1 -0
  12. package/dist/commands/build-lambda-zip.js +19 -0
  13. package/dist/commands/build-lambda-zip.js.map +1 -0
  14. package/dist/commands/deploy.js +3 -3
  15. package/dist/commands/deploy.js.map +1 -1
  16. package/dist/commands/init.js +2 -2
  17. package/dist/commands/init.js.map +1 -1
  18. package/dist/commands/list-tokens.d.ts.map +1 -1
  19. package/dist/commands/list-tokens.js +3 -1
  20. package/dist/commands/list-tokens.js.map +1 -1
  21. package/dist/commands/login.d.ts.map +1 -1
  22. package/dist/commands/login.js +8 -5
  23. package/dist/commands/login.js.map +1 -1
  24. package/dist/config/oauth.d.ts +3 -17
  25. package/dist/config/oauth.d.ts.map +1 -1
  26. package/dist/config/oauth.js +18 -34
  27. package/dist/config/oauth.js.map +1 -1
  28. package/dist/constants.d.ts +23 -12
  29. package/dist/constants.d.ts.map +1 -1
  30. package/dist/constants.js +31 -12
  31. package/dist/constants.js.map +1 -1
  32. package/dist/db-content-api/README.md +0 -10
  33. package/dist/db-content-api/generated/content-api-types.d.ts +171 -25
  34. package/dist/db-content-api/generated/content-api-types.d.ts.map +1 -1
  35. package/dist/db-content-api/generated/content-api-types.js.map +1 -1
  36. package/dist/db-content-api/index.d.ts.map +1 -1
  37. package/dist/db-content-api/index.js +7 -8
  38. package/dist/db-content-api/index.js.map +1 -1
  39. package/dist/db-content-api/temp-utilities/sorting.d.ts +2 -6
  40. package/dist/db-content-api/temp-utilities/sorting.d.ts.map +1 -1
  41. package/dist/db-content-api/temp-utilities/sorting.js +2 -41
  42. package/dist/db-content-api/temp-utilities/sorting.js.map +1 -1
  43. package/dist/db-content-api/utilities/data/index.d.ts +2 -0
  44. package/dist/db-content-api/utilities/data/index.d.ts.map +1 -1
  45. package/dist/db-content-api/utilities/data/index.js +7 -0
  46. package/dist/db-content-api/utilities/data/index.js.map +1 -1
  47. package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +12 -0
  48. package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts.map +1 -0
  49. package/dist/db-content-api/utilities/data/removeVirtualFields.js +54 -0
  50. package/dist/db-content-api/utilities/data/removeVirtualFields.js.map +1 -0
  51. package/dist/db-content-api/utilities/joins.d.ts +4 -4
  52. package/dist/db-content-api/utilities/joins.d.ts.map +1 -1
  53. package/dist/db-content-api/utilities/joins.js +12 -6
  54. package/dist/db-content-api/utilities/joins.js.map +1 -1
  55. package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +1 -1
  56. package/dist/oauth/endpoints/getLoginEndpoint.js +0 -3
  57. package/dist/oauth/endpoints/getLoginEndpoint.js.map +1 -1
  58. package/dist/oauth/index.d.ts.map +1 -1
  59. package/dist/oauth/index.js +0 -1
  60. package/dist/oauth/index.js.map +1 -1
  61. package/dist/oauth/strategy/index.d.ts +0 -2
  62. package/dist/oauth/strategy/index.d.ts.map +1 -1
  63. package/dist/oauth/strategy/index.js +33 -14
  64. package/dist/oauth/strategy/index.js.map +1 -1
  65. package/dist/plugin/build-config.d.ts.map +1 -1
  66. package/dist/plugin/build-config.js +12 -5
  67. package/dist/plugin/build-config.js.map +1 -1
  68. package/dist/types.d.ts +1 -0
  69. package/dist/types.d.ts.map +1 -1
  70. package/dist/types.js.map +1 -1
  71. package/dist/utils/asset-collection.d.ts +3 -6
  72. package/dist/utils/asset-collection.d.ts.map +1 -1
  73. package/dist/utils/asset-collection.js +10 -34
  74. package/dist/utils/asset-collection.js.map +1 -1
  75. package/dist/utils/build-lambda-zip.d.ts +14 -0
  76. package/dist/utils/build-lambda-zip.d.ts.map +1 -0
  77. package/dist/utils/build-lambda-zip.js +81 -0
  78. package/dist/utils/build-lambda-zip.js.map +1 -0
  79. package/dist/utils/config.js +1 -1
  80. package/dist/utils/config.js.map +1 -1
  81. package/dist/utils/env-management.js +2 -2
  82. package/dist/utils/env-management.js.map +1 -1
  83. package/dist/utils/formatter.d.ts.map +1 -1
  84. package/dist/utils/formatter.js +7 -3
  85. package/dist/utils/formatter.js.map +1 -1
  86. package/dist/utils/lambda-config.d.ts +3 -1
  87. package/dist/utils/lambda-config.d.ts.map +1 -1
  88. package/dist/utils/lambda-config.js +13 -22
  89. package/dist/utils/lambda-config.js.map +1 -1
  90. package/dist/utils/messages.d.ts.map +1 -1
  91. package/dist/utils/messages.js +2 -0
  92. package/dist/utils/messages.js.map +1 -1
  93. package/dist/utils/payload-config-modifier.d.ts.map +1 -1
  94. package/dist/utils/payload-config-modifier.js +7 -4
  95. package/dist/utils/payload-config-modifier.js.map +1 -1
  96. package/dist/utils/payload-package-check.d.ts +7 -1
  97. package/dist/utils/payload-package-check.d.ts.map +1 -1
  98. package/dist/utils/payload-package-check.js +29 -15
  99. package/dist/utils/payload-package-check.js.map +1 -1
  100. package/dist/utils/project.d.ts.map +1 -1
  101. package/dist/utils/project.js +4 -3
  102. package/dist/utils/project.js.map +1 -1
  103. package/dist/utils/typescript-validator.d.ts.map +1 -1
  104. package/dist/utils/typescript-validator.js +7 -4
  105. package/dist/utils/typescript-validator.js.map +1 -1
  106. package/package.json +6 -2
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport fs from 'fs/promises'\nimport path from 'path'\nimport pc from 'picocolors'\n\nimport type { TokenStore } from '../auth/token-store.js'\n\nimport { getDatasetInfo } from '../api/control-plane.js'\nimport { FigmaApiError } from '../api/figma-api.js'\nimport { getValidAccessToken } from '../auth/oauth-flow.js'\nimport { getValidProjectToken, ProjectTokenError } from '../auth/project-token.js'\nimport { getTokenStore } from '../auth/token-store.js'\nimport { ensureGitignore } from '../utils/config.js'\nimport { addOrUpdateEnvVar } from '../utils/env-management.js'\nimport { isDebug } from '../utils/is-debug.js'\nimport { applyLambdaModifications } from '../utils/lambda-config.js'\nimport * as log from '../utils/log.js'\nimport {\n displayManualInstructions,\n ensurePayloadFigmaConfig,\n} from '../utils/payload-config-modifier.js'\nimport { runScript } from '../utils/payload-package-check.js'\nimport {\n detectPayloadProject,\n hasRequiredDependencies,\n initializeGitRepo,\n installDependencies,\n isInProjectDirectory,\n scaffoldProject,\n validatePayloadVersion,\n} from '../utils/project.js'\nimport { loginCommand } from './login.js'\n\n/**\n * Options for init command\n */\nexport interface InitCommandOptions {\n /** Enable debug mode */\n debug?: boolean\n /** Force reconfiguration of existing project */\n force?: boolean\n /** Content System ID to use */\n id?: string\n /** Project name (for scaffolding) */\n name?: string\n /** Skip authentication check (for testing/development) */\n skipAuth?: boolean\n /** Skip prompts and use defaults where possible */\n yes?: boolean\n}\n\n/**\n * Generate and store project token for a content system\n * Non-blocking - will show warning but not exit on failure\n * Only shows feedback if DEBUG mode is enabled, otherwise runs silently\n *\n * @param tokenStore - Token store instance\n * @param contentSystemId - Content System ID to generate token for\n * @param spinner - Clack spinner instance for status updates (only used in debug mode)\n */\nasync function generateProjectTokenWithFeedback(\n tokenStore: TokenStore,\n contentSystemId: string,\n spinner: ReturnType<typeof p.spinner>,\n): Promise<void> {\n if (isDebug()) {\n spinner.start('Generating project token...')\n }\n\n try {\n const projectToken = await getValidProjectToken(tokenStore, contentSystemId)\n if (isDebug()) {\n if (projectToken) {\n spinner.stop(pc.green('✓ Project token generated'))\n } else {\n spinner.stop(pc.yellow('⚠ Project token not generated (authentication required)'))\n }\n }\n } catch (error) {\n if (isDebug()) {\n spinner.stop(pc.yellow('⚠ Project token generation failed'))\n }\n // Always show failures, even without debug\n if (error instanceof ProjectTokenError || error instanceof FigmaApiError) {\n log.warning(error.message)\n p.note(\n 'Project token is used for authenticating to the Content API.\\nYou can continue without it, but may need to regenerate later.',\n 'Note',\n )\n } else {\n log.warning(\n `Unable to retrieve project token: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n // Don't exit - token generation failure shouldn't block initialization\n }\n}\n\n/**\n * Fetch dataset info from the API\n * Throws on error - caller must handle\n */\nasync function fetchDatasetInfo(\n accessToken: string,\n datasetId: string,\n): Promise<{ oauthClientId: string; oauthClientSecret: string; tenantId: string }> {\n log.debug('Fetching dataset info...')\n\n const datasetInfo = await getDatasetInfo(accessToken, datasetId)\n log.debug('Dataset info retrieved successfully')\n return {\n oauthClientId: datasetInfo.oauthClientId,\n oauthClientSecret: datasetInfo.oauthClientSecret,\n tenantId: datasetInfo.tenantId,\n }\n}\n\n/**\n * Handle the `init` command\n *\n * Sets up a project by:\n * 1. Checking authentication\n * 2. Detecting/scaffolding Payload project\n * 3. Fetching tenant details\n * 4. Storing configuration\n *\n * @param options - Command options\n */\nexport async function initCommand(options: InitCommandOptions): Promise<void> {\n // Check authentication\n const tokenStore = getTokenStore()\n const s = p.spinner()\n\n if (options.skipAuth) {\n // Skip authentication for testing/development\n p.log.warn(pc.yellow('Skipping authentication (--skip-auth mode)'))\n } else {\n try {\n // Check for valid cached tokens first (no API call needed)\n if (!tokenStore.hasValidTokens()) {\n // Need to refresh or authenticate - show spinner for API call\n s.start('Checking authentication...')\n const token = await getValidAccessToken(tokenStore)\n if (!token) {\n s.stop('Authentication required to continue')\n\n // Run login command\n await loginCommand({ showNextSteps: false })\n\n // Get token after auth\n const newToken = await getValidAccessToken(tokenStore)\n if (!newToken) {\n p.log.error('Authentication failed')\n process.exit(1)\n }\n } else {\n s.stop(pc.green('✓ Authenticated'))\n }\n }\n } catch (error) {\n s.stop(pc.red('✗ Authentication failed'))\n log.error(error instanceof Error ? error.message : 'Unknown error')\n p.note('Run `figma auth` to authenticate', 'Tip')\n process.exit(1)\n }\n }\n\n // Note: We no longer check for figma.config.json here\n // Instead, the AST detection will check if figma object already exists in payload.config.ts\n // and skip modification if it does (unless --force is used)\n\n // Step 3: Get Content System ID (required argument)\n log.debug('Configuring Project...')\n\n if (!options.id) {\n p.log.error('Content System ID is required. Use --id <content_system_id>')\n process.exit(1)\n }\n\n const contentSystemId = options.id\n\n // Fetch dataset info (required - will fail if feature not enabled)\n let datasetInfo: { oauthClientId: string; oauthClientSecret: string; tenantId: string } | null =\n null\n if (!options.skipAuth) {\n const accessToken = await getValidAccessToken(tokenStore)\n if (accessToken) {\n try {\n datasetInfo = await fetchDatasetInfo(accessToken, contentSystemId)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n p.log.error(\n pc.red(`✗ Unable to fetch dataset info for content system \"${contentSystemId}\"`),\n )\n p.log.error(pc.dim(`Details: ${message}`))\n p.note(\n 'This may indicate the CMS feature is not enabled for your account.\\n' +\n 'Contact support if you believe this is an error.',\n 'Error',\n )\n process.exit(1)\n }\n }\n }\n\n // Step 4: Detect or scaffold Payload project\n const isInProject = await isInProjectDirectory()\n\n if (isInProject) {\n // ===== EXISTING PROJECT FLOW =====\n log.debug('Project directory detected')\n\n // Detect Payload\n const projectInfo = await detectPayloadProject()\n\n if (projectInfo.hasPayload) {\n // Validate existing Payload version\n if (projectInfo.payloadVersion && !validatePayloadVersion(projectInfo.payloadVersion)) {\n p.log.warn(\n pc.yellow(\n `Payload version ${projectInfo.payloadVersion} detected. Version 3.x is required.`,\n ),\n )\n p.note('Upgrade to Payload 3.x before continuing', 'Action Required')\n process.exit(1)\n }\n\n p.log.success(pc.green(`✓ Payload ${projectInfo.payloadVersion || 'detected'}`))\n\n // Check dependencies\n s.start('Checking dependencies...')\n const hasDeps = await hasRequiredDependencies(process.cwd())\n s.stop(pc.green('✓ Dependencies checked'))\n\n if (!hasDeps) {\n const shouldInstall = await p.confirm({\n initialValue: true,\n message: 'Install dependencies now?',\n })\n\n if (!p.isCancel(shouldInstall) && shouldInstall) {\n s.start('Installing dependencies...')\n await installDependencies(process.cwd(), projectInfo.packageManager || 'pnpm')\n s.stop(pc.green('✓ Dependencies installed'))\n }\n }\n\n s.start('Checking Payload configuration...')\n const modResult = await ensurePayloadFigmaConfig(\n process.cwd(),\n projectInfo.packageManager || 'pnpm',\n {\n contentSystemId,\n },\n )\n\n if (!modResult.success) {\n s.stop(pc.red('✗ Configuration check failed'))\n displayManualInstructions(modResult.error || 'Unknown error')\n process.exit(1)\n }\n\n if (modResult.modified) {\n s.stop(pc.green('✓ Payload configuration updated'))\n if (modResult.changes.length > 0) {\n modResult.changes.forEach((change) => log.debug(pc.dim(` → ${change}`)))\n }\n } else {\n s.stop(pc.green('✓ Payload configuration valid'))\n }\n\n // Display warnings if any\n if (modResult.warnings && modResult.warnings.length > 0) {\n modResult.warnings.forEach((warning) => {\n p.log.warn(pc.yellow(`⚠ ${warning}`))\n })\n }\n\n // Write environment variables to .env file\n try {\n await addOrUpdateEnvVar(process.cwd(), 'FIGMA_CONTENT_SYSTEM_ID', contentSystemId)\n log.debug(`Added FIGMA_CONTENT_SYSTEM_ID to .env file`)\n\n if (datasetInfo) {\n await addOrUpdateEnvVar(process.cwd(), 'FIGMA_TENANT_ID', datasetInfo.tenantId)\n await addOrUpdateEnvVar(process.cwd(), 'FIGMA_OAUTH_CLIENT_ID', datasetInfo.oauthClientId)\n await addOrUpdateEnvVar(\n process.cwd(),\n 'FIGMA_OAUTH_CLIENT_SECRET',\n datasetInfo.oauthClientSecret,\n )\n log.debug(\n `Added FIGMA_TENANT_ID, FIGMA_OAUTH_CLIENT_ID, FIGMA_OAUTH_CLIENT_SECRET to .env file`,\n )\n }\n } catch (error) {\n p.log.warn(\n pc.yellow(\n `⚠ Failed to update .env file: ${error instanceof Error ? error.message : 'Unknown error'}`,\n ),\n )\n }\n } else {\n // Has package.json but no Payload - offer to add Payload\n p.log.warn(pc.yellow('⚠ No Payload detected in this project'))\n\n const shouldAddPayload = await p.confirm({\n initialValue: true,\n message: 'Would you like to add Payload to this project?',\n })\n\n if (p.isCancel(shouldAddPayload)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n if (!shouldAddPayload) {\n p.log.error('Payload is required to use Figma CMS')\n process.exit(1)\n }\n\n // TODO: Add Payload to existing project (future enhancement)\n p.log.error('Adding Payload to existing projects is not yet supported')\n p.note('Create a new project or manually add Payload dependencies', 'Action Required')\n process.exit(1)\n }\n\n // Generate import map to prevent errors on first pnpm dev\n await runScript(process.cwd(), 'generate:importmap', projectInfo.packageManager || 'pnpm')\n\n // Apply Lambda modifications (run.sh, build_for_lambda.sh, standalone output, etc.)\n await applyLambdaModifications(process.cwd())\n\n // Ensure .gitignore has required entries\n await ensureGitignore(process.cwd(), ['.env', '.env.local', 'lambda.zip'])\n\n // Generate project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, contentSystemId, s)\n }\n\n // Success message for existing project\n p.outro(pc.green('✓ Project initialized successfully!'))\n\n const nextSteps = ['Start development server: `pnpm dev`'].filter(Boolean)\n\n p.note(nextSteps.join('\\n'), 'Next Steps')\n } else {\n // ===== NEW PROJECT FLOW =====\n // p.log.info('No project detected - Creating New Project')\n\n // Prompt for path\n const projectPathInput = await p.text({\n initialValue: './',\n message: 'Enter path to create project:',\n placeholder: './my-cms-project',\n validate: (value) => {\n if (!value) {\n return 'Path is required'\n }\n // Allow relative or absolute paths\n return undefined\n },\n })\n\n if (p.isCancel(projectPathInput)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n const projectPath = projectPathInput\n const fullPath = path.resolve(process.cwd(), projectPath)\n\n // Get project name from path or prompt\n const projectName = options.name || path.basename(fullPath)\n\n // Create directory\n try {\n await fs.mkdir(fullPath, { recursive: true })\n } catch (error) {\n p.log.error(\n `Failed to create directory: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n process.exit(1)\n }\n\n // Scaffold project\n s.start('Downloading template from GitHub...')\n try {\n await scaffoldProject(fullPath, projectName)\n s.stop(pc.green('✓ Template downloaded'))\n\n s.start('Installing dependencies...')\n await installDependencies(fullPath, 'pnpm')\n s.stop(pc.green('✓ Dependencies installed'))\n } catch (error) {\n s.stop(pc.red('✗ Failed'))\n log.error(error instanceof Error ? error.message : 'Unknown error')\n process.exit(1)\n }\n\n // Modify Payload configuration\n s.start('Checking Payload configuration...')\n const modResult = await ensurePayloadFigmaConfig(fullPath, 'pnpm', {\n contentSystemId,\n })\n\n if (!modResult.success) {\n s.stop(pc.red('✗ Configuration check failed'))\n displayManualInstructions(modResult.error || 'Unknown error')\n process.exit(1)\n }\n\n if (modResult.modified) {\n s.stop(pc.green('✓ Payload configuration updated'))\n if (modResult.changes.length > 0) {\n modResult.changes.forEach((change) => log.debug(pc.dim(` → ${change}`)))\n }\n } else {\n s.stop(pc.green('✓ Payload configuration valid'))\n }\n\n // Display warnings if any\n if (modResult.warnings && modResult.warnings.length > 0) {\n modResult.warnings.forEach((warning) => {\n p.log.warn(pc.yellow(`⚠ ${warning}`))\n })\n }\n\n // Write environment variables to .env file\n try {\n await addOrUpdateEnvVar(fullPath, 'FIGMA_CONTENT_SYSTEM_ID', contentSystemId)\n log.debug(`Added FIGMA_CONTENT_SYSTEM_ID to .env file`)\n\n if (datasetInfo) {\n await addOrUpdateEnvVar(fullPath, 'FIGMA_TENANT_ID', datasetInfo.tenantId)\n await addOrUpdateEnvVar(fullPath, 'FIGMA_OAUTH_CLIENT_ID', datasetInfo.oauthClientId)\n await addOrUpdateEnvVar(\n fullPath,\n 'FIGMA_OAUTH_CLIENT_SECRET',\n datasetInfo.oauthClientSecret,\n )\n log.debug(\n `Added FIGMA_TENANT_ID, FIGMA_OAUTH_CLIENT_ID, FIGMA_OAUTH_CLIENT_SECRET to .env file`,\n )\n }\n } catch (error) {\n p.log.warn(\n pc.yellow(\n `⚠ Failed to update .env file: ${error instanceof Error ? error.message : 'Unknown error'}`,\n ),\n )\n }\n\n // Generate import map to prevent errors on first pnpm dev\n await runScript(fullPath, 'generate:importmap', 'pnpm')\n\n // Generate project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, contentSystemId, s)\n }\n\n // Initialize git repository (after all files including lock file are ready)\n initializeGitRepo(fullPath)\n\n // Success message for NEW project\n p.log.step(pc.bgGreen(pc.black(' Project created successfully! ')))\n\n const relativePath = path.relative(process.cwd(), fullPath)\n const nextSteps: string[] = []\n\n // Only show cd command if user needs to navigate\n if (relativePath && relativePath !== '.') {\n nextSteps.push(`cd ${relativePath}`)\n }\n\n nextSteps.push(\n 'pnpm dev or follow directions in README.md',\n '',\n 'Documentation:',\n '- Getting Started: https://payloadcms.com/docs/getting-started/what-is-payload',\n '- Configuration: https://payloadcms.com/docs/configuration/overview',\n )\n\n p.note(nextSteps.join('\\n'), 'Next Steps')\n p.outro(pc.green('✓ Done'))\n }\n}\n"],"names":["p","fs","path","pc","getDatasetInfo","FigmaApiError","getValidAccessToken","getValidProjectToken","ProjectTokenError","getTokenStore","ensureGitignore","addOrUpdateEnvVar","isDebug","applyLambdaModifications","log","displayManualInstructions","ensurePayloadFigmaConfig","runScript","detectPayloadProject","hasRequiredDependencies","initializeGitRepo","installDependencies","isInProjectDirectory","scaffoldProject","validatePayloadVersion","loginCommand","generateProjectTokenWithFeedback","tokenStore","contentSystemId","spinner","start","projectToken","stop","green","yellow","error","warning","message","note","Error","fetchDatasetInfo","accessToken","datasetId","debug","datasetInfo","oauthClientId","oauthClientSecret","tenantId","initCommand","options","s","skipAuth","warn","hasValidTokens","token","showNextSteps","newToken","process","exit","red","id","dim","isInProject","projectInfo","hasPayload","payloadVersion","success","hasDeps","cwd","shouldInstall","confirm","initialValue","isCancel","packageManager","modResult","modified","changes","length","forEach","change","warnings","shouldAddPayload","cancel","outro","nextSteps","filter","Boolean","join","projectPathInput","text","placeholder","validate","value","undefined","projectPath","fullPath","resolve","projectName","name","basename","mkdir","recursive","step","bgGreen","black","relativePath","relative","push"],"mappings":"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"}
1
+ {"version":3,"sources":["../../src/commands/init.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport fs from 'fs/promises'\nimport path from 'path'\nimport pc from 'picocolors'\n\nimport type { TokenStore } from '../auth/token-store.js'\n\nimport { getDatasetInfo } from '../api/control-plane.js'\nimport { FigmaApiError } from '../api/figma-api.js'\nimport { getValidAccessToken } from '../auth/oauth-flow.js'\nimport { getValidProjectToken, ProjectTokenError } from '../auth/project-token.js'\nimport { getTokenStore } from '../auth/token-store.js'\nimport { ensureGitignore } from '../utils/config.js'\nimport { addOrUpdateEnvVar } from '../utils/env-management.js'\nimport { isDebug } from '../utils/is-debug.js'\nimport { applyLambdaModifications } from '../utils/lambda-config.js'\nimport * as log from '../utils/log.js'\nimport {\n displayManualInstructions,\n ensurePayloadFigmaConfig,\n} from '../utils/payload-config-modifier.js'\nimport { runScript } from '../utils/payload-package-check.js'\nimport {\n detectPayloadProject,\n hasRequiredDependencies,\n initializeGitRepo,\n installDependencies,\n isInProjectDirectory,\n scaffoldProject,\n validatePayloadVersion,\n} from '../utils/project.js'\nimport { loginCommand } from './login.js'\n\n/**\n * Options for init command\n */\nexport interface InitCommandOptions {\n /** Enable debug mode */\n debug?: boolean\n /** Force reconfiguration of existing project */\n force?: boolean\n /** Content System ID to use */\n id?: string\n /** Project name (for scaffolding) */\n name?: string\n /** Skip authentication check (for testing/development) */\n skipAuth?: boolean\n /** Skip prompts and use defaults where possible */\n yes?: boolean\n}\n\n/**\n * Generate and store project token for a content system\n * Non-blocking - will show warning but not exit on failure\n * Only shows feedback if DEBUG mode is enabled, otherwise runs silently\n *\n * @param tokenStore - Token store instance\n * @param contentSystemId - Content System ID to generate token for\n * @param spinner - Clack spinner instance for status updates (only used in debug mode)\n */\nasync function generateProjectTokenWithFeedback(\n tokenStore: TokenStore,\n contentSystemId: string,\n spinner: ReturnType<typeof p.spinner>,\n): Promise<void> {\n if (isDebug()) {\n spinner.start('Generating project token...')\n }\n\n try {\n const projectToken = await getValidProjectToken(tokenStore, contentSystemId)\n if (isDebug()) {\n if (projectToken) {\n spinner.stop(pc.green('✓ Project token generated'))\n } else {\n spinner.stop(pc.yellow('⚠ Project token not generated (authentication required)'))\n }\n }\n } catch (error) {\n if (isDebug()) {\n spinner.stop(pc.yellow('⚠ Project token generation failed'))\n }\n // Always show failures, even without debug\n if (error instanceof ProjectTokenError || error instanceof FigmaApiError) {\n log.warning(error.message)\n p.note(\n 'Project token is used for authenticating to the Content API.\\nYou can continue without it, but may need to regenerate later.',\n 'Note',\n )\n } else {\n log.warning(\n `Unable to retrieve project token: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n // Don't exit - token generation failure shouldn't block initialization\n }\n}\n\n/**\n * Fetch dataset info from the API\n * Throws on error - caller must handle\n */\nasync function fetchDatasetInfo(\n accessToken: string,\n datasetId: string,\n): Promise<{ oauthClientId: string; oauthClientSecret: string; tenantId: string }> {\n log.debug('Fetching dataset info...')\n\n const datasetInfo = await getDatasetInfo(accessToken, datasetId)\n log.debug('Dataset info retrieved successfully')\n return {\n oauthClientId: datasetInfo.oauthClientId,\n oauthClientSecret: datasetInfo.oauthClientSecret,\n tenantId: datasetInfo.tenantId,\n }\n}\n\n/**\n * Handle the `init` command\n *\n * Sets up a project by:\n * 1. Checking authentication\n * 2. Detecting/scaffolding Payload project\n * 3. Fetching tenant details\n * 4. Storing configuration\n *\n * @param options - Command options\n */\nexport async function initCommand(options: InitCommandOptions): Promise<void> {\n // Check authentication\n const tokenStore = getTokenStore()\n const s = p.spinner()\n\n if (options.skipAuth) {\n // Skip authentication for testing/development\n p.log.warn(pc.yellow('Skipping authentication (--skip-auth mode)'))\n } else {\n try {\n // Check for valid cached tokens first (no API call needed)\n if (!tokenStore.hasValidTokens()) {\n // Need to refresh or authenticate - show spinner for API call\n s.start('Checking authentication...')\n const token = await getValidAccessToken(tokenStore)\n if (!token) {\n s.stop('Authentication required to continue')\n\n // Run login command\n await loginCommand({ showNextSteps: false })\n\n // Get token after auth\n const newToken = await getValidAccessToken(tokenStore)\n if (!newToken) {\n p.log.error('Authentication failed')\n process.exit(1)\n }\n } else {\n s.stop(pc.green('✓ Authenticated'))\n }\n }\n } catch (error) {\n s.stop(pc.red('✗ Authentication failed'))\n log.error(error instanceof Error ? error.message : 'Unknown error')\n p.note('Run `figma auth` to authenticate', 'Tip')\n process.exit(1)\n }\n }\n\n // Note: We no longer check for figma.config.json here\n // Instead, the AST detection will check if figma object already exists in payload.config.ts\n // and skip modification if it does (unless --force is used)\n\n // Step 3: Get Content System ID (required argument)\n log.debug('Configuring Project...')\n\n if (!options.id) {\n p.log.error('Content System ID is required. Use --id <content_system_id>')\n process.exit(1)\n }\n\n const contentSystemId = options.id\n\n // Fetch dataset info (required - will fail if feature not enabled)\n let datasetInfo: { oauthClientId: string; oauthClientSecret: string; tenantId: string } | null =\n null\n if (!options.skipAuth) {\n const accessToken = await getValidAccessToken(tokenStore)\n if (accessToken) {\n try {\n datasetInfo = await fetchDatasetInfo(accessToken, contentSystemId)\n } catch (error) {\n const message = error instanceof Error ? error.message : 'Unknown error'\n p.log.error(\n pc.red(`✗ Unable to fetch dataset info for content system \"${contentSystemId}\"`),\n )\n p.log.error(pc.dim(`Details: ${message}`))\n p.note(\n 'This may indicate the CMS feature is not enabled for your account.\\n' +\n 'Contact support if you believe this is an error.',\n 'Error',\n )\n process.exit(1)\n }\n }\n }\n\n // Step 4: Detect or scaffold Payload project\n const isInProject = await isInProjectDirectory()\n\n if (isInProject) {\n // ===== EXISTING PROJECT FLOW =====\n log.debug('Project directory detected')\n\n // Detect Payload\n const projectInfo = await detectPayloadProject()\n\n if (projectInfo.hasPayload) {\n // Validate existing Payload version\n if (projectInfo.payloadVersion && !validatePayloadVersion(projectInfo.payloadVersion)) {\n p.log.warn(\n pc.yellow(\n `Payload version ${projectInfo.payloadVersion} detected. Version 3.x is required.`,\n ),\n )\n p.note('Upgrade to Payload 3.x before continuing', 'Action Required')\n process.exit(1)\n }\n\n p.log.success(pc.green(`✓ Payload ${projectInfo.payloadVersion || 'detected'}`))\n\n // Check dependencies\n s.start('Checking dependencies...')\n const hasDeps = await hasRequiredDependencies(process.cwd())\n s.stop(pc.green('✓ Dependencies checked'))\n\n if (!hasDeps) {\n const shouldInstall = await p.confirm({\n initialValue: true,\n message: 'Install dependencies now?',\n })\n\n if (!p.isCancel(shouldInstall) && shouldInstall) {\n s.start('Installing dependencies...')\n await installDependencies(process.cwd(), projectInfo.packageManager || 'pnpm')\n s.stop(pc.green('✓ Dependencies installed'))\n }\n }\n\n s.start('Checking Payload configuration...')\n const modResult = await ensurePayloadFigmaConfig(\n process.cwd(),\n projectInfo.packageManager || 'pnpm',\n {\n contentSystemId,\n },\n )\n\n if (!modResult.success) {\n s.stop(pc.red('✗ Configuration check failed'))\n displayManualInstructions(modResult.error || 'Unknown error')\n process.exit(1)\n }\n\n if (modResult.modified) {\n s.stop(pc.green('✓ Payload configuration updated'))\n if (modResult.changes.length > 0) {\n modResult.changes.forEach((change) => log.debug(pc.dim(` → ${change}`)))\n }\n } else {\n s.stop(pc.green('✓ Payload configuration valid'))\n }\n\n // Display warnings if any\n if (modResult.warnings && modResult.warnings.length > 0) {\n modResult.warnings.forEach((warning) => {\n p.log.warn(pc.yellow(`⚠ ${warning}`))\n })\n }\n\n // Write environment variables to .env file\n try {\n await addOrUpdateEnvVar(process.cwd(), 'FIGMA_CONTENT_SYSTEM_ID', contentSystemId)\n log.debug(`Added FIGMA_CONTENT_SYSTEM_ID to .env file`)\n\n if (datasetInfo) {\n await addOrUpdateEnvVar(process.cwd(), 'FIGMA_TENANT_ID', datasetInfo.tenantId)\n await addOrUpdateEnvVar(process.cwd(), 'FIGMA_OAUTH_CLIENT_ID', datasetInfo.oauthClientId)\n await addOrUpdateEnvVar(\n process.cwd(),\n 'FIGMA_OAUTH_CLIENT_SECRET',\n datasetInfo.oauthClientSecret,\n )\n log.debug(\n `Added FIGMA_TENANT_ID, FIGMA_OAUTH_CLIENT_ID, FIGMA_OAUTH_CLIENT_SECRET to .env file`,\n )\n }\n } catch (error) {\n p.log.warn(\n pc.yellow(\n `⚠ Failed to update .env file: ${error instanceof Error ? error.message : 'Unknown error'}`,\n ),\n )\n }\n } else {\n // Has package.json but no Payload - offer to add Payload\n p.log.warn(pc.yellow('⚠ No Payload detected in this project'))\n\n const shouldAddPayload = await p.confirm({\n initialValue: true,\n message: 'Would you like to add Payload to this project?',\n })\n\n if (p.isCancel(shouldAddPayload)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n if (!shouldAddPayload) {\n p.log.error('Payload is required to use Figma CMS')\n process.exit(1)\n }\n\n // TODO: Add Payload to existing project (future enhancement)\n p.log.error('Adding Payload to existing projects is not yet supported')\n p.note('Create a new project or manually add Payload dependencies', 'Action Required')\n process.exit(1)\n }\n\n // Generate import map to prevent errors on first pnpm dev\n await runScript(process.cwd(), 'generate:importmap', projectInfo.packageManager || 'pnpm')\n\n // Apply Lambda modifications (run.sh, standalone output, lambda:buildzip script)\n await applyLambdaModifications(process.cwd(), projectInfo.packageManager || 'pnpm')\n\n // Ensure .gitignore has required entries\n await ensureGitignore(process.cwd(), ['.env', '.env.local', 'lambda.zip'])\n\n // Generate project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, contentSystemId, s)\n }\n\n // Success message for existing project\n p.outro(pc.green('✓ Project initialized successfully!'))\n\n const nextSteps = ['Start development server: `pnpm dev`'].filter(Boolean)\n\n p.note(nextSteps.join('\\n'), 'Next Steps')\n } else {\n // ===== NEW PROJECT FLOW =====\n // p.log.info('No project detected - Creating New Project')\n\n // Prompt for path\n const projectPathInput = await p.text({\n initialValue: './',\n message: 'Enter path to create project:',\n placeholder: './my-cms-project',\n validate: (value) => {\n if (!value) {\n return 'Path is required'\n }\n // Allow relative or absolute paths\n return undefined\n },\n })\n\n if (p.isCancel(projectPathInput)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n const projectPath = projectPathInput\n const fullPath = path.resolve(process.cwd(), projectPath)\n\n // Get project name from path or prompt\n const projectName = options.name || path.basename(fullPath)\n\n // Create directory\n try {\n await fs.mkdir(fullPath, { recursive: true })\n } catch (error) {\n p.log.error(\n `Failed to create directory: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n process.exit(1)\n }\n\n // Scaffold project\n s.start('Downloading template from GitHub...')\n try {\n await scaffoldProject(fullPath, projectName)\n s.stop(pc.green('✓ Template downloaded'))\n\n s.start('Installing dependencies...')\n await installDependencies(fullPath, 'pnpm')\n s.stop(pc.green('✓ Dependencies installed'))\n } catch (error) {\n s.stop(pc.red('✗ Failed'))\n log.error(error instanceof Error ? error.message : 'Unknown error')\n process.exit(1)\n }\n\n // Modify Payload configuration\n s.start('Checking Payload configuration...')\n const modResult = await ensurePayloadFigmaConfig(fullPath, 'pnpm', {\n contentSystemId,\n })\n\n if (!modResult.success) {\n s.stop(pc.red('✗ Configuration check failed'))\n displayManualInstructions(modResult.error || 'Unknown error')\n process.exit(1)\n }\n\n if (modResult.modified) {\n s.stop(pc.green('✓ Payload configuration updated'))\n if (modResult.changes.length > 0) {\n modResult.changes.forEach((change) => log.debug(pc.dim(` → ${change}`)))\n }\n } else {\n s.stop(pc.green('✓ Payload configuration valid'))\n }\n\n // Display warnings if any\n if (modResult.warnings && modResult.warnings.length > 0) {\n modResult.warnings.forEach((warning) => {\n p.log.warn(pc.yellow(`⚠ ${warning}`))\n })\n }\n\n // Write environment variables to .env file\n try {\n await addOrUpdateEnvVar(fullPath, 'FIGMA_CONTENT_SYSTEM_ID', contentSystemId)\n log.debug(`Added FIGMA_CONTENT_SYSTEM_ID to .env file`)\n\n if (datasetInfo) {\n await addOrUpdateEnvVar(fullPath, 'FIGMA_TENANT_ID', datasetInfo.tenantId)\n await addOrUpdateEnvVar(fullPath, 'FIGMA_OAUTH_CLIENT_ID', datasetInfo.oauthClientId)\n await addOrUpdateEnvVar(\n fullPath,\n 'FIGMA_OAUTH_CLIENT_SECRET',\n datasetInfo.oauthClientSecret,\n )\n log.debug(\n `Added FIGMA_TENANT_ID, FIGMA_OAUTH_CLIENT_ID, FIGMA_OAUTH_CLIENT_SECRET to .env file`,\n )\n }\n } catch (error) {\n p.log.warn(\n pc.yellow(\n `⚠ Failed to update .env file: ${error instanceof Error ? error.message : 'Unknown error'}`,\n ),\n )\n }\n\n // Generate import map to prevent errors on first pnpm dev\n await runScript(fullPath, 'generate:importmap', 'pnpm')\n\n // Generate project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, contentSystemId, s)\n }\n\n // Initialize git repository (after all files including lock file are ready)\n initializeGitRepo(fullPath)\n\n // Success message for NEW project\n p.log.step(pc.bgGreen(pc.black(' Project created successfully! ')))\n\n const relativePath = path.relative(process.cwd(), fullPath)\n const nextSteps: string[] = []\n\n // Only show cd command if user needs to navigate\n if (relativePath && relativePath !== '.') {\n nextSteps.push(`cd ${relativePath}`)\n }\n\n nextSteps.push(\n 'pnpm dev or follow directions in README.md',\n '',\n 'Documentation:',\n '- Getting Started: https://payloadcms.com/docs/getting-started/what-is-payload',\n '- Configuration: https://payloadcms.com/docs/configuration/overview',\n )\n\n p.note(nextSteps.join('\\n'), 'Next Steps')\n p.outro(pc.green('✓ Done'))\n }\n}\n"],"names":["p","fs","path","pc","getDatasetInfo","FigmaApiError","getValidAccessToken","getValidProjectToken","ProjectTokenError","getTokenStore","ensureGitignore","addOrUpdateEnvVar","isDebug","applyLambdaModifications","log","displayManualInstructions","ensurePayloadFigmaConfig","runScript","detectPayloadProject","hasRequiredDependencies","initializeGitRepo","installDependencies","isInProjectDirectory","scaffoldProject","validatePayloadVersion","loginCommand","generateProjectTokenWithFeedback","tokenStore","contentSystemId","spinner","start","projectToken","stop","green","yellow","error","warning","message","note","Error","fetchDatasetInfo","accessToken","datasetId","debug","datasetInfo","oauthClientId","oauthClientSecret","tenantId","initCommand","options","s","skipAuth","warn","hasValidTokens","token","showNextSteps","newToken","process","exit","red","id","dim","isInProject","projectInfo","hasPayload","payloadVersion","success","hasDeps","cwd","shouldInstall","confirm","initialValue","isCancel","packageManager","modResult","modified","changes","length","forEach","change","warnings","shouldAddPayload","cancel","outro","nextSteps","filter","Boolean","join","projectPathInput","text","placeholder","validate","value","undefined","projectPath","fullPath","resolve","projectName","name","basename","mkdir","recursive","step","bgGreen","black","relativePath","relative","push"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"list-tokens.d.ts","sourceRoot":"","sources":["../../src/commands/list-tokens.ts"],"names":[],"mappings":"AAOA;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,wBAAwB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,wBAA6B,GAAG,IAAI,CA6C/E"}
1
+ {"version":3,"file":"list-tokens.d.ts","sourceRoot":"","sources":["../../src/commands/list-tokens.ts"],"names":[],"mappings":"AAQA;;GAEG;AACH,MAAM,WAAW,wBAAwB;IACvC,wBAAwB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,QAAQ,GAAE,wBAA6B,GAAG,IAAI,CA8C/E"}
@@ -1,6 +1,7 @@
1
1
  import * as p from '@clack/prompts';
2
2
  import pc from 'picocolors';
3
3
  import { getTokenStore } from '../auth/token-store.js';
4
+ import { getEnvironment } from '../constants.js';
4
5
  import { isDebug } from '../utils/is-debug.js';
5
6
  import { formatTimestamp, maskToken, showProjectTokens } from '../utils/token-display.js';
6
7
  /**
@@ -19,7 +20,8 @@ import { formatTimestamp, maskToken, showProjectTokens } from '../utils/token-di
19
20
  }
20
21
  const isValid = tokenStore.hasValidTokens();
21
22
  const status = isValid ? pc.green('✓ Valid') : pc.red('✗ Expired');
22
- p.log.step(pc.bold('Stored Tokens'));
23
+ const env = getEnvironment();
24
+ p.log.step(pc.bold(`Token Status (${env})`));
23
25
  // Build OAuth token info display
24
26
  const lines = [
25
27
  `Status: ${status}`,
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/list-tokens.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { getTokenStore } from '../auth/token-store.js'\nimport { isDebug } from '../utils/is-debug.js'\nimport { formatTimestamp, maskToken, showProjectTokens } from '../utils/token-display.js'\n\n/**\n * Options for list-tokens command\n */\nexport interface ListTokensCommandOptions {\n /** Enable debug mode */\n debug?: boolean\n}\n\n/**\n * Handle the `@payloadcms/figma list-tokens` command\n *\n * Displays stored token information including OAuth and project tokens.\n *\n * @param _options - Command options (unused)\n */\nexport function listTokensCommand(_options: ListTokensCommandOptions = {}): void {\n const tokenStore = getTokenStore()\n\n const tokens = tokenStore.getTokens()\n\n if (!tokens) {\n p.log.warn(pc.yellow('No tokens found. Not authenticated.'))\n p.note(`Run ${pc.cyan('@payloadcms/figma login')} to authenticate`, 'Tip')\n return\n }\n\n const isValid = tokenStore.hasValidTokens()\n const status = isValid ? pc.green('✓ Valid') : pc.red('✗ Expired')\n\n p.log.step(pc.bold('Stored Tokens'))\n\n // Build OAuth token info display\n const lines = [\n `Status: ${status}`,\n `Access Token: ${isDebug() ? tokens.accessToken : maskToken(tokens.accessToken)}`,\n `Refresh Token: ${isDebug() ? tokens.refreshToken : maskToken(tokens.refreshToken)}`,\n `Expires: ${formatTimestamp(tokens.expiresAt)}`,\n ]\n\n if (tokens.userId) {\n lines.push(`User ID: ${tokens.userId}`)\n }\n\n if (tokens.scopes && tokens.scopes.length > 0) {\n lines.push(`Scopes: ${tokens.scopes.join(', ')}`)\n }\n\n lines.push(`Storage Path: ${pc.dim(tokenStore.getStoragePath())}`)\n\n p.note(lines.join('\\n'), 'OAuth Tokens')\n\n if (!isValid) {\n p.note(\n `Tokens have expired. Run ${pc.cyan('@payloadcms/figma login')} to re-authenticate`,\n 'Action Required',\n )\n }\n\n // Show project tokens if any exist\n showProjectTokens(tokenStore)\n}\n"],"names":["p","pc","getTokenStore","isDebug","formatTimestamp","maskToken","showProjectTokens","listTokensCommand","_options","tokenStore","tokens","getTokens","log","warn","yellow","note","cyan","isValid","hasValidTokens","status","green","red","step","bold","lines","accessToken","refreshToken","expiresAt","userId","push","scopes","length","join","dim","getStoragePath"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,aAAY;AAE3B,SAASC,aAAa,QAAQ,yBAAwB;AACtD,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,SAASC,eAAe,EAAEC,SAAS,EAAEC,iBAAiB,QAAQ,4BAA2B;AAUzF;;;;;;CAMC,GACD,OAAO,SAASC,kBAAkBC,WAAqC,CAAC,CAAC;IACvE,MAAMC,aAAaP;IAEnB,MAAMQ,SAASD,WAAWE,SAAS;IAEnC,IAAI,CAACD,QAAQ;QACXV,EAAEY,GAAG,CAACC,IAAI,CAACZ,GAAGa,MAAM,CAAC;QACrBd,EAAEe,IAAI,CAAC,CAAC,IAAI,EAAEd,GAAGe,IAAI,CAAC,2BAA2B,gBAAgB,CAAC,EAAE;QACpE;IACF;IAEA,MAAMC,UAAUR,WAAWS,cAAc;IACzC,MAAMC,SAASF,UAAUhB,GAAGmB,KAAK,CAAC,aAAanB,GAAGoB,GAAG,CAAC;IAEtDrB,EAAEY,GAAG,CAACU,IAAI,CAACrB,GAAGsB,IAAI,CAAC;IAEnB,iCAAiC;IACjC,MAAMC,QAAQ;QACZ,CAAC,gBAAgB,EAAEL,QAAQ;QAC3B,CAAC,gBAAgB,EAAEhB,YAAYO,OAAOe,WAAW,GAAGpB,UAAUK,OAAOe,WAAW,GAAG;QACnF,CAAC,gBAAgB,EAAEtB,YAAYO,OAAOgB,YAAY,GAAGrB,UAAUK,OAAOgB,YAAY,GAAG;QACrF,CAAC,gBAAgB,EAAEtB,gBAAgBM,OAAOiB,SAAS,GAAG;KACvD;IAED,IAAIjB,OAAOkB,MAAM,EAAE;QACjBJ,MAAMK,IAAI,CAAC,CAAC,gBAAgB,EAAEnB,OAAOkB,MAAM,EAAE;IAC/C;IAEA,IAAIlB,OAAOoB,MAAM,IAAIpB,OAAOoB,MAAM,CAACC,MAAM,GAAG,GAAG;QAC7CP,MAAMK,IAAI,CAAC,CAAC,gBAAgB,EAAEnB,OAAOoB,MAAM,CAACE,IAAI,CAAC,OAAO;IAC1D;IAEAR,MAAMK,IAAI,CAAC,CAAC,gBAAgB,EAAE5B,GAAGgC,GAAG,CAACxB,WAAWyB,cAAc,KAAK;IAEnElC,EAAEe,IAAI,CAACS,MAAMQ,IAAI,CAAC,OAAO;IAEzB,IAAI,CAACf,SAAS;QACZjB,EAAEe,IAAI,CACJ,CAAC,yBAAyB,EAAEd,GAAGe,IAAI,CAAC,2BAA2B,mBAAmB,CAAC,EACnF;IAEJ;IAEA,mCAAmC;IACnCV,kBAAkBG;AACpB"}
1
+ {"version":3,"sources":["../../src/commands/list-tokens.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { getTokenStore } from '../auth/token-store.js'\nimport { getEnvironment } from '../constants.js'\nimport { isDebug } from '../utils/is-debug.js'\nimport { formatTimestamp, maskToken, showProjectTokens } from '../utils/token-display.js'\n\n/**\n * Options for list-tokens command\n */\nexport interface ListTokensCommandOptions {\n /** Enable debug mode */\n debug?: boolean\n}\n\n/**\n * Handle the `@payloadcms/figma list-tokens` command\n *\n * Displays stored token information including OAuth and project tokens.\n *\n * @param _options - Command options (unused)\n */\nexport function listTokensCommand(_options: ListTokensCommandOptions = {}): void {\n const tokenStore = getTokenStore()\n\n const tokens = tokenStore.getTokens()\n\n if (!tokens) {\n p.log.warn(pc.yellow('No tokens found. Not authenticated.'))\n p.note(`Run ${pc.cyan('@payloadcms/figma login')} to authenticate`, 'Tip')\n return\n }\n\n const isValid = tokenStore.hasValidTokens()\n const status = isValid ? pc.green('✓ Valid') : pc.red('✗ Expired')\n\n const env = getEnvironment()\n p.log.step(pc.bold(`Token Status (${env})`))\n\n // Build OAuth token info display\n const lines = [\n `Status: ${status}`,\n `Access Token: ${isDebug() ? tokens.accessToken : maskToken(tokens.accessToken)}`,\n `Refresh Token: ${isDebug() ? tokens.refreshToken : maskToken(tokens.refreshToken)}`,\n `Expires: ${formatTimestamp(tokens.expiresAt)}`,\n ]\n\n if (tokens.userId) {\n lines.push(`User ID: ${tokens.userId}`)\n }\n\n if (tokens.scopes && tokens.scopes.length > 0) {\n lines.push(`Scopes: ${tokens.scopes.join(', ')}`)\n }\n\n lines.push(`Storage Path: ${pc.dim(tokenStore.getStoragePath())}`)\n\n p.note(lines.join('\\n'), 'OAuth Tokens')\n\n if (!isValid) {\n p.note(\n `Tokens have expired. Run ${pc.cyan('@payloadcms/figma login')} to re-authenticate`,\n 'Action Required',\n )\n }\n\n // Show project tokens if any exist\n showProjectTokens(tokenStore)\n}\n"],"names":["p","pc","getTokenStore","getEnvironment","isDebug","formatTimestamp","maskToken","showProjectTokens","listTokensCommand","_options","tokenStore","tokens","getTokens","log","warn","yellow","note","cyan","isValid","hasValidTokens","status","green","red","env","step","bold","lines","accessToken","refreshToken","expiresAt","userId","push","scopes","length","join","dim","getStoragePath"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,aAAY;AAE3B,SAASC,aAAa,QAAQ,yBAAwB;AACtD,SAASC,cAAc,QAAQ,kBAAiB;AAChD,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,SAASC,eAAe,EAAEC,SAAS,EAAEC,iBAAiB,QAAQ,4BAA2B;AAUzF;;;;;;CAMC,GACD,OAAO,SAASC,kBAAkBC,WAAqC,CAAC,CAAC;IACvE,MAAMC,aAAaR;IAEnB,MAAMS,SAASD,WAAWE,SAAS;IAEnC,IAAI,CAACD,QAAQ;QACXX,EAAEa,GAAG,CAACC,IAAI,CAACb,GAAGc,MAAM,CAAC;QACrBf,EAAEgB,IAAI,CAAC,CAAC,IAAI,EAAEf,GAAGgB,IAAI,CAAC,2BAA2B,gBAAgB,CAAC,EAAE;QACpE;IACF;IAEA,MAAMC,UAAUR,WAAWS,cAAc;IACzC,MAAMC,SAASF,UAAUjB,GAAGoB,KAAK,CAAC,aAAapB,GAAGqB,GAAG,CAAC;IAEtD,MAAMC,MAAMpB;IACZH,EAAEa,GAAG,CAACW,IAAI,CAACvB,GAAGwB,IAAI,CAAC,CAAC,cAAc,EAAEF,IAAI,CAAC,CAAC;IAE1C,iCAAiC;IACjC,MAAMG,QAAQ;QACZ,CAAC,gBAAgB,EAAEN,QAAQ;QAC3B,CAAC,gBAAgB,EAAEhB,YAAYO,OAAOgB,WAAW,GAAGrB,UAAUK,OAAOgB,WAAW,GAAG;QACnF,CAAC,gBAAgB,EAAEvB,YAAYO,OAAOiB,YAAY,GAAGtB,UAAUK,OAAOiB,YAAY,GAAG;QACrF,CAAC,gBAAgB,EAAEvB,gBAAgBM,OAAOkB,SAAS,GAAG;KACvD;IAED,IAAIlB,OAAOmB,MAAM,EAAE;QACjBJ,MAAMK,IAAI,CAAC,CAAC,gBAAgB,EAAEpB,OAAOmB,MAAM,EAAE;IAC/C;IAEA,IAAInB,OAAOqB,MAAM,IAAIrB,OAAOqB,MAAM,CAACC,MAAM,GAAG,GAAG;QAC7CP,MAAMK,IAAI,CAAC,CAAC,gBAAgB,EAAEpB,OAAOqB,MAAM,CAACE,IAAI,CAAC,OAAO;IAC1D;IAEAR,MAAMK,IAAI,CAAC,CAAC,gBAAgB,EAAE9B,GAAGkC,GAAG,CAACzB,WAAW0B,cAAc,KAAK;IAEnEpC,EAAEgB,IAAI,CAACU,MAAMQ,IAAI,CAAC,OAAO;IAEzB,IAAI,CAAChB,SAAS;QACZlB,EAAEgB,IAAI,CACJ,CAAC,yBAAyB,EAAEf,GAAGgB,IAAI,CAAC,2BAA2B,mBAAmB,CAAC,EACnF;IAEJ;IAEA,mCAAmC;IACnCV,kBAAkBG;AACpB"}
@@ -1 +1 @@
1
- {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAUA,KAAK,SAAS,GAAG;IACf;;OAEG;IACH,aAAa,EAAE,OAAO,CAAA;CACvB,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BlE"}
1
+ {"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAWA,KAAK,SAAS,GAAG;IACf;;OAEG;IACH,aAAa,EAAE,OAAO,CAAA;CACvB,CAAA;AAED;;;;;GAKG;AACH,wBAAsB,YAAY,CAAC,IAAI,CAAC,EAAE,SAAS,GAAG,OAAO,CAAC,IAAI,CAAC,CA2BlE"}
@@ -2,7 +2,8 @@ import * as p from '@clack/prompts';
2
2
  import pc from 'picocolors';
3
3
  import { executeOAuthFlow, getValidAccessToken, OAuthFlowError } from '../auth/oauth-flow.js';
4
4
  import { getTokenStore } from '../auth/token-store.js';
5
- import { OAUTH_CONFIG } from '../config/oauth.js';
5
+ import { getOAuthConfig } from '../config/oauth.js';
6
+ import { getEnvironment } from '../constants.js';
6
7
  import * as log from '../utils/log.js';
7
8
  /**
8
9
  * Handle the `@payloadcms/figma login` command
@@ -42,12 +43,14 @@ import * as log from '../utils/log.js';
42
43
  */ async function handleAuthentication({ showNextSteps, tokenStore }) {
43
44
  try {
44
45
  // Execute OAuth flow
46
+ const oauthConfig = getOAuthConfig();
45
47
  const result = await executeOAuthFlow(tokenStore, {
46
- clientId: OAUTH_CONFIG.clientId,
47
- redirectUri: OAUTH_CONFIG.redirectUri,
48
- scopes: OAUTH_CONFIG.scopes
48
+ clientId: oauthConfig.clientId,
49
+ redirectUri: oauthConfig.redirectUri,
50
+ scopes: oauthConfig.scopes
49
51
  });
50
- p.log.success(pc.green('✓ You are now authenticated with Figma'));
52
+ const env = getEnvironment();
53
+ p.log.success(pc.green(`✓ Logged in to Figma (${env})`));
51
54
  if (result.userId) {
52
55
  log.debug(`User ID: ${result.userId}`);
53
56
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport type { TokenStore } from '../auth/token-store.js'\n\nimport { executeOAuthFlow, getValidAccessToken, OAuthFlowError } from '../auth/oauth-flow.js'\nimport { getTokenStore } from '../auth/token-store.js'\nimport { OAUTH_CONFIG } from '../config/oauth.js'\nimport * as log from '../utils/log.js'\n\ntype LoginArgs = {\n /** Set this to show next steps after login\n * @default true\n */\n showNextSteps: boolean\n}\n\n/**\n * Handle the `@payloadcms/figma login` command\n *\n * Authenticates the user with Figma OAuth2 and stores tokens locally.\n * If valid tokens already exist, shows an error message.\n */\nexport async function loginCommand(args?: LoginArgs): Promise<void> {\n const { showNextSteps } = args || { showNextSteps: false }\n const tokenStore = getTokenStore()\n\n // Check for existing valid tokens\n try {\n const existingToken = await getValidAccessToken(tokenStore)\n if (existingToken) {\n const tokens = tokenStore.getTokens()\n p.log.warn(pc.yellow('Already logged in'))\n if (tokens?.userId) {\n log.info(`User ID: ${tokens.userId}`)\n }\n log.info(`Token storage: ${pc.dim(tokenStore.getStoragePath())}`)\n p.note(`To re-authenticate, first run ${pc.cyan('@payloadcms/figma logout')}`, 'Tip')\n return\n }\n } catch {\n // Token refresh failed - continue with new auth flow\n log.warning('Existing tokens are invalid. Starting new authentication...')\n }\n\n // Start OAuth flow\n await handleAuthentication({\n showNextSteps,\n tokenStore,\n })\n}\n\n/**\n * Handle authentication flow\n */\nasync function handleAuthentication({\n showNextSteps,\n tokenStore,\n}: {\n showNextSteps: boolean\n tokenStore: TokenStore\n}): Promise<void> {\n try {\n // Execute OAuth flow\n const result = await executeOAuthFlow(tokenStore, {\n clientId: OAUTH_CONFIG.clientId,\n redirectUri: OAUTH_CONFIG.redirectUri,\n scopes: OAUTH_CONFIG.scopes,\n })\n\n p.log.success(pc.green('✓ You are now authenticated with Figma'))\n\n if (result.userId) {\n log.debug(`User ID: ${result.userId}`)\n }\n\n log.debug(`Token storage: ${pc.dim(tokenStore.getStoragePath())}`)\n\n // Show next steps unless disabled\n if (showNextSteps !== false) {\n p.note(` ${pc.cyan('@payloadcms/figma init')} Create a new CMS instance`, 'Next Steps')\n }\n } catch (error) {\n if (error instanceof OAuthFlowError) {\n log.error(error.message)\n\n if (error.cause) {\n log.debug(`Cause: ${error.cause.message}`)\n }\n } else {\n log.error(error instanceof Error ? error.message : 'Unknown error')\n }\n\n process.exit(1)\n }\n}\n"],"names":["p","pc","executeOAuthFlow","getValidAccessToken","OAuthFlowError","getTokenStore","OAUTH_CONFIG","log","loginCommand","args","showNextSteps","tokenStore","existingToken","tokens","getTokens","warn","yellow","userId","info","dim","getStoragePath","note","cyan","warning","handleAuthentication","result","clientId","redirectUri","scopes","success","green","debug","error","message","cause","Error","process","exit"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,aAAY;AAI3B,SAASC,gBAAgB,EAAEC,mBAAmB,EAAEC,cAAc,QAAQ,wBAAuB;AAC7F,SAASC,aAAa,QAAQ,yBAAwB;AACtD,SAASC,YAAY,QAAQ,qBAAoB;AACjD,YAAYC,SAAS,kBAAiB;AAStC;;;;;CAKC,GACD,OAAO,eAAeC,aAAaC,IAAgB;IACjD,MAAM,EAAEC,aAAa,EAAE,GAAGD,QAAQ;QAAEC,eAAe;IAAM;IACzD,MAAMC,aAAaN;IAEnB,kCAAkC;IAClC,IAAI;QACF,MAAMO,gBAAgB,MAAMT,oBAAoBQ;QAChD,IAAIC,eAAe;YACjB,MAAMC,SAASF,WAAWG,SAAS;YACnCd,EAAEO,GAAG,CAACQ,IAAI,CAACd,GAAGe,MAAM,CAAC;YACrB,IAAIH,QAAQI,QAAQ;gBAClBV,IAAIW,IAAI,CAAC,CAAC,SAAS,EAAEL,OAAOI,MAAM,EAAE;YACtC;YACAV,IAAIW,IAAI,CAAC,CAAC,eAAe,EAAEjB,GAAGkB,GAAG,CAACR,WAAWS,cAAc,KAAK;YAChEpB,EAAEqB,IAAI,CAAC,CAAC,8BAA8B,EAAEpB,GAAGqB,IAAI,CAAC,6BAA6B,EAAE;YAC/E;QACF;IACF,EAAE,OAAM;QACN,qDAAqD;QACrDf,IAAIgB,OAAO,CAAC;IACd;IAEA,mBAAmB;IACnB,MAAMC,qBAAqB;QACzBd;QACAC;IACF;AACF;AAEA;;CAEC,GACD,eAAea,qBAAqB,EAClCd,aAAa,EACbC,UAAU,EAIX;IACC,IAAI;QACF,qBAAqB;QACrB,MAAMc,SAAS,MAAMvB,iBAAiBS,YAAY;YAChDe,UAAUpB,aAAaoB,QAAQ;YAC/BC,aAAarB,aAAaqB,WAAW;YACrCC,QAAQtB,aAAasB,MAAM;QAC7B;QAEA5B,EAAEO,GAAG,CAACsB,OAAO,CAAC5B,GAAG6B,KAAK,CAAC;QAEvB,IAAIL,OAAOR,MAAM,EAAE;YACjBV,IAAIwB,KAAK,CAAC,CAAC,SAAS,EAAEN,OAAOR,MAAM,EAAE;QACvC;QAEAV,IAAIwB,KAAK,CAAC,CAAC,eAAe,EAAE9B,GAAGkB,GAAG,CAACR,WAAWS,cAAc,KAAK;QAEjE,kCAAkC;QAClC,IAAIV,kBAAkB,OAAO;YAC3BV,EAAEqB,IAAI,CAAC,CAAC,EAAE,EAAEpB,GAAGqB,IAAI,CAAC,0BAA0B,2BAA2B,CAAC,EAAE;QAC9E;IACF,EAAE,OAAOU,OAAO;QACd,IAAIA,iBAAiB5B,gBAAgB;YACnCG,IAAIyB,KAAK,CAACA,MAAMC,OAAO;YAEvB,IAAID,MAAME,KAAK,EAAE;gBACf3B,IAAIwB,KAAK,CAAC,CAAC,OAAO,EAAEC,MAAME,KAAK,CAACD,OAAO,EAAE;YAC3C;QACF,OAAO;YACL1B,IAAIyB,KAAK,CAACA,iBAAiBG,QAAQH,MAAMC,OAAO,GAAG;QACrD;QAEAG,QAAQC,IAAI,CAAC;IACf;AACF"}
1
+ {"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport type { TokenStore } from '../auth/token-store.js'\n\nimport { executeOAuthFlow, getValidAccessToken, OAuthFlowError } from '../auth/oauth-flow.js'\nimport { getTokenStore } from '../auth/token-store.js'\nimport { getOAuthConfig } from '../config/oauth.js'\nimport { getEnvironment } from '../constants.js'\nimport * as log from '../utils/log.js'\n\ntype LoginArgs = {\n /** Set this to show next steps after login\n * @default true\n */\n showNextSteps: boolean\n}\n\n/**\n * Handle the `@payloadcms/figma login` command\n *\n * Authenticates the user with Figma OAuth2 and stores tokens locally.\n * If valid tokens already exist, shows an error message.\n */\nexport async function loginCommand(args?: LoginArgs): Promise<void> {\n const { showNextSteps } = args || { showNextSteps: false }\n const tokenStore = getTokenStore()\n\n // Check for existing valid tokens\n try {\n const existingToken = await getValidAccessToken(tokenStore)\n if (existingToken) {\n const tokens = tokenStore.getTokens()\n p.log.warn(pc.yellow('Already logged in'))\n if (tokens?.userId) {\n log.info(`User ID: ${tokens.userId}`)\n }\n log.info(`Token storage: ${pc.dim(tokenStore.getStoragePath())}`)\n p.note(`To re-authenticate, first run ${pc.cyan('@payloadcms/figma logout')}`, 'Tip')\n return\n }\n } catch {\n // Token refresh failed - continue with new auth flow\n log.warning('Existing tokens are invalid. Starting new authentication...')\n }\n\n // Start OAuth flow\n await handleAuthentication({\n showNextSteps,\n tokenStore,\n })\n}\n\n/**\n * Handle authentication flow\n */\nasync function handleAuthentication({\n showNextSteps,\n tokenStore,\n}: {\n showNextSteps: boolean\n tokenStore: TokenStore\n}): Promise<void> {\n try {\n // Execute OAuth flow\n const oauthConfig = getOAuthConfig()\n const result = await executeOAuthFlow(tokenStore, {\n clientId: oauthConfig.clientId,\n redirectUri: oauthConfig.redirectUri,\n scopes: oauthConfig.scopes,\n })\n\n const env = getEnvironment()\n p.log.success(pc.green(`✓ Logged in to Figma (${env})`))\n\n if (result.userId) {\n log.debug(`User ID: ${result.userId}`)\n }\n\n log.debug(`Token storage: ${pc.dim(tokenStore.getStoragePath())}`)\n\n // Show next steps unless disabled\n if (showNextSteps !== false) {\n p.note(` ${pc.cyan('@payloadcms/figma init')} Create a new CMS instance`, 'Next Steps')\n }\n } catch (error) {\n if (error instanceof OAuthFlowError) {\n log.error(error.message)\n\n if (error.cause) {\n log.debug(`Cause: ${error.cause.message}`)\n }\n } else {\n log.error(error instanceof Error ? error.message : 'Unknown error')\n }\n\n process.exit(1)\n }\n}\n"],"names":["p","pc","executeOAuthFlow","getValidAccessToken","OAuthFlowError","getTokenStore","getOAuthConfig","getEnvironment","log","loginCommand","args","showNextSteps","tokenStore","existingToken","tokens","getTokens","warn","yellow","userId","info","dim","getStoragePath","note","cyan","warning","handleAuthentication","oauthConfig","result","clientId","redirectUri","scopes","env","success","green","debug","error","message","cause","Error","process","exit"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,aAAY;AAI3B,SAASC,gBAAgB,EAAEC,mBAAmB,EAAEC,cAAc,QAAQ,wBAAuB;AAC7F,SAASC,aAAa,QAAQ,yBAAwB;AACtD,SAASC,cAAc,QAAQ,qBAAoB;AACnD,SAASC,cAAc,QAAQ,kBAAiB;AAChD,YAAYC,SAAS,kBAAiB;AAStC;;;;;CAKC,GACD,OAAO,eAAeC,aAAaC,IAAgB;IACjD,MAAM,EAAEC,aAAa,EAAE,GAAGD,QAAQ;QAAEC,eAAe;IAAM;IACzD,MAAMC,aAAaP;IAEnB,kCAAkC;IAClC,IAAI;QACF,MAAMQ,gBAAgB,MAAMV,oBAAoBS;QAChD,IAAIC,eAAe;YACjB,MAAMC,SAASF,WAAWG,SAAS;YACnCf,EAAEQ,GAAG,CAACQ,IAAI,CAACf,GAAGgB,MAAM,CAAC;YACrB,IAAIH,QAAQI,QAAQ;gBAClBV,IAAIW,IAAI,CAAC,CAAC,SAAS,EAAEL,OAAOI,MAAM,EAAE;YACtC;YACAV,IAAIW,IAAI,CAAC,CAAC,eAAe,EAAElB,GAAGmB,GAAG,CAACR,WAAWS,cAAc,KAAK;YAChErB,EAAEsB,IAAI,CAAC,CAAC,8BAA8B,EAAErB,GAAGsB,IAAI,CAAC,6BAA6B,EAAE;YAC/E;QACF;IACF,EAAE,OAAM;QACN,qDAAqD;QACrDf,IAAIgB,OAAO,CAAC;IACd;IAEA,mBAAmB;IACnB,MAAMC,qBAAqB;QACzBd;QACAC;IACF;AACF;AAEA;;CAEC,GACD,eAAea,qBAAqB,EAClCd,aAAa,EACbC,UAAU,EAIX;IACC,IAAI;QACF,qBAAqB;QACrB,MAAMc,cAAcpB;QACpB,MAAMqB,SAAS,MAAMzB,iBAAiBU,YAAY;YAChDgB,UAAUF,YAAYE,QAAQ;YAC9BC,aAAaH,YAAYG,WAAW;YACpCC,QAAQJ,YAAYI,MAAM;QAC5B;QAEA,MAAMC,MAAMxB;QACZP,EAAEQ,GAAG,CAACwB,OAAO,CAAC/B,GAAGgC,KAAK,CAAC,CAAC,sBAAsB,EAAEF,IAAI,CAAC,CAAC;QAEtD,IAAIJ,OAAOT,MAAM,EAAE;YACjBV,IAAI0B,KAAK,CAAC,CAAC,SAAS,EAAEP,OAAOT,MAAM,EAAE;QACvC;QAEAV,IAAI0B,KAAK,CAAC,CAAC,eAAe,EAAEjC,GAAGmB,GAAG,CAACR,WAAWS,cAAc,KAAK;QAEjE,kCAAkC;QAClC,IAAIV,kBAAkB,OAAO;YAC3BX,EAAEsB,IAAI,CAAC,CAAC,EAAE,EAAErB,GAAGsB,IAAI,CAAC,0BAA0B,2BAA2B,CAAC,EAAE;QAC9E;IACF,EAAE,OAAOY,OAAO;QACd,IAAIA,iBAAiB/B,gBAAgB;YACnCI,IAAI2B,KAAK,CAACA,MAAMC,OAAO;YAEvB,IAAID,MAAME,KAAK,EAAE;gBACf7B,IAAI0B,KAAK,CAAC,CAAC,OAAO,EAAEC,MAAME,KAAK,CAACD,OAAO,EAAE;YAC3C;QACF,OAAO;YACL5B,IAAI2B,KAAK,CAACA,iBAAiBG,QAAQH,MAAMC,OAAO,GAAG;QACrD;QAEAG,QAAQC,IAAI,CAAC;IACf;AACF"}
@@ -1,24 +1,10 @@
1
1
  import type { OAuthConfig } from '../auth/types.js';
2
- /**
3
- * Default port for OAuth callback server
4
- * Using a high port (34462) to avoid conflicts with common dev servers (3000, 8080, etc.)
5
- */
6
2
  export declare const DEFAULT_CALLBACK_PORT = 34462;
7
3
  export declare const URLS: Record<'prod' | 'staging', Pick<OAuthConfig, 'authorizationUrl' | 'refreshUrl' | 'tokenUrl'>>;
8
4
  /**
9
- * Figma OAuth2 configuration for public CLI client
10
- *
11
- * This is a PUBLIC OAuth client using PKCE (Proof Key for Code Exchange).
12
- * No client secret is used because CLIs cannot securely store secrets.
13
- * PKCE provides security through the code_verifier/code_challenge mechanism.
14
- *
15
- * For production use, register a public OAuth app with Figma.
16
- * To register an OAuth app, visit: https://www.figma.com/developers/api#oauth2
17
- */
18
- export declare const OAUTH_CONFIG: OAuthConfig;
19
- /**
20
- * Buffer time (in seconds) before token expiration to consider token as expired
21
- * This helps avoid using tokens that are about to expire
5
+ * Get OAuth configuration for current environment
6
+ * Uses getEnvironment() to determine staging vs production
22
7
  */
8
+ export declare function getOAuthConfig(): OAuthConfig;
23
9
  export declare const TOKEN_EXPIRY_BUFFER_SECONDS = 300;
24
10
  //# sourceMappingURL=oauth.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/config/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAInD;;;GAGG;AACH,eAAO,MAAM,qBAAqB,QAAQ,CAAA;AAE1C,eAAO,MAAM,IAAI,EAAE,MAAM,CACvB,MAAM,GAAG,SAAS,EAClB,IAAI,CAAC,WAAW,EAAE,kBAAkB,GAAG,YAAY,GAAG,UAAU,CAAC,CAkBlE,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,EAAE,WAgB1B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAA"}
1
+ {"version":3,"file":"oauth.d.ts","sourceRoot":"","sources":["../../src/config/oauth.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,kBAAkB,CAAA;AAInD,eAAO,MAAM,qBAAqB,QAAQ,CAAA;AAE1C,eAAO,MAAM,IAAI,EAAE,MAAM,CACvB,MAAM,GAAG,SAAS,EAClB,IAAI,CAAC,WAAW,EAAE,kBAAkB,GAAG,YAAY,GAAG,UAAU,CAAC,CAkBlE,CAAA;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAW5C;AAED,eAAO,MAAM,2BAA2B,MAAM,CAAA"}
@@ -1,8 +1,5 @@
1
- import { FIGMA_CLIENT_IDS } from '../constants.js';
2
- /**
3
- * Default port for OAuth callback server
4
- * Using a high port (34462) to avoid conflicts with common dev servers (3000, 8080, etc.)
5
- */ export const DEFAULT_CALLBACK_PORT = 34462;
1
+ import { ENV_CONFIG, getEnvironment } from '../constants.js';
2
+ export const DEFAULT_CALLBACK_PORT = 34462;
6
3
  export const URLS = {
7
4
  prod: {
8
5
  authorizationUrl: 'https://www.figma.com/oauth',
@@ -10,39 +7,26 @@ export const URLS = {
10
7
  tokenUrl: 'https://api.figma.com/v1/oauth/token'
11
8
  },
12
9
  staging: {
13
- authorizationUrl: process.env.FIGMA_AUTH_URL ? `${process.env.FIGMA_AUTH_URL}/oauth` // TODO: Might need to add /cms here based on recent changes
14
- : 'https://staging.figma.com/oauth',
10
+ authorizationUrl: process.env.FIGMA_AUTH_URL ? `${process.env.FIGMA_AUTH_URL}/oauth` : 'https://staging.figma.com/oauth',
15
11
  refreshUrl: process.env.FIGMA_API_URL ? `${process.env.FIGMA_API_URL}/v1/oauth/refresh` : 'https://api.staging.figma.com/v1/oauth/refresh',
16
12
  tokenUrl: process.env.FIGMA_API_URL ? `${process.env.FIGMA_API_URL}/v1/oauth/token` : 'https://api.staging.figma.com/v1/oauth/token'
17
13
  }
18
14
  };
19
15
  /**
20
- * Figma OAuth2 configuration for public CLI client
21
- *
22
- * This is a PUBLIC OAuth client using PKCE (Proof Key for Code Exchange).
23
- * No client secret is used because CLIs cannot securely store secrets.
24
- * PKCE provides security through the code_verifier/code_challenge mechanism.
25
- *
26
- * For production use, register a public OAuth app with Figma.
27
- * To register an OAuth app, visit: https://www.figma.com/developers/api#oauth2
28
- */ export const OAUTH_CONFIG = {
29
- // OAuth client ID (public client)
30
- // Uses staging client ID by default since we use staging endpoints
31
- clientId: process.env.FIGMA_CLIENT_ID || FIGMA_CLIENT_IDS.staging,
32
- // No client secret - this is a public OAuth client using PKCE
33
- // Public clients cannot securely store secrets in CLI environments
34
- redirectUri: process.env.FIGMA_REDIRECT_URI || `http://localhost:${DEFAULT_CALLBACK_PORT}/callback`,
35
- // Only current_user:read scope is needed for basic user info
36
- scopes: [
37
- 'current_user:read'
38
- ],
39
- // TODO: Dynamically choose between prod and staging based on environment
40
- ...URLS.staging
41
- };
42
- /**
43
- * Buffer time (in seconds) before token expiration to consider token as expired
44
- * This helps avoid using tokens that are about to expire
45
- */ export const TOKEN_EXPIRY_BUFFER_SECONDS = 300 // 5 minutes
46
- ;
16
+ * Get OAuth configuration for current environment
17
+ * Uses getEnvironment() to determine staging vs production
18
+ */ export function getOAuthConfig() {
19
+ const env = getEnvironment();
20
+ const urlKey = env === 'production' ? 'prod' : 'staging';
21
+ return {
22
+ clientId: process.env.FIGMA_CLIENT_ID || ENV_CONFIG[env].clientId,
23
+ redirectUri: process.env.FIGMA_REDIRECT_URI || `http://localhost:${DEFAULT_CALLBACK_PORT}/callback`,
24
+ scopes: [
25
+ 'current_user:read'
26
+ ],
27
+ ...URLS[urlKey]
28
+ };
29
+ }
30
+ export const TOKEN_EXPIRY_BUFFER_SECONDS = 300;
47
31
 
48
32
  //# sourceMappingURL=oauth.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/config/oauth.ts"],"sourcesContent":["import type { OAuthConfig } from '../auth/types.js'\n\nimport { FIGMA_CLIENT_IDS } from '../constants.js'\n\n/**\n * Default port for OAuth callback server\n * Using a high port (34462) to avoid conflicts with common dev servers (3000, 8080, etc.)\n */\nexport const DEFAULT_CALLBACK_PORT = 34462\n\nexport const URLS: Record<\n 'prod' | 'staging',\n Pick<OAuthConfig, 'authorizationUrl' | 'refreshUrl' | 'tokenUrl'>\n> = {\n prod: {\n authorizationUrl: 'https://www.figma.com/oauth',\n refreshUrl: 'https://api.figma.com/v1/oauth/refresh',\n tokenUrl: 'https://api.figma.com/v1/oauth/token',\n },\n staging: {\n authorizationUrl: process.env.FIGMA_AUTH_URL\n ? `${process.env.FIGMA_AUTH_URL}/oauth` // TODO: Might need to add /cms here based on recent changes\n : 'https://staging.figma.com/oauth',\n refreshUrl: process.env.FIGMA_API_URL\n ? `${process.env.FIGMA_API_URL}/v1/oauth/refresh`\n : 'https://api.staging.figma.com/v1/oauth/refresh',\n tokenUrl: process.env.FIGMA_API_URL\n ? `${process.env.FIGMA_API_URL}/v1/oauth/token`\n : 'https://api.staging.figma.com/v1/oauth/token',\n },\n}\n\n/**\n * Figma OAuth2 configuration for public CLI client\n *\n * This is a PUBLIC OAuth client using PKCE (Proof Key for Code Exchange).\n * No client secret is used because CLIs cannot securely store secrets.\n * PKCE provides security through the code_verifier/code_challenge mechanism.\n *\n * For production use, register a public OAuth app with Figma.\n * To register an OAuth app, visit: https://www.figma.com/developers/api#oauth2\n */\nexport const OAUTH_CONFIG: OAuthConfig = {\n // OAuth client ID (public client)\n // Uses staging client ID by default since we use staging endpoints\n clientId: process.env.FIGMA_CLIENT_ID || FIGMA_CLIENT_IDS.staging,\n\n // No client secret - this is a public OAuth client using PKCE\n // Public clients cannot securely store secrets in CLI environments\n\n redirectUri:\n process.env.FIGMA_REDIRECT_URI || `http://localhost:${DEFAULT_CALLBACK_PORT}/callback`,\n\n // Only current_user:read scope is needed for basic user info\n scopes: ['current_user:read'],\n\n // TODO: Dynamically choose between prod and staging based on environment\n ...URLS.staging,\n}\n\n/**\n * Buffer time (in seconds) before token expiration to consider token as expired\n * This helps avoid using tokens that are about to expire\n */\nexport const TOKEN_EXPIRY_BUFFER_SECONDS = 300 // 5 minutes\n"],"names":["FIGMA_CLIENT_IDS","DEFAULT_CALLBACK_PORT","URLS","prod","authorizationUrl","refreshUrl","tokenUrl","staging","process","env","FIGMA_AUTH_URL","FIGMA_API_URL","OAUTH_CONFIG","clientId","FIGMA_CLIENT_ID","redirectUri","FIGMA_REDIRECT_URI","scopes","TOKEN_EXPIRY_BUFFER_SECONDS"],"mappings":"AAEA,SAASA,gBAAgB,QAAQ,kBAAiB;AAElD;;;CAGC,GACD,OAAO,MAAMC,wBAAwB,MAAK;AAE1C,OAAO,MAAMC,OAGT;IACFC,MAAM;QACJC,kBAAkB;QAClBC,YAAY;QACZC,UAAU;IACZ;IACAC,SAAS;QACPH,kBAAkBI,QAAQC,GAAG,CAACC,cAAc,GACxC,GAAGF,QAAQC,GAAG,CAACC,cAAc,CAAC,MAAM,CAAC,CAAC,4DAA4D;WAClG;QACJL,YAAYG,QAAQC,GAAG,CAACE,aAAa,GACjC,GAAGH,QAAQC,GAAG,CAACE,aAAa,CAAC,iBAAiB,CAAC,GAC/C;QACJL,UAAUE,QAAQC,GAAG,CAACE,aAAa,GAC/B,GAAGH,QAAQC,GAAG,CAACE,aAAa,CAAC,eAAe,CAAC,GAC7C;IACN;AACF,EAAC;AAED;;;;;;;;;CASC,GACD,OAAO,MAAMC,eAA4B;IACvC,kCAAkC;IAClC,mEAAmE;IACnEC,UAAUL,QAAQC,GAAG,CAACK,eAAe,IAAId,iBAAiBO,OAAO;IAEjE,8DAA8D;IAC9D,mEAAmE;IAEnEQ,aACEP,QAAQC,GAAG,CAACO,kBAAkB,IAAI,CAAC,iBAAiB,EAAEf,sBAAsB,SAAS,CAAC;IAExF,6DAA6D;IAC7DgB,QAAQ;QAAC;KAAoB;IAE7B,yEAAyE;IACzE,GAAGf,KAAKK,OAAO;AACjB,EAAC;AAED;;;CAGC,GACD,OAAO,MAAMW,8BAA8B,IAAI,YAAY;CAAb"}
1
+ {"version":3,"sources":["../../src/config/oauth.ts"],"sourcesContent":["import type { OAuthConfig } from '../auth/types.js'\n\nimport { ENV_CONFIG, getEnvironment } from '../constants.js'\n\nexport const DEFAULT_CALLBACK_PORT = 34462\n\nexport const URLS: Record<\n 'prod' | 'staging',\n Pick<OAuthConfig, 'authorizationUrl' | 'refreshUrl' | 'tokenUrl'>\n> = {\n prod: {\n authorizationUrl: 'https://www.figma.com/oauth',\n refreshUrl: 'https://api.figma.com/v1/oauth/refresh',\n tokenUrl: 'https://api.figma.com/v1/oauth/token',\n },\n staging: {\n authorizationUrl: process.env.FIGMA_AUTH_URL\n ? `${process.env.FIGMA_AUTH_URL}/oauth`\n : 'https://staging.figma.com/oauth',\n refreshUrl: process.env.FIGMA_API_URL\n ? `${process.env.FIGMA_API_URL}/v1/oauth/refresh`\n : 'https://api.staging.figma.com/v1/oauth/refresh',\n tokenUrl: process.env.FIGMA_API_URL\n ? `${process.env.FIGMA_API_URL}/v1/oauth/token`\n : 'https://api.staging.figma.com/v1/oauth/token',\n },\n}\n\n/**\n * Get OAuth configuration for current environment\n * Uses getEnvironment() to determine staging vs production\n */\nexport function getOAuthConfig(): OAuthConfig {\n const env = getEnvironment()\n const urlKey = env === 'production' ? 'prod' : 'staging'\n\n return {\n clientId: process.env.FIGMA_CLIENT_ID || ENV_CONFIG[env].clientId,\n redirectUri:\n process.env.FIGMA_REDIRECT_URI || `http://localhost:${DEFAULT_CALLBACK_PORT}/callback`,\n scopes: ['current_user:read'],\n ...URLS[urlKey],\n }\n}\n\nexport const TOKEN_EXPIRY_BUFFER_SECONDS = 300\n"],"names":["ENV_CONFIG","getEnvironment","DEFAULT_CALLBACK_PORT","URLS","prod","authorizationUrl","refreshUrl","tokenUrl","staging","process","env","FIGMA_AUTH_URL","FIGMA_API_URL","getOAuthConfig","urlKey","clientId","FIGMA_CLIENT_ID","redirectUri","FIGMA_REDIRECT_URI","scopes","TOKEN_EXPIRY_BUFFER_SECONDS"],"mappings":"AAEA,SAASA,UAAU,EAAEC,cAAc,QAAQ,kBAAiB;AAE5D,OAAO,MAAMC,wBAAwB,MAAK;AAE1C,OAAO,MAAMC,OAGT;IACFC,MAAM;QACJC,kBAAkB;QAClBC,YAAY;QACZC,UAAU;IACZ;IACAC,SAAS;QACPH,kBAAkBI,QAAQC,GAAG,CAACC,cAAc,GACxC,GAAGF,QAAQC,GAAG,CAACC,cAAc,CAAC,MAAM,CAAC,GACrC;QACJL,YAAYG,QAAQC,GAAG,CAACE,aAAa,GACjC,GAAGH,QAAQC,GAAG,CAACE,aAAa,CAAC,iBAAiB,CAAC,GAC/C;QACJL,UAAUE,QAAQC,GAAG,CAACE,aAAa,GAC/B,GAAGH,QAAQC,GAAG,CAACE,aAAa,CAAC,eAAe,CAAC,GAC7C;IACN;AACF,EAAC;AAED;;;CAGC,GACD,OAAO,SAASC;IACd,MAAMH,MAAMT;IACZ,MAAMa,SAASJ,QAAQ,eAAe,SAAS;IAE/C,OAAO;QACLK,UAAUN,QAAQC,GAAG,CAACM,eAAe,IAAIhB,UAAU,CAACU,IAAI,CAACK,QAAQ;QACjEE,aACER,QAAQC,GAAG,CAACQ,kBAAkB,IAAI,CAAC,iBAAiB,EAAEhB,sBAAsB,SAAS,CAAC;QACxFiB,QAAQ;YAAC;SAAoB;QAC7B,GAAGhB,IAAI,CAACW,OAAO;IACjB;AACF;AAEA,OAAO,MAAMM,8BAA8B,IAAG"}
@@ -1,20 +1,30 @@
1
- export declare const FIGMA_CLIENT_IDS: {
2
- production: string;
3
- staging: string;
4
- };
5
- export declare const JWKS_URI: {
6
- production: string;
7
- staging: string;
8
- };
9
1
  /**
10
2
  * Figma environment (production or staging)
11
3
  */
12
4
  export type Environment = 'production' | 'staging';
5
+ type EnvironmentConfig = {
6
+ /** OAuth client ID. Override: FIGMA_CLIENT_ID or FIGMA_OAUTH_CLIENT_ID */
7
+ clientId: string;
8
+ /** Content API base URL. Override: FIGMA_CONTENT_API_URL */
9
+ contentApiUrl: string;
10
+ /** OIDC discovery endpoint */
11
+ identityMetadata: string;
12
+ /** JSON Web Key Set URL for token validation */
13
+ jwksUri: string;
14
+ };
13
15
  /**
14
- * Get current Figma environment from environment variable
15
- * Defaults to 'staging' if not specified
16
- *
17
- * @returns Current environment
16
+ * Environment-specific configuration for Figma integration.
17
+ * Selected via FIGMA_ENV ('production' | 'staging'), defaults to 'staging'.
18
+ */
19
+ export declare const ENV_CONFIG: Record<Environment, EnvironmentConfig>;
20
+ /**
21
+ * Set environment override (used by --env CLI flag)
22
+ * Pass undefined to clear the override
23
+ */
24
+ export declare function setEnvironment(env: Environment | undefined): void;
25
+ /**
26
+ * Get current Figma environment
27
+ * Priority: 1) setEnvironment override, 2) FIGMA_ENV env var, 3) 'staging' default
18
28
  */
19
29
  export declare function getEnvironment(): Environment;
20
30
  /**
@@ -24,4 +34,5 @@ export declare function getEnvironment(): Environment;
24
34
  * @returns JWKS URI for the environment
25
35
  */
26
36
  export declare function getJWKSUri(env?: Environment): string;
37
+ export {};
27
38
  //# sourceMappingURL=constants.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,gBAAgB;;;CAG5B,CAAA;AAED,eAAO,MAAM,QAAQ;;;CAGpB,CAAA;AAED;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,SAAS,CAAA;AAElD;;;;;GAKG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAE5C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,CAGpD"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,MAAM,WAAW,GAAG,YAAY,GAAG,SAAS,CAAA;AAElD,KAAK,iBAAiB,GAAG;IACvB,0EAA0E;IAC1E,QAAQ,EAAE,MAAM,CAAA;IAChB,4DAA4D;IAC5D,aAAa,EAAE,MAAM,CAAA;IACrB,8BAA8B;IAC9B,gBAAgB,EAAE,MAAM,CAAA;IACxB,gDAAgD;IAChD,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,UAAU,EAAE,MAAM,CAAC,WAAW,EAAE,iBAAiB,CAa7D,CAAA;AAID;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,WAAW,GAAG,SAAS,GAAG,IAAI,CAEjE;AAED;;;GAGG;AACH,wBAAgB,cAAc,IAAI,WAAW,CAK5C;AAED;;;;;GAKG;AACH,wBAAgB,UAAU,CAAC,GAAG,CAAC,EAAE,WAAW,GAAG,MAAM,CAGpD"}
package/dist/constants.js CHANGED
@@ -1,17 +1,36 @@
1
- export const FIGMA_CLIENT_IDS = {
2
- production: '',
3
- staging: 'wqAToBAp4UI9AZ5M6wTfT9'
4
- };
5
- export const JWKS_URI = {
6
- production: 'https://static.figmacontent.com/.well_known/jwks.json',
7
- staging: 'https://static.figmacontentstaging.com/.well_known/jwks.json'
1
+ /**
2
+ * Figma environment (production or staging)
3
+ */ /**
4
+ * Environment-specific configuration for Figma integration.
5
+ * Selected via FIGMA_ENV ('production' | 'staging'), defaults to 'staging'.
6
+ */ export const ENV_CONFIG = {
7
+ production: {
8
+ clientId: 'lelKVTAzOekFnirnlAMbuD',
9
+ contentApiUrl: 'https://us-east-1.cms-tenants-001.figmacontent.com',
10
+ identityMetadata: 'https://www.figma.com/.well-known/openid-configuration',
11
+ jwksUri: 'https://static.figmacontent.com/.well_known/jwks.json'
12
+ },
13
+ staging: {
14
+ clientId: 'wqAToBAp4UI9AZ5M6wTfT9',
15
+ contentApiUrl: 'https://us-east-1.cms-tenants-001-staging.figmacontentstaging.com',
16
+ identityMetadata: 'https://staging.figma.com/.well-known/openid-configuration',
17
+ jwksUri: 'https://static.figmacontentstaging.com/.well_known/jwks.json'
18
+ }
8
19
  };
20
+ let envOverride;
9
21
  /**
10
- * Get current Figma environment from environment variable
11
- * Defaults to 'staging' if not specified
12
- *
13
- * @returns Current environment
22
+ * Set environment override (used by --env CLI flag)
23
+ * Pass undefined to clear the override
24
+ */ export function setEnvironment(env) {
25
+ envOverride = env;
26
+ }
27
+ /**
28
+ * Get current Figma environment
29
+ * Priority: 1) setEnvironment override, 2) FIGMA_ENV env var, 3) 'staging' default
14
30
  */ export function getEnvironment() {
31
+ if (envOverride) {
32
+ return envOverride;
33
+ }
15
34
  return process.env.FIGMA_ENV === 'production' ? 'production' : 'staging';
16
35
  }
17
36
  /**
@@ -21,7 +40,7 @@ export const JWKS_URI = {
21
40
  * @returns JWKS URI for the environment
22
41
  */ export function getJWKSUri(env) {
23
42
  const environment = env || getEnvironment();
24
- return JWKS_URI[environment];
43
+ return ENV_CONFIG[environment].jwksUri;
25
44
  }
26
45
 
27
46
  //# sourceMappingURL=constants.js.map
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/constants.ts"],"sourcesContent":["export const FIGMA_CLIENT_IDS = {\n production: '',\n staging: 'wqAToBAp4UI9AZ5M6wTfT9', // Hard-coded staging client ID\n}\n\nexport const JWKS_URI = {\n production: 'https://static.figmacontent.com/.well_known/jwks.json',\n staging: 'https://static.figmacontentstaging.com/.well_known/jwks.json',\n}\n\n/**\n * Figma environment (production or staging)\n */\nexport type Environment = 'production' | 'staging'\n\n/**\n * Get current Figma environment from environment variable\n * Defaults to 'staging' if not specified\n *\n * @returns Current environment\n */\nexport function getEnvironment(): Environment {\n return process.env.FIGMA_ENV === 'production' ? 'production' : 'staging'\n}\n\n/**\n * Get JWKS URI for a given environment\n *\n * @param env - Environment (defaults to current environment)\n * @returns JWKS URI for the environment\n */\nexport function getJWKSUri(env?: Environment): string {\n const environment = env || getEnvironment()\n return JWKS_URI[environment]\n}\n"],"names":["FIGMA_CLIENT_IDS","production","staging","JWKS_URI","getEnvironment","process","env","FIGMA_ENV","getJWKSUri","environment"],"mappings":"AAAA,OAAO,MAAMA,mBAAmB;IAC9BC,YAAY;IACZC,SAAS;AACX,EAAC;AAED,OAAO,MAAMC,WAAW;IACtBF,YAAY;IACZC,SAAS;AACX,EAAC;AAOD;;;;;CAKC,GACD,OAAO,SAASE;IACd,OAAOC,QAAQC,GAAG,CAACC,SAAS,KAAK,eAAe,eAAe;AACjE;AAEA;;;;;CAKC,GACD,OAAO,SAASC,WAAWF,GAAiB;IAC1C,MAAMG,cAAcH,OAAOF;IAC3B,OAAOD,QAAQ,CAACM,YAAY;AAC9B"}
1
+ {"version":3,"sources":["../src/constants.ts"],"sourcesContent":["/**\n * Figma environment (production or staging)\n */\nexport type Environment = 'production' | 'staging'\n\ntype EnvironmentConfig = {\n /** OAuth client ID. Override: FIGMA_CLIENT_ID or FIGMA_OAUTH_CLIENT_ID */\n clientId: string\n /** Content API base URL. Override: FIGMA_CONTENT_API_URL */\n contentApiUrl: string\n /** OIDC discovery endpoint */\n identityMetadata: string\n /** JSON Web Key Set URL for token validation */\n jwksUri: string\n}\n\n/**\n * Environment-specific configuration for Figma integration.\n * Selected via FIGMA_ENV ('production' | 'staging'), defaults to 'staging'.\n */\nexport const ENV_CONFIG: Record<Environment, EnvironmentConfig> = {\n production: {\n clientId: 'lelKVTAzOekFnirnlAMbuD',\n contentApiUrl: 'https://us-east-1.cms-tenants-001.figmacontent.com',\n identityMetadata: 'https://www.figma.com/.well-known/openid-configuration',\n jwksUri: 'https://static.figmacontent.com/.well_known/jwks.json',\n },\n staging: {\n clientId: 'wqAToBAp4UI9AZ5M6wTfT9',\n contentApiUrl: 'https://us-east-1.cms-tenants-001-staging.figmacontentstaging.com',\n identityMetadata: 'https://staging.figma.com/.well-known/openid-configuration',\n jwksUri: 'https://static.figmacontentstaging.com/.well_known/jwks.json',\n },\n}\n\nlet envOverride: Environment | undefined\n\n/**\n * Set environment override (used by --env CLI flag)\n * Pass undefined to clear the override\n */\nexport function setEnvironment(env: Environment | undefined): void {\n envOverride = env\n}\n\n/**\n * Get current Figma environment\n * Priority: 1) setEnvironment override, 2) FIGMA_ENV env var, 3) 'staging' default\n */\nexport function getEnvironment(): Environment {\n if (envOverride) {\n return envOverride\n }\n return process.env.FIGMA_ENV === 'production' ? 'production' : 'staging'\n}\n\n/**\n * Get JWKS URI for a given environment\n *\n * @param env - Environment (defaults to current environment)\n * @returns JWKS URI for the environment\n */\nexport function getJWKSUri(env?: Environment): string {\n const environment = env || getEnvironment()\n return ENV_CONFIG[environment].jwksUri\n}\n"],"names":["ENV_CONFIG","production","clientId","contentApiUrl","identityMetadata","jwksUri","staging","envOverride","setEnvironment","env","getEnvironment","process","FIGMA_ENV","getJWKSUri","environment"],"mappings":"AAAA;;CAEC,GAcD;;;CAGC,GACD,OAAO,MAAMA,aAAqD;IAChEC,YAAY;QACVC,UAAU;QACVC,eAAe;QACfC,kBAAkB;QAClBC,SAAS;IACX;IACAC,SAAS;QACPJ,UAAU;QACVC,eAAe;QACfC,kBAAkB;QAClBC,SAAS;IACX;AACF,EAAC;AAED,IAAIE;AAEJ;;;CAGC,GACD,OAAO,SAASC,eAAeC,GAA4B;IACzDF,cAAcE;AAChB;AAEA;;;CAGC,GACD,OAAO,SAASC;IACd,IAAIH,aAAa;QACf,OAAOA;IACT;IACA,OAAOI,QAAQF,GAAG,CAACG,SAAS,KAAK,eAAe,eAAe;AACjE;AAEA;;;;;CAKC,GACD,OAAO,SAASC,WAAWJ,GAAiB;IAC1C,MAAMK,cAAcL,OAAOC;IAC3B,OAAOV,UAAU,CAACc,YAAY,CAACT,OAAO;AACxC"}
@@ -14,16 +14,6 @@ Future
14
14
 
15
15
  The format stays different. This allows the Content API to evolve its filter schema, for example to support composite types like Point, which are not lexicographically sortable. Semantics must remain identical to Payload.
16
16
 
17
- ## Sorting
18
-
19
- Now
20
- `[{ path: "createdAt", direction: "desc" }]`
21
-
22
- Future
23
- `"-createdAt"` or `"createdAt"` or `["-createdAt", "title"]`
24
-
25
- Sorting will match Payload. It can be a single string or an array of strings using Payload path syntax.
26
-
27
17
  ## Pagination
28
18
 
29
19
  ~~Now~~