@payloadcms/figma 0.0.1-alpha.6 → 0.0.1-alpha.61
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/dist/api/control-plane.d.ts +52 -6
- package/dist/api/control-plane.js +174 -72
- package/dist/api/figma-api.d.ts +22 -1
- package/dist/api/figma-api.js +78 -25
- package/dist/auth/callback-server.js +2 -1
- package/dist/auth/credentials.d.ts +21 -0
- package/dist/auth/credentials.js +21 -0
- package/dist/auth/crypto-utils.d.ts +6 -0
- package/dist/auth/crypto-utils.js +16 -14
- package/dist/auth/jwt-validator.d.ts +2 -1
- package/dist/auth/jwt-validator.js +2 -2
- package/dist/auth/oauth-flow.d.ts +17 -3
- package/dist/auth/oauth-flow.js +63 -16
- package/dist/auth/project-token.js +16 -11
- package/dist/auth/refresh.d.ts +2 -1
- package/dist/auth/refresh.js +25 -12
- package/dist/auth/token-store.d.ts +42 -1
- package/dist/auth/token-store.js +118 -14
- package/dist/auth/types.d.ts +17 -4
- package/dist/cli.js +68 -5
- package/dist/commands/build-lambda-zip.d.ts +5 -0
- package/dist/commands/build-lambda-zip.js +19 -0
- package/dist/commands/debug.d.ts +8 -0
- package/dist/commands/debug.js +176 -0
- package/dist/commands/deploy.d.ts +9 -0
- package/dist/commands/deploy.js +178 -151
- package/dist/commands/env.d.ts +13 -0
- package/dist/commands/env.js +88 -0
- package/dist/commands/init.d.ts +3 -5
- package/dist/commands/init.js +165 -148
- package/dist/commands/list-tokens.d.ts +3 -3
- package/dist/commands/list-tokens.js +22 -7
- package/dist/commands/login.d.ts +8 -1
- package/dist/commands/login.js +33 -15
- package/dist/commands/logout.d.ts +5 -4
- package/dist/commands/logout.js +56 -13
- package/dist/commands/upgrade.d.ts +5 -0
- package/dist/commands/upgrade.js +331 -0
- package/dist/config/oauth.d.ts +4 -14
- package/dist/config/oauth.js +18 -40
- package/dist/constants.d.ts +44 -19
- package/dist/constants.js +73 -20
- package/dist/db-content-api/README.md +98 -0
- package/dist/db-content-api/generated/content-api-types.d.ts +3972 -0
- package/dist/db-content-api/generated/content-api-types.js +7 -0
- package/dist/db-content-api/index.d.ts +21 -0
- package/dist/db-content-api/index.js +914 -0
- package/dist/db-content-api/temp-utilities/slug.d.ts +2 -0
- package/dist/db-content-api/temp-utilities/slug.js +3 -0
- package/dist/db-content-api/temp-utilities/sorting.d.ts +3 -0
- package/dist/db-content-api/temp-utilities/sorting.js +39 -0
- package/dist/db-content-api/temp-utilities/types.d.ts +22 -0
- package/dist/db-content-api/temp-utilities/types.js +15 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +39 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.js +59 -0
- package/dist/db-content-api/utilities/auth.d.ts +30 -0
- package/dist/db-content-api/utilities/auth.js +81 -0
- package/dist/db-content-api/utilities/data/applyDefaults.d.ts +7 -0
- package/dist/db-content-api/utilities/data/applyDefaults.js +75 -0
- package/dist/db-content-api/utilities/data/castFieldValue.d.ts +11 -0
- package/dist/db-content-api/utilities/data/castFieldValue.js +68 -0
- package/dist/db-content-api/utilities/data/index.d.ts +49 -0
- package/dist/db-content-api/utilities/data/index.js +301 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +12 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.js +54 -0
- package/dist/db-content-api/utilities/data/stripFields.d.ts +48 -0
- package/dist/db-content-api/utilities/data/stripFields.js +195 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +23 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.js +42 -0
- package/dist/db-content-api/utilities/joins.d.ts +53 -0
- package/dist/db-content-api/utilities/joins.js +139 -0
- package/dist/db-content-api/utilities/locale/index.d.ts +10 -0
- package/dist/db-content-api/utilities/locale/index.js +21 -0
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts +11 -0
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +74 -0
- package/dist/db-content-api/utilities/meta/buildMeta.d.ts +42 -0
- package/dist/db-content-api/utilities/meta/buildMeta.js +41 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts +17 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.js +244 -0
- package/dist/db-content-api/utilities/meta/buildUniquePaths.d.ts +13 -0
- package/dist/db-content-api/utilities/meta/buildUniquePaths.js +62 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.d.ts +10 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.js +102 -0
- package/dist/db-content-api/utilities/where.d.ts +20 -0
- package/dist/db-content-api/utilities/where.js +108 -0
- package/dist/deploy/schedule-extract-plugin.d.ts +11 -0
- package/dist/deploy/schedule-extract-plugin.js +34 -0
- package/dist/endpoints/health.d.ts +3 -0
- package/dist/endpoints/health.js +11 -0
- package/dist/endpoints/schema.d.ts +3 -0
- package/dist/endpoints/schema.js +29 -0
- package/dist/exports/client.d.ts +3 -0
- package/dist/exports/client.js +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/oauth/components/FigmaAvatar/index.d.ts +4 -0
- package/dist/oauth/components/FigmaAvatar/index.js +27 -0
- package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
- package/dist/oauth/components/FigmaAvatarCell/index.d.ts +5 -0
- package/dist/oauth/components/FigmaAvatarCell/index.js +25 -0
- package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +9 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +37 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
- package/dist/oauth/components/LoginButton/index.js +50 -6
- package/dist/oauth/components/LoginButton/index.scss +50 -3
- package/dist/oauth/components/LogoutButton/index.js +5 -4
- package/dist/oauth/defaults.js +67 -10
- package/dist/oauth/endpoints/getLoginEndpoint.js +77 -24
- package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -4
- package/dist/oauth/index.js +40 -13
- package/dist/oauth/strategy/index.d.ts +0 -2
- package/dist/oauth/strategy/index.js +40 -17
- package/dist/oauth/types.d.ts +6 -6
- package/dist/oauth/utilities/isDuplicateKeyError.d.ts +7 -0
- package/dist/oauth/utilities/isDuplicateKeyError.js +14 -0
- package/dist/oauth/utilities/refreshTokens.js +6 -3
- package/dist/plugin/build-config.d.ts +18 -15
- package/dist/plugin/build-config.js +213 -18
- package/dist/storage-content-api/api-types.d.ts +168 -0
- package/dist/storage-content-api/api-types.js +6 -0
- package/dist/storage-content-api/client-uploads/ClientUploadHandler.d.ts +9 -0
- package/dist/storage-content-api/client-uploads/ClientUploadHandler.js +42 -0
- package/dist/storage-content-api/client-uploads/generateSignedURL.d.ts +13 -0
- package/dist/storage-content-api/client-uploads/generateSignedURL.js +39 -0
- package/dist/storage-content-api/client.d.ts +6 -0
- package/dist/storage-content-api/client.js +36 -0
- package/dist/storage-content-api/generateURL.d.ts +7 -0
- package/dist/storage-content-api/generateURL.js +8 -0
- package/dist/storage-content-api/handleDelete.d.ts +8 -0
- package/dist/storage-content-api/handleDelete.js +17 -0
- package/dist/storage-content-api/handleUpload.d.ts +11 -0
- package/dist/storage-content-api/handleUpload.js +144 -0
- package/dist/storage-content-api/index.d.ts +5 -0
- package/dist/storage-content-api/index.js +31 -0
- package/dist/storage-content-api/staticHandler.d.ts +10 -0
- package/dist/storage-content-api/staticHandler.js +56 -0
- package/dist/storage-content-api/types.d.ts +10 -0
- package/dist/storage-content-api/types.js +3 -0
- package/dist/storage-content-api/utilities/getSafeFilename.d.ts +12 -0
- package/dist/storage-content-api/utilities/getSafeFilename.js +61 -0
- package/dist/storage-content-api/utilities/index.d.ts +2 -0
- package/dist/storage-content-api/utilities/index.js +3 -0
- package/dist/templates/.env.example +5 -0
- package/dist/templates/README.md +19 -0
- package/dist/types/config.d.ts +2 -1
- package/dist/types/config.js +0 -2
- package/dist/types.d.ts +8 -1
- package/dist/utils/adapters/nextjs.d.ts +9 -0
- package/dist/utils/adapters/nextjs.js +64 -0
- package/dist/utils/adapters/nitro.d.ts +9 -0
- package/dist/utils/adapters/nitro.js +169 -0
- package/dist/utils/adapters/vite.d.ts +10 -0
- package/dist/utils/adapters/vite.js +33 -0
- package/dist/utils/asset-collection.d.ts +27 -6
- package/dist/utils/asset-collection.js +59 -30
- package/dist/utils/build-detection.d.ts +5 -11
- package/dist/utils/build-detection.js +74 -11
- package/dist/utils/build-lambda-zip.d.ts +14 -0
- package/dist/utils/build-lambda-zip.js +81 -0
- package/dist/utils/cache-bootstrap.d.ts +8 -0
- package/dist/utils/cache-bootstrap.js +18 -0
- package/dist/utils/config.js +1 -1
- package/dist/utils/deploy-adapter.d.ts +40 -0
- package/dist/utils/deploy-adapter.js +58 -0
- package/dist/utils/download-template.js +3 -2
- package/dist/utils/env-management.d.ts +24 -7
- package/dist/utils/env-management.js +119 -64
- package/dist/utils/format-env-suffix.d.ts +12 -0
- package/dist/utils/format-env-suffix.js +13 -0
- package/dist/utils/formatter.js +23 -11
- package/dist/utils/fs-utils.d.ts +6 -0
- package/dist/utils/fs-utils.js +27 -0
- package/dist/utils/handle-upgrade.d.ts +9 -0
- package/dist/utils/handle-upgrade.js +41 -0
- package/dist/utils/lambda-config.d.ts +3 -1
- package/dist/utils/lambda-config.js +75 -78
- package/dist/utils/messages.d.ts +1 -2
- package/dist/utils/messages.js +29 -11
- package/dist/utils/package-manager.d.ts +24 -0
- package/dist/utils/package-manager.js +53 -0
- package/dist/utils/payload-config-ast.d.ts +27 -6
- package/dist/utils/payload-config-ast.js +106 -58
- package/dist/utils/payload-config-finder.d.ts +2 -2
- package/dist/utils/payload-config-finder.js +48 -9
- package/dist/utils/payload-config-modifier.d.ts +1 -1
- package/dist/utils/payload-config-modifier.js +70 -11
- package/dist/utils/payload-package-check.d.ts +12 -1
- package/dist/utils/payload-package-check.js +63 -5
- package/dist/utils/project.d.ts +3 -2
- package/dist/utils/project.js +29 -15
- package/dist/utils/resolve-environment.d.ts +14 -0
- package/dist/utils/resolve-environment.js +31 -0
- package/dist/utils/s3-upload.d.ts +7 -2
- package/dist/utils/s3-upload.js +39 -6
- package/dist/utils/token-display.js +11 -5
- package/dist/utils/typescript-validator.js +4 -6
- package/dist/utils/version-check.d.ts +3 -0
- package/dist/utils/version-check.js +38 -0
- package/package.json +33 -15
- package/dist/api/control-plane.d.ts.map +0 -1
- package/dist/api/control-plane.js.map +0 -1
- package/dist/api/figma-api.d.ts.map +0 -1
- package/dist/api/figma-api.js.map +0 -1
- package/dist/auth/browser.d.ts.map +0 -1
- package/dist/auth/browser.js.map +0 -1
- package/dist/auth/callback-server.d.ts.map +0 -1
- package/dist/auth/callback-server.js.map +0 -1
- package/dist/auth/crypto-utils.d.ts.map +0 -1
- package/dist/auth/crypto-utils.js.map +0 -1
- package/dist/auth/jwt-validator.d.ts.map +0 -1
- package/dist/auth/jwt-validator.js.map +0 -1
- package/dist/auth/oauth-flow.d.ts.map +0 -1
- package/dist/auth/oauth-flow.js.map +0 -1
- package/dist/auth/pkce.d.ts.map +0 -1
- package/dist/auth/pkce.js.map +0 -1
- package/dist/auth/project-token.d.ts.map +0 -1
- package/dist/auth/project-token.js.map +0 -1
- package/dist/auth/refresh.d.ts.map +0 -1
- package/dist/auth/refresh.js.map +0 -1
- package/dist/auth/token-store.d.ts.map +0 -1
- package/dist/auth/token-store.js.map +0 -1
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/deploy.d.ts.map +0 -1
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list-tokens.d.ts.map +0 -1
- package/dist/commands/list-tokens.js.map +0 -1
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js.map +0 -1
- package/dist/config/oauth.d.ts.map +0 -1
- package/dist/config/oauth.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/exports/client.d.ts.map +0 -1
- package/dist/exports/client.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/oauth/components/LoginButton/index.d.ts.map +0 -1
- package/dist/oauth/components/LoginButton/index.js.map +0 -1
- package/dist/oauth/components/LogoutButton/index.d.ts.map +0 -1
- package/dist/oauth/components/LogoutButton/index.js.map +0 -1
- package/dist/oauth/defaults.d.ts.map +0 -1
- package/dist/oauth/defaults.js.map +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +0 -1
- package/dist/oauth/exports/client.d.ts.map +0 -1
- package/dist/oauth/exports/client.js.map +0 -1
- package/dist/oauth/hooks/afterLogout.d.ts.map +0 -1
- package/dist/oauth/hooks/afterLogout.js.map +0 -1
- package/dist/oauth/hooks/me.d.ts.map +0 -1
- package/dist/oauth/hooks/me.js.map +0 -1
- package/dist/oauth/hooks/refresh.d.ts.map +0 -1
- package/dist/oauth/hooks/refresh.js.map +0 -1
- package/dist/oauth/index.d.ts.map +0 -1
- package/dist/oauth/index.js.map +0 -1
- package/dist/oauth/strategy/index.d.ts.map +0 -1
- package/dist/oauth/strategy/index.js.map +0 -1
- package/dist/oauth/types.d.ts.map +0 -1
- package/dist/oauth/types.js.map +0 -1
- package/dist/oauth/utilities/clearCookie.d.ts.map +0 -1
- package/dist/oauth/utilities/clearCookie.js.map +0 -1
- package/dist/oauth/utilities/createCookieOptions.d.ts.map +0 -1
- package/dist/oauth/utilities/createCookieOptions.js.map +0 -1
- package/dist/oauth/utilities/createDebugLogger.d.ts.map +0 -1
- package/dist/oauth/utilities/createDebugLogger.js.map +0 -1
- package/dist/oauth/utilities/extractOrigin.d.ts.map +0 -1
- package/dist/oauth/utilities/extractOrigin.js.map +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.js.map +0 -1
- package/dist/oauth/utilities/getAdminPath.d.ts +0 -8
- package/dist/oauth/utilities/getAdminPath.d.ts.map +0 -1
- package/dist/oauth/utilities/getAdminPath.js +0 -9
- package/dist/oauth/utilities/getAdminPath.js.map +0 -1
- package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +0 -1
- package/dist/oauth/utilities/getAuthorizeURL.js.map +0 -1
- package/dist/oauth/utilities/getCookieExpiration.d.ts.map +0 -1
- package/dist/oauth/utilities/getCookieExpiration.js.map +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +0 -1
- package/dist/oauth/utilities/getTokenExp.d.ts.map +0 -1
- package/dist/oauth/utilities/getTokenExp.js.map +0 -1
- package/dist/oauth/utilities/getUsernameField.d.ts.map +0 -1
- package/dist/oauth/utilities/getUsernameField.js.map +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +0 -1
- package/dist/oauth/utilities/mergeHeaders.d.ts.map +0 -1
- package/dist/oauth/utilities/mergeHeaders.js.map +0 -1
- package/dist/oauth/utilities/refreshTokens.d.ts.map +0 -1
- package/dist/oauth/utilities/refreshTokens.js.map +0 -1
- package/dist/plugin/adapter.d.ts.map +0 -1
- package/dist/plugin/adapter.js.map +0 -1
- package/dist/plugin/build-config.d.ts.map +0 -1
- package/dist/plugin/build-config.js.map +0 -1
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/config.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/asset-collection.d.ts.map +0 -1
- package/dist/utils/asset-collection.js.map +0 -1
- package/dist/utils/build-detection.d.ts.map +0 -1
- package/dist/utils/build-detection.js.map +0 -1
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/download-template.d.ts.map +0 -1
- package/dist/utils/download-template.js.map +0 -1
- package/dist/utils/env-management.d.ts.map +0 -1
- package/dist/utils/env-management.js.map +0 -1
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/formatter.d.ts.map +0 -1
- package/dist/utils/formatter.js.map +0 -1
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/is-debug.d.ts.map +0 -1
- package/dist/utils/is-debug.js.map +0 -1
- package/dist/utils/lambda-config.d.ts.map +0 -1
- package/dist/utils/lambda-config.js.map +0 -1
- package/dist/utils/log.d.ts.map +0 -1
- package/dist/utils/log.js.map +0 -1
- package/dist/utils/messages.d.ts.map +0 -1
- package/dist/utils/messages.js.map +0 -1
- package/dist/utils/package-manager.d.ts.map +0 -1
- package/dist/utils/package-manager.js.map +0 -1
- package/dist/utils/payload-config-ast.d.ts.map +0 -1
- package/dist/utils/payload-config-ast.js.map +0 -1
- package/dist/utils/payload-config-finder.d.ts.map +0 -1
- package/dist/utils/payload-config-finder.js.map +0 -1
- package/dist/utils/payload-config-modifier.d.ts.map +0 -1
- package/dist/utils/payload-config-modifier.js.map +0 -1
- package/dist/utils/payload-package-check.d.ts.map +0 -1
- package/dist/utils/payload-package-check.js.map +0 -1
- package/dist/utils/project.d.ts.map +0 -1
- package/dist/utils/project.js.map +0 -1
- package/dist/utils/s3-upload.d.ts.map +0 -1
- package/dist/utils/s3-upload.js.map +0 -1
- package/dist/utils/token-display.d.ts.map +0 -1
- package/dist/utils/token-display.js.map +0 -1
- package/dist/utils/typescript-validator.d.ts.map +0 -1
- package/dist/utils/typescript-validator.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/crypto-utils.ts"],"sourcesContent":["import Conf from 'conf'\nimport crypto from 'crypto'\nimport os from 'os'\n\n// Configuration store for cryptographic salt\nconst cryptoConf = new Conf<{ salt: string }>({\n configName: 'payloadcms-figma-crypto',\n projectName: 'payloadcms-figma',\n})\n\n/**\n * Get or generate a random salt for key derivation\n *\n * Generates a cryptographically secure random salt on first run and persists it\n * for future use. This ensures the encryption key is unique per machine and not\n * reproducible even if machine identifiers are known.\n *\n * @returns 32-byte hex string (64 characters)\n */\nfunction getOrCreateSalt(): string {\n let salt = cryptoConf.get('salt')\n if (!salt) {\n // Generate cryptographically secure random salt (32 bytes = 256 bits)\n salt = crypto.randomBytes(32).toString('hex')\n cryptoConf.set('salt', salt)\n }\n return salt\n}\n\n/**\n * Gather machine-specific entropy sources\n *\n * Collects multiple machine and user identifiers to create a unique input\n * for key derivation. More entropy sources make the key harder to guess.\n *\n * @returns Combined machine identifier string\n * @throws Error if unable to gather sufficient entropy\n */\nfunction gatherMachineEntropy(): string {\n try {\n const userInfo = os.userInfo()\n const networkInterfaces = os.networkInterfaces()\n\n // Get MAC address from first available network interface (if available)\n const macAddress = Object.values(networkInterfaces)\n .flat()\n .find((iface) => iface && !iface.internal && iface.mac !== '00:00:00:00:00:00')?.mac\n\n const entropy = [\n os.hostname(), // Machine hostname\n os.homedir(), // User home directory path\n userInfo.username, // OS username\n os.platform(), // Operating system platform\n os.arch(), // CPU architecture\n macAddress, // MAC address (if available)\n ].filter(Boolean) // Remove any undefined values\n\n if (entropy.length < 4) {\n throw new Error('Insufficient machine entropy available')\n }\n\n return entropy.join('::')\n } catch (error) {\n throw new Error(\n `Failed to gather machine entropy: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n}\n\n/**\n * Derive a machine-specific encryption key for token storage\n *\n * Creates a deterministic encryption key using PBKDF2 with machine-specific\n * identifiers and a random salt. This provides stronger security than simple\n * hashing by making brute force attacks computationally expensive.\n *\n * Security model - What this protects against:\n * ✅ Accidental file exposure (cloud backups, shared drives)\n * ✅ Non-technical users reading token files\n * ✅ Brute force attacks (100k PBKDF2 iterations)\n * ✅ Key guessing even with known machine identifiers (random salt)\n *\n * Security model - What this DOES NOT protect against:\n * ❌ Local user compromise (same user can run this function)\n * ❌ Root/admin access attacks\n * ❌ Sophisticated attackers with system access\n *\n * For stronger security, use OS keychain (@napi-rs/keyring) instead.\n * This is a fallback for environments without keychain access.\n *\n * Implementation details:\n * - Uses PBKDF2 with SHA-256 and 100,000 iterations (~500ms-1s)\n * - Combines multiple machine identifiers for entropy\n * - Uses persistent random salt unique to each machine\n * - Produces consistent key for same machine (deterministic)\n * - Tokens are not portable between machines (by design)\n *\n * @returns 64-character hex string (32-byte key) suitable for AES-256 encryption\n * @throws Error if unable to derive key due to missing machine information\n */\nexport function deriveEncryptionKey(): string {\n const machineId = gatherMachineEntropy()\n const salt = getOrCreateSalt()\n\n // PBKDF2 with 100k iterations provides strong security against brute force\n // while remaining performant for CLI use (~500ms-1s key derivation time)\n const key = crypto.pbkdf2Sync(\n machineId, // Password (machine identifiers)\n salt, // Salt (random, persisted)\n 100000, // Iterations (100k for strong security)\n 32, // Key length (32 bytes = 256 bits for AES-256)\n 'sha256', // Hash algorithm\n )\n\n return key.toString('hex')\n}\n"],"names":["Conf","crypto","os","cryptoConf","configName","projectName","getOrCreateSalt","salt","get","randomBytes","toString","set","gatherMachineEntropy","userInfo","networkInterfaces","macAddress","Object","values","flat","find","iface","internal","mac","entropy","hostname","homedir","username","platform","arch","filter","Boolean","length","Error","join","error","message","deriveEncryptionKey","machineId","key","pbkdf2Sync"],"mappings":"AAAA,OAAOA,UAAU,OAAM;AACvB,OAAOC,YAAY,SAAQ;AAC3B,OAAOC,QAAQ,KAAI;AAEnB,6CAA6C;AAC7C,MAAMC,aAAa,IAAIH,KAAuB;IAC5CI,YAAY;IACZC,aAAa;AACf;AAEA;;;;;;;;CAQC,GACD,SAASC;IACP,IAAIC,OAAOJ,WAAWK,GAAG,CAAC;IAC1B,IAAI,CAACD,MAAM;QACT,sEAAsE;QACtEA,OAAON,OAAOQ,WAAW,CAAC,IAAIC,QAAQ,CAAC;QACvCP,WAAWQ,GAAG,CAAC,QAAQJ;IACzB;IACA,OAAOA;AACT;AAEA;;;;;;;;CAQC,GACD,SAASK;IACP,IAAI;QACF,MAAMC,WAAWX,GAAGW,QAAQ;QAC5B,MAAMC,oBAAoBZ,GAAGY,iBAAiB;QAE9C,wEAAwE;QACxE,MAAMC,aAAaC,OAAOC,MAAM,CAACH,mBAC9BI,IAAI,GACJC,IAAI,CAAC,CAACC,QAAUA,SAAS,CAACA,MAAMC,QAAQ,IAAID,MAAME,GAAG,KAAK,sBAAsBA;QAEnF,MAAMC,UAAU;YACdrB,GAAGsB,QAAQ;YACXtB,GAAGuB,OAAO;YACVZ,SAASa,QAAQ;YACjBxB,GAAGyB,QAAQ;YACXzB,GAAG0B,IAAI;YACPb;SACD,CAACc,MAAM,CAACC,SAAS,8BAA8B;;QAEhD,IAAIP,QAAQQ,MAAM,GAAG,GAAG;YACtB,MAAM,IAAIC,MAAM;QAClB;QAEA,OAAOT,QAAQU,IAAI,CAAC;IACtB,EAAE,OAAOC,OAAO;QACd,MAAM,IAAIF,MACR,CAAC,kCAAkC,EAAEE,iBAAiBF,QAAQE,MAAMC,OAAO,GAAG,iBAAiB;IAEnG;AACF;AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CA8BC,GACD,OAAO,SAASC;IACd,MAAMC,YAAYzB;IAClB,MAAML,OAAOD;IAEb,2EAA2E;IAC3E,yEAAyE;IACzE,MAAMgC,MAAMrC,OAAOsC,UAAU,CAC3BF,WACA9B,MACA,QACA,IACA;IAGF,OAAO+B,IAAI5B,QAAQ,CAAC;AACtB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"jwt-validator.d.ts","sourceRoot":"","sources":["../../src/auth/jwt-validator.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,YAAY,CAAA;AAI5C;;GAEG;AACH,qBAAa,kBAAmB,SAAQ,KAAK;IAGlC,IAAI,EAAE,SAAS,GAAG,mBAAmB,GAAG,aAAa,GAAG,mBAAmB;IAC3E,KAAK,CAAC,EAAE,KAAK;gBAFpB,OAAO,EAAE,MAAM,EACR,IAAI,EAAE,SAAS,GAAG,mBAAmB,GAAG,aAAa,GAAG,mBAAmB,EAC3E,KAAK,CAAC,EAAE,KAAK,YAAA;CAKvB;AAqCD;;;;;;;;;;;;;;;;;;;GAmBG;AACH,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,YAAY,GAAG,SAAS,GACpC,OAAO,CAAC,UAAU,CAAC,CA8ErB;AAED;;;;;;;;GAQG;AACH,wBAAgB,cAAc,IAAI,IAAI,CAErC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/jwt-validator.ts"],"sourcesContent":["import { createRemoteJWKSet, jwtVerify } from 'jose'\nimport {\n JWKSMultipleMatchingKeys,\n JWKSNoMatchingKey,\n JWSInvalid,\n JWSSignatureVerificationFailed,\n JWTExpired,\n} from 'jose/errors'\n\nimport type { JWTPayload } from './types.js'\n\nimport { getJWKSUri } from '../constants.js'\n\n/**\n * JWT validation error with specific error codes\n */\nexport class JWTValidationError extends Error {\n constructor(\n message: string,\n public code: 'EXPIRED' | 'JWKS_FETCH_FAILED' | 'MISSING_KID' | 'SIGNATURE_INVALID',\n public cause?: Error,\n ) {\n super(message)\n this.name = 'JWTValidationError'\n }\n}\n\n/**\n * JWKS resolvers cached per environment\n * Uses jose's createRemoteJWKSet which handles:\n * - Automatic JWKS fetching from URI\n * - Built-in caching with configurable max age\n * - Automatic key rotation handling\n * - Cooldown protection between refetches\n */\nconst jwksResolvers = new Map<string, ReturnType<typeof createRemoteJWKSet>>()\n\n/**\n * Get or create a JWKS resolver for a given environment\n *\n * The resolver is cached in module scope and reused across validations.\n * Jose handles all the complexity of fetching, caching, and rotating keys.\n *\n * @param environment - Figma environment ('production' or 'staging')\n * @returns JWKS resolver function\n */\nfunction getJWKSResolver(environment: 'production' | 'staging') {\n const jwksUri = getJWKSUri(environment)\n\n if (!jwksResolvers.has(jwksUri)) {\n jwksResolvers.set(\n jwksUri,\n createRemoteJWKSet(new URL(jwksUri), {\n cacheMaxAge: 24 * 60 * 60 * 1000, // 24 hours\n cooldownDuration: 30000, // 30 seconds between refetches\n }),\n )\n }\n\n return jwksResolvers.get(jwksUri)!\n}\n\n/**\n * Validate a project token JWT\n *\n * This function:\n * 1. Gets the JWKS resolver for the environment (cached)\n * 2. Uses jose's jwtVerify to validate signature and claims in one call\n * 3. Maps jose errors to our custom error types\n *\n * Jose automatically:\n * - Fetches JWKS from the URI (with caching)\n * - Matches the key by kid from the JWT header\n * - Verifies the signature using the correct algorithm\n * - Validates standard claims (exp, iat, nbf)\n * - Handles clock skew tolerance\n *\n * @param token - JWT token string\n * @param environment - Figma environment ('production' or 'staging')\n * @returns Promise resolving to validated JWT payload\n * @throws {JWTValidationError} If validation fails\n */\nexport async function validateProjectToken(\n token: string,\n environment: 'production' | 'staging',\n): Promise<JWTPayload> {\n try {\n const JWKS = getJWKSResolver(environment)\n\n const { payload } = await jwtVerify(token, JWKS, {\n clockTolerance: 300, // 5 minutes clock skew tolerance\n // Optional additional validation (uncomment if Figma provides these):\n // issuer: 'https://api.figma.com',\n // audience: 'payloadcms-figma',\n })\n\n return payload\n } catch (error: unknown) {\n // Map jose errors to our custom error types using instanceof checks\n // This is more reliable than checking error.code strings\n\n // Token expired\n if (error instanceof JWTExpired) {\n throw new JWTValidationError('Project token has expired', 'EXPIRED', error)\n }\n\n // Key not found in JWKS (possible key rotation or invalid kid)\n if (error instanceof JWKSNoMatchingKey) {\n throw new JWTValidationError(\n 'Key not found in JWKS - this may indicate key rotation or an invalid token',\n 'SIGNATURE_INVALID',\n error,\n )\n }\n\n // Multiple matching keys (JWKS configuration issue)\n if (error instanceof JWKSMultipleMatchingKeys) {\n throw new JWTValidationError(\n 'Multiple matching keys found in JWKS',\n 'SIGNATURE_INVALID',\n error,\n )\n }\n\n // Invalid signature or other verification failure\n if (error instanceof JWSSignatureVerificationFailed) {\n throw new JWTValidationError(\n 'JWT signature verification failed - token may be tampered with',\n 'SIGNATURE_INVALID',\n error,\n )\n }\n\n // Missing or invalid kid/alg in JWT header\n if (error instanceof JWSInvalid) {\n throw new JWTValidationError(\n 'Invalid JWT structure - missing required header fields (kid or alg)',\n 'MISSING_KID',\n error,\n )\n }\n\n // Network or fetch errors (not jose errors, generic Error instances)\n if (error instanceof Error) {\n const message = error.message\n if (\n message.includes('fetch') ||\n message.includes('network') ||\n message.includes('ENOTFOUND') ||\n message.includes('ECONNREFUSED')\n ) {\n throw new JWTValidationError(`Failed to fetch JWKS: ${message}`, 'JWKS_FETCH_FAILED', error)\n }\n }\n\n // Generic error fallback\n const message = error instanceof Error ? error.message : 'Unknown error'\n throw new JWTValidationError(\n `JWT validation failed: ${message}`,\n 'SIGNATURE_INVALID',\n error instanceof Error ? error : undefined,\n )\n }\n}\n\n/**\n * Clear JWKS cache (useful for testing or forcing refresh)\n *\n * This clears the cached JWKS resolvers, forcing fresh fetches\n * on the next validation. Useful for:\n * - Testing with different JWKS\n * - Forcing key rotation updates\n * - Clearing state between test runs\n */\nexport function clearJWKSCache(): void {\n jwksResolvers.clear()\n}\n"],"names":["createRemoteJWKSet","jwtVerify","JWKSMultipleMatchingKeys","JWKSNoMatchingKey","JWSInvalid","JWSSignatureVerificationFailed","JWTExpired","getJWKSUri","JWTValidationError","Error","message","code","cause","name","jwksResolvers","Map","getJWKSResolver","environment","jwksUri","has","set","URL","cacheMaxAge","cooldownDuration","get","validateProjectToken","token","JWKS","payload","clockTolerance","error","includes","undefined","clearJWKSCache","clear"],"mappings":"AAAA,SAASA,kBAAkB,EAAEC,SAAS,QAAQ,OAAM;AACpD,SACEC,wBAAwB,EACxBC,iBAAiB,EACjBC,UAAU,EACVC,8BAA8B,EAC9BC,UAAU,QACL,cAAa;AAIpB,SAASC,UAAU,QAAQ,kBAAiB;AAE5C;;CAEC,GACD,OAAO,MAAMC,2BAA2BC;;;IACtC,YACEC,OAAe,EACf,AAAOC,IAA2E,EAClF,AAAOC,KAAa,CACpB;QACA,KAAK,CAACF,eAHCC,OAAAA,WACAC,QAAAA;QAGP,IAAI,CAACC,IAAI,GAAG;IACd;AACF;AAEA;;;;;;;CAOC,GACD,MAAMC,gBAAgB,IAAIC;AAE1B;;;;;;;;CAQC,GACD,SAASC,gBAAgBC,WAAqC;IAC5D,MAAMC,UAAUX,WAAWU;IAE3B,IAAI,CAACH,cAAcK,GAAG,CAACD,UAAU;QAC/BJ,cAAcM,GAAG,CACfF,SACAlB,mBAAmB,IAAIqB,IAAIH,UAAU;YACnCI,aAAa,KAAK,KAAK,KAAK;YAC5BC,kBAAkB;QACpB;IAEJ;IAEA,OAAOT,cAAcU,GAAG,CAACN;AAC3B;AAEA;;;;;;;;;;;;;;;;;;;CAmBC,GACD,OAAO,eAAeO,qBACpBC,KAAa,EACbT,WAAqC;IAErC,IAAI;QACF,MAAMU,OAAOX,gBAAgBC;QAE7B,MAAM,EAAEW,OAAO,EAAE,GAAG,MAAM3B,UAAUyB,OAAOC,MAAM;YAC/CE,gBAAgB;QAIlB;QAEA,OAAOD;IACT,EAAE,OAAOE,OAAgB;QACvB,oEAAoE;QACpE,yDAAyD;QAEzD,gBAAgB;QAChB,IAAIA,iBAAiBxB,YAAY;YAC/B,MAAM,IAAIE,mBAAmB,6BAA6B,WAAWsB;QACvE;QAEA,+DAA+D;QAC/D,IAAIA,iBAAiB3B,mBAAmB;YACtC,MAAM,IAAIK,mBACR,8EACA,qBACAsB;QAEJ;QAEA,oDAAoD;QACpD,IAAIA,iBAAiB5B,0BAA0B;YAC7C,MAAM,IAAIM,mBACR,wCACA,qBACAsB;QAEJ;QAEA,kDAAkD;QAClD,IAAIA,iBAAiBzB,gCAAgC;YACnD,MAAM,IAAIG,mBACR,kEACA,qBACAsB;QAEJ;QAEA,2CAA2C;QAC3C,IAAIA,iBAAiB1B,YAAY;YAC/B,MAAM,IAAII,mBACR,uEACA,eACAsB;QAEJ;QAEA,qEAAqE;QACrE,IAAIA,iBAAiBrB,OAAO;YAC1B,MAAMC,UAAUoB,MAAMpB,OAAO;YAC7B,IACEA,QAAQqB,QAAQ,CAAC,YACjBrB,QAAQqB,QAAQ,CAAC,cACjBrB,QAAQqB,QAAQ,CAAC,gBACjBrB,QAAQqB,QAAQ,CAAC,iBACjB;gBACA,MAAM,IAAIvB,mBAAmB,CAAC,sBAAsB,EAAEE,SAAS,EAAE,qBAAqBoB;YACxF;QACF;QAEA,yBAAyB;QACzB,MAAMpB,UAAUoB,iBAAiBrB,QAAQqB,MAAMpB,OAAO,GAAG;QACzD,MAAM,IAAIF,mBACR,CAAC,uBAAuB,EAAEE,SAAS,EACnC,qBACAoB,iBAAiBrB,QAAQqB,QAAQE;IAErC;AACF;AAEA;;;;;;;;CAQC,GACD,OAAO,SAASC;IACdnB,cAAcoB,KAAK;AACrB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"oauth-flow.d.ts","sourceRoot":"","sources":["../../src/auth/oauth-flow.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAA;AAS7C;;GAEG;AACH,qBAAa,cAAe,SAAQ,KAAK;IAG9B,KAAK,CAAC,EAAE,KAAK;gBADpB,OAAO,EAAE,MAAM,EACR,KAAK,CAAC,EAAE,KAAK,YAAA;CAKvB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,4CAA4C;IAC5C,QAAQ,CAAC,EAAE,MAAM,CAAA;IACjB,8CAA8C;IAC9C,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,WAAW,CAAC,EAAE,MAAM,CAAA;IACpB,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAA;IACjB,4DAA4D;IAC5D,SAAS,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,oBAAoB;IACpB,MAAM,EAAE,WAAW,CAAA;IACnB,oBAAoB;IACpB,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,gBAAgB,CACpC,UAAU,EAAE,UAAU,EACtB,OAAO,GAAE,gBAAqB,GAC7B,OAAO,CAAC,eAAe,CAAC,CAsI1B;AAED;;;;;;;;;GASG;AACH,wBAAsB,mBAAmB,CAAC,UAAU,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAyBxF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/oauth-flow.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport crypto from 'crypto'\n\nimport type { TokenStore } from './token-store.js'\nimport type { FigmaTokens } from './types.js'\n\nimport { OAUTH_CONFIG } from '../config/oauth.js'\nimport * as log from '../utils/log.js'\nimport { buildAuthorizationUrl, openBrowser } from './browser.js'\nimport { CallbackServer } from './callback-server.js'\nimport { generatePKCEPair } from './pkce.js'\nimport { exchangeCodeForTokens, refreshAccessToken } from './refresh.js'\n\n/**\n * Error during OAuth flow\n */\nexport class OAuthFlowError extends Error {\n constructor(\n message: string,\n public cause?: Error,\n ) {\n super(message)\n this.name = 'OAuthFlowError'\n }\n}\n\n/**\n * Options for OAuth flow\n */\nexport interface OAuthFlowOptions {\n /** OAuth2 client ID (defaults to config) */\n clientId?: string\n /** Callback server port (defaults to 3000) */\n port?: number\n /** Redirect URI (defaults to config) */\n redirectUri?: string\n /** OAuth scopes (defaults to config) */\n scopes?: string[]\n /** Callback timeout in milliseconds (defaults to 120000) */\n timeoutMs?: number\n}\n\n/**\n * Result of OAuth flow\n */\nexport interface OAuthFlowResult {\n /** OAuth2 tokens */\n tokens: FigmaTokens\n /** Figma user ID */\n userId?: string\n}\n\n/**\n * Execute complete OAuth2 authorization flow\n *\n * This orchestrates the full OAuth flow:\n * 1. Generate PKCE pair for security\n * 2. Start local callback server\n * 3. Open browser to authorization URL\n * 4. Wait for user to authorize\n * 5. Exchange authorization code for tokens\n * 6. Store tokens securely\n *\n * @param tokenStore - Token store for persisting tokens\n * @param options - Flow configuration options\n * @returns Promise resolving to OAuth flow result\n * @throws OAuthFlowError if any step fails\n */\nexport async function executeOAuthFlow(\n tokenStore: TokenStore,\n options: OAuthFlowOptions = {},\n): Promise<OAuthFlowResult> {\n // Check if OAuth flow should be mocked\n // Default to true for OAuth (allow testing without real authentication by default)\n const shouldMock = process.env.FIGMA_MOCK_OAUTH !== 'false'\n\n if (shouldMock) {\n // MOCK IMPLEMENTATION: Return mock tokens for testing\n log.debug('Using mock OAuth flow (FIGMA_MOCK_OAUTH != \"false\")')\n const mockTokens: FigmaTokens = {\n accessToken: 'figt_mock_access_token_' + crypto.randomBytes(16).toString('hex'),\n expiresAt: Date.now() + 2 * 60 * 60 * 1000, // 2 hours\n refreshToken: 'figt_mock_refresh_token_' + crypto.randomBytes(16).toString('hex'),\n scopes: (options.scopes || OAUTH_CONFIG.scopes) as FigmaTokens['scopes'],\n tokenType: 'Bearer',\n }\n\n // Store mock tokens\n tokenStore.setTokens(mockTokens)\n\n return {\n tokens: mockTokens,\n userId: 'mock_user_123',\n }\n }\n\n // REAL OAUTH IMPLEMENTATION\n const {\n clientId = OAUTH_CONFIG.clientId,\n port = 3000,\n redirectUri = OAUTH_CONFIG.redirectUri,\n scopes = OAUTH_CONFIG.scopes,\n timeoutMs = 120000,\n } = options\n\n // Generate PKCE pair for enhanced security\n const { codeChallenge, codeChallengeMethod, codeVerifier } = generatePKCEPair()\n\n // Generate random state for CSRF protection\n const state = crypto.randomBytes(32).toString('base64url')\n\n // Create callback server\n const callbackServer = new CallbackServer({ port, timeoutMs })\n\n try {\n // Start waiting for callback (this starts the server and captures actual port)\n const callbackPromise = callbackServer.waitForCallback(state)\n\n // Wait a bit for server to start and determine actual port\n await new Promise((resolve) => setTimeout(resolve, 100))\n\n // Get the actual port (may differ from preferred if that was in use)\n const actualPort = callbackServer.getActualPort()\n\n // Build redirect URI with actual port\n const actualRedirectUri = redirectUri.replace(/:\\d+/, `:${actualPort}`)\n\n // Build authorization URL\n const authUrl = buildAuthorizationUrl({\n authorizationUrl: OAUTH_CONFIG.authorizationUrl,\n clientId,\n codeChallenge,\n codeChallengeMethod,\n redirectUri: actualRedirectUri,\n scopes,\n state,\n })\n\n // Prompt user to open browser\n const shouldOpenBrowser = await p.confirm({\n initialValue: true,\n message: 'Log in or create Figma account in your browser?',\n })\n\n if (p.isCancel(shouldOpenBrowser)) {\n throw new OAuthFlowError('Authentication cancelled by user')\n }\n\n if (shouldOpenBrowser) {\n // Try to open browser, but don't fail if it doesn't work\n try {\n await openBrowser(authUrl)\n } catch (_error) {\n // Browser opening failed, show URL for manual opening\n log.warning('Could not open browser automatically.')\n log.info(`Please open this URL in your browser:`)\n log.info(` ${authUrl}`)\n }\n } else {\n // User declined automatic opening, show URL\n log.info(`Please open this URL manually in your browser:`)\n log.info(` ${authUrl}`)\n }\n\n // Wait for callback\n const { code } = await callbackPromise\n\n // Exchange authorization code for tokens\n let tokens: FigmaTokens\n try {\n tokens = await exchangeCodeForTokens(code, codeVerifier, actualRedirectUri, clientId)\n } catch (error) {\n throw new OAuthFlowError(\n 'Failed to exchange authorization code for tokens',\n error instanceof Error ? error : undefined,\n )\n }\n\n // Store tokens\n try {\n tokenStore.setTokens(tokens)\n } catch (error) {\n throw new OAuthFlowError('Failed to store tokens', error instanceof Error ? error : undefined)\n }\n\n return {\n tokens,\n userId: tokens.userId,\n }\n } catch (error) {\n // Clean up server on error\n callbackServer.stop()\n\n if (error instanceof OAuthFlowError) {\n throw error\n }\n\n throw new OAuthFlowError(\n `OAuth flow failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error instanceof Error ? error : undefined,\n )\n } finally {\n // Ensure server is always stopped\n callbackServer.stop()\n }\n}\n\n/**\n * Get valid access token, refreshing if necessary\n *\n * Checks if stored tokens exist and are valid. If expired, automatically\n * refreshes using the refresh token. If no tokens exist, returns null.\n *\n * @param tokenStore - Token store to use\n * @returns Promise resolving to access token or null if no valid tokens\n * @throws OAuthFlowError if refresh fails\n */\nexport async function getValidAccessToken(tokenStore: TokenStore): Promise<null | string> {\n // Check if we have valid tokens\n if (tokenStore.hasValidTokens()) {\n return tokenStore.getAccessToken()\n }\n\n // Check if we have a refresh token\n const refreshToken = tokenStore.getRefreshToken()\n if (!refreshToken) {\n return null\n }\n\n // Try to refresh\n try {\n const tokens = await refreshAccessToken(refreshToken)\n tokenStore.setTokens(tokens)\n return tokens.accessToken\n } catch (error) {\n // Refresh failed - clear invalid tokens\n tokenStore.clearTokens()\n throw new OAuthFlowError(\n 'Failed to refresh access token',\n error instanceof Error ? error : undefined,\n )\n }\n}\n"],"names":["p","crypto","OAUTH_CONFIG","log","buildAuthorizationUrl","openBrowser","CallbackServer","generatePKCEPair","exchangeCodeForTokens","refreshAccessToken","OAuthFlowError","Error","message","cause","name","executeOAuthFlow","tokenStore","options","shouldMock","process","env","FIGMA_MOCK_OAUTH","debug","mockTokens","accessToken","randomBytes","toString","expiresAt","Date","now","refreshToken","scopes","tokenType","setTokens","tokens","userId","clientId","port","redirectUri","timeoutMs","codeChallenge","codeChallengeMethod","codeVerifier","state","callbackServer","callbackPromise","waitForCallback","Promise","resolve","setTimeout","actualPort","getActualPort","actualRedirectUri","replace","authUrl","authorizationUrl","shouldOpenBrowser","confirm","initialValue","isCancel","_error","warning","info","code","error","undefined","stop","getValidAccessToken","hasValidTokens","getAccessToken","getRefreshToken","clearTokens"],"mappings":"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"}
|
package/dist/auth/pkce.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"pkce.d.ts","sourceRoot":"","sources":["../../src/auth/pkce.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,WAAW,QAAQ;IACvB,mEAAmE;IACnE,aAAa,EAAE,MAAM,CAAA;IACrB,gDAAgD;IAChD,mBAAmB,EAAE,MAAM,CAAA;IAC3B,gFAAgF;IAChF,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAK7C;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAG9D;AAED;;;;;;;;;;;;;;;GAeG;AACH,wBAAgB,gBAAgB,IAAI,QAAQ,CAS3C"}
|
package/dist/auth/pkce.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/pkce.ts"],"sourcesContent":["import crypto from 'crypto'\n\n/**\n * PKCE code verifier and challenge pair\n * @see https://datatracker.ietf.org/doc/html/rfc7636\n */\nexport interface PKCEPair {\n /** SHA256 hash of verifier, base64url encoded (without padding) */\n codeChallenge: string\n /** Challenge method (always S256 for SHA256) */\n codeChallengeMethod: 'S256'\n /** Random code verifier (43-128 characters from [A-Z, a-z, 0-9, -, ., _, ~]) */\n codeVerifier: string\n}\n\n/**\n * Generate a cryptographically random PKCE code verifier\n *\n * Creates a high-entropy random string suitable for use as an OAuth 2.0 PKCE code verifier.\n * The verifier must be 43-128 characters and use only [A-Z, a-z, 0-9, -, ., _, ~].\n *\n * @returns Random code verifier string (43 characters from 32 random bytes)\n * @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.1\n */\nexport function generateCodeVerifier(): string {\n // Generate 32 random bytes (256 bits of entropy)\n // This will produce a 43-character base64url string\n const buffer = crypto.randomBytes(32)\n return base64UrlEncode(buffer)\n}\n\n/**\n * Generate code challenge from verifier using S256 method\n *\n * Creates a SHA256 hash of the code verifier and encodes it in base64url format.\n * Formula: challenge = BASE64URL(SHA256(ASCII(code_verifier)))\n *\n * @param verifier - The code verifier to hash\n * @returns Code challenge string (43 characters)\n * @see https://datatracker.ietf.org/doc/html/rfc7636#section-4.2\n */\nexport function generateCodeChallenge(verifier: string): string {\n const hash = crypto.createHash('sha256').update(verifier).digest()\n return base64UrlEncode(hash)\n}\n\n/**\n * Generate complete PKCE pair for OAuth flow\n *\n * Creates both a code verifier and its corresponding code challenge.\n * Use this at the start of an OAuth flow:\n * 1. Generate pair\n * 2. Store verifier securely (needed for token exchange)\n * 3. Send challenge in authorization request\n * 4. Send verifier in token exchange request\n *\n * @returns Complete PKCE pair with verifier, challenge, and method\n * @example\n * const { codeVerifier, codeChallenge, codeChallengeMethod } = generatePKCEPair()\n * // Store codeVerifier for later\n * // Include codeChallenge and codeChallengeMethod in authorization URL\n */\nexport function generatePKCEPair(): PKCEPair {\n const codeVerifier = generateCodeVerifier()\n const codeChallenge = generateCodeChallenge(codeVerifier)\n\n return {\n codeChallenge,\n codeChallengeMethod: 'S256',\n codeVerifier,\n }\n}\n\n/**\n * Base64URL encode without padding (RFC 7636 requirement)\n *\n * Converts a buffer to base64url format by:\n * 1. Base64 encoding\n * 2. Replacing + with -\n * 3. Replacing / with _\n * 4. Removing = padding\n *\n * This format is URL-safe and required by OAuth 2.0 PKCE spec.\n *\n * @param buffer - Buffer to encode\n * @returns Base64url encoded string (no padding)\n * @see https://datatracker.ietf.org/doc/html/rfc7636#appendix-A\n */\nfunction base64UrlEncode(buffer: Buffer): string {\n return buffer.toString('base64').replace(/\\+/g, '-').replace(/\\//g, '_').replace(/=/g, '')\n}\n"],"names":["crypto","generateCodeVerifier","buffer","randomBytes","base64UrlEncode","generateCodeChallenge","verifier","hash","createHash","update","digest","generatePKCEPair","codeVerifier","codeChallenge","codeChallengeMethod","toString","replace"],"mappings":"AAAA,OAAOA,YAAY,SAAQ;AAe3B;;;;;;;;CAQC,GACD,OAAO,SAASC;IACd,iDAAiD;IACjD,oDAAoD;IACpD,MAAMC,SAASF,OAAOG,WAAW,CAAC;IAClC,OAAOC,gBAAgBF;AACzB;AAEA;;;;;;;;;CASC,GACD,OAAO,SAASG,sBAAsBC,QAAgB;IACpD,MAAMC,OAAOP,OAAOQ,UAAU,CAAC,UAAUC,MAAM,CAACH,UAAUI,MAAM;IAChE,OAAON,gBAAgBG;AACzB;AAEA;;;;;;;;;;;;;;;CAeC,GACD,OAAO,SAASI;IACd,MAAMC,eAAeX;IACrB,MAAMY,gBAAgBR,sBAAsBO;IAE5C,OAAO;QACLC;QACAC,qBAAqB;QACrBF;IACF;AACF;AAEA;;;;;;;;;;;;;;CAcC,GACD,SAASR,gBAAgBF,MAAc;IACrC,OAAOA,OAAOa,QAAQ,CAAC,UAAUC,OAAO,CAAC,OAAO,KAAKA,OAAO,CAAC,OAAO,KAAKA,OAAO,CAAC,MAAM;AACzF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"project-token.d.ts","sourceRoot":"","sources":["../../src/auth/project-token.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAA;AASlD;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAGjC,KAAK,CAAC,EAAE,KAAK;gBADpB,OAAO,EAAE,MAAM,EACR,KAAK,CAAC,EAAE,KAAK,YAAA;CAKvB;AAkCD;;;;;;;;;;;;;;;;;GAiBG;AACH,wBAAsB,oBAAoB,CACxC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAiExB;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,mBAAmB,CACvC,UAAU,EAAE,UAAU,EACtB,QAAQ,EAAE,MAAM,GACf,OAAO,CAAC,IAAI,GAAG,MAAM,CAAC,CAMxB"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/project-token.ts"],"sourcesContent":["/**\n * Project Token Management\n *\n * Handles project token (JWT) generation and refresh for authenticating\n * to the Content API. Project tokens are scoped to a specific tenant/CMS\n * and have a shorter lifespan (15-30 minutes) than OAuth tokens.\n */\n\nimport type { TokenStore } from './token-store.js'\nimport type { JWTPayload } from './types.js'\n\nimport { getProjectToken as fetchProjectToken } from '../api/figma-api.js'\nimport { getEnvironment } from '../constants.js'\nimport * as log from '../utils/log.js'\nimport { JWTValidationError, validateProjectToken } from './jwt-validator.js'\nimport { getValidAccessToken } from './oauth-flow.js'\n\n/**\n * Error during project token operations\n */\nexport class ProjectTokenError extends Error {\n constructor(\n message: string,\n public cause?: Error,\n ) {\n super(message)\n this.name = 'ProjectTokenError'\n }\n}\n\n/**\n * Parse JWT claims from token without validation\n * Used for mock tokens where signature validation is not needed\n *\n * @param token - JWT token string\n * @returns Parsed JWT payload\n * @throws {ProjectTokenError} If JWT cannot be parsed\n */\nfunction parseJWTClaims(token: string): JWTPayload {\n try {\n // JWT format: header.payload.signature\n const parts = token.split('.')\n if (parts.length !== 3) {\n throw new Error('Invalid JWT format')\n }\n\n // Decode the payload (second part)\n const payload = parts[1]\n const base64 = payload.replace(/-/g, '+').replace(/_/g, '/')\n const paddedBase64 = base64.padEnd(base64.length + ((4 - (base64.length % 4)) % 4), '=')\n\n const decodedPayload = JSON.parse(Buffer.from(paddedBase64, 'base64').toString('utf-8'))\n\n return decodedPayload as JWTPayload\n } catch (error) {\n throw new ProjectTokenError(\n `Failed to parse JWT claims: ${error instanceof Error ? error.message : 'Unknown error'}`,\n error instanceof Error ? error : undefined,\n )\n }\n}\n\n/**\n * Get a valid project token for a tenant, refreshing if necessary\n *\n * This function:\n * 1. Checks if a stored project token exists and is valid (not expired)\n * 2. If expired or missing, gets a valid user access token\n * 3. Calls the Figma API to generate a new project token\n * 4. Stores the new project token in encrypted storage\n * 5. Returns the JWT string\n *\n * The project token is used by local Payload instances to authenticate\n * requests to the Content API without requiring a round-trip to Sinatra.\n *\n * @param tokenStore - Token store for persisting tokens\n * @param tenantId - The tenant/CMS ID to get a token for\n * @returns Promise resolving to JWT token string or null if failed\n * @throws {ProjectTokenError} If token generation fails\n */\nexport async function getValidProjectToken(\n tokenStore: TokenStore,\n tenantId: string,\n): Promise<null | string> {\n // Check if we have a valid project token already\n if (tokenStore.hasValidProjectToken(tenantId)) {\n const projectToken = tokenStore.getProjectToken(tenantId)\n return projectToken?.token || null\n }\n\n // We need to refresh the project token\n // First, get a valid user access token (will auto-refresh if needed)\n let accessToken: null | string\n try {\n accessToken = await getValidAccessToken(tokenStore)\n } catch (error) {\n throw new ProjectTokenError(\n 'Failed to get valid access token for project token refresh',\n error instanceof Error ? error : undefined,\n )\n }\n\n if (!accessToken) {\n // No valid user tokens available - user needs to authenticate\n return null\n }\n\n // Fetch a new project token from the Figma API\n const projectToken = await fetchProjectToken(accessToken, tenantId)\n\n // Validate the JWT signature and claims (skip for mocks)\n const shouldMock = process.env.FIGMA_MOCK_PROJECT_TOKEN !== 'false'\n let validatedClaims: JWTPayload\n\n if (shouldMock) {\n // MOCK: Skip JWT validation and parse claims directly\n log.debug('Skipping JWT validation for mock project token')\n validatedClaims = parseJWTClaims(projectToken.token)\n } else {\n // REAL: Validate JWT signature against JWKS\n try {\n validatedClaims = await validateProjectToken(projectToken.token, getEnvironment())\n } catch (validationError) {\n // Handle validation errors\n if (validationError instanceof JWTValidationError) {\n throw new ProjectTokenError(\n `Project token validation failed: ${validationError.message}`,\n validationError,\n )\n }\n throw validationError\n }\n }\n\n // Ensure exp claim is present\n if (!validatedClaims.exp) {\n throw new ProjectTokenError('Project token missing expiration (exp) claim')\n }\n\n // Store the project token with validated expiration and claims\n tokenStore.setProjectToken(tenantId, {\n claims: validatedClaims,\n expiresAt: validatedClaims.exp * 1000, // Convert from seconds to milliseconds\n tenantId,\n token: projectToken.token,\n })\n\n return projectToken.token\n}\n\n/**\n * Refresh a project token for a tenant\n *\n * Forces a refresh of the project token even if the current one is still valid.\n * Useful for testing or when you want to ensure you have the freshest token.\n *\n * @param tokenStore - Token store for persisting tokens\n * @param tenantId - The tenant/CMS ID to refresh token for\n * @returns Promise resolving to JWT token string or null if failed\n * @throws {ProjectTokenError} If token refresh fails\n */\nexport async function refreshProjectToken(\n tokenStore: TokenStore,\n tenantId: string,\n): Promise<null | string> {\n // Clear the existing project token to force a refresh\n tokenStore.clearProjectToken(tenantId)\n\n // Get a new token (which will fetch from API since we just cleared it)\n return getValidProjectToken(tokenStore, tenantId)\n}\n"],"names":["getProjectToken","fetchProjectToken","getEnvironment","log","JWTValidationError","validateProjectToken","getValidAccessToken","ProjectTokenError","Error","message","cause","name","parseJWTClaims","token","parts","split","length","payload","base64","replace","paddedBase64","padEnd","decodedPayload","JSON","parse","Buffer","from","toString","error","undefined","getValidProjectToken","tokenStore","tenantId","hasValidProjectToken","projectToken","accessToken","shouldMock","process","env","FIGMA_MOCK_PROJECT_TOKEN","validatedClaims","debug","validationError","exp","setProjectToken","claims","expiresAt","refreshProjectToken","clearProjectToken"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"refresh.d.ts","sourceRoot":"","sources":["../../src/auth/refresh.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAsB,WAAW,EAAE,MAAM,YAAY,CAAA;AAKjE;;GAEG;AACH,qBAAa,iBAAkB,SAAQ,KAAK;IAGjC,UAAU,CAAC,EAAE,MAAM;gBAD1B,OAAO,EAAE,MAAM,EACR,UAAU,CAAC,EAAE,MAAM,YAAA;CAK7B;AAED;;;;;;;;;;GAUG;AACH,wBAAsB,kBAAkB,CACtC,YAAY,EAAE,MAAM,EACpB,QAAQ,GAAE,MAA8B,GACvC,OAAO,CAAC,WAAW,CAAC,CAmDtB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,MAAM,EACZ,YAAY,EAAE,MAAM,EACpB,WAAW,GAAE,MAAiC,EAC9C,QAAQ,GAAE,MAA8B,GACvC,OAAO,CAAC,WAAW,CAAC,CAuFtB"}
|
package/dist/auth/refresh.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/refresh.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-objects */\nimport type { FigmaTokenResponse, FigmaTokens } from './types.js'\n\nimport { OAUTH_CONFIG } from '../config/oauth.js'\nimport * as log from '../utils/log.js'\n\n/**\n * Error thrown when token refresh fails\n */\nexport class TokenRefreshError extends Error {\n constructor(\n message: string,\n public statusCode?: number,\n ) {\n super(message)\n this.name = 'TokenRefreshError'\n }\n}\n\n/**\n * Refresh an expired OAuth2 access token using a refresh token\n *\n * Makes a POST request to Figma's token endpoint with the refresh token\n * to obtain a new access token. Uses public client pattern (no client secret).\n *\n * @param refreshToken - The refresh token to use\n * @param clientId - OAuth2 client ID (defaults to config)\n * @returns Promise resolving to new tokens\n * @throws TokenRefreshError if refresh fails\n */\nexport async function refreshAccessToken(\n refreshToken: string,\n clientId: string = OAUTH_CONFIG.clientId,\n): Promise<FigmaTokens> {\n // Prepare form data for token refresh request (public client)\n const params = new URLSearchParams({\n client_id: clientId,\n grant_type: 'refresh_token',\n refresh_token: refreshToken,\n })\n\n try {\n const response = await fetch(OAUTH_CONFIG.refreshUrl, {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/x-www-form-urlencoded',\n },\n body: params.toString(),\n })\n\n if (!response.ok) {\n const errorText = await response.text()\n throw new TokenRefreshError(\n `Token refresh failed: ${response.statusText}. ${errorText}`,\n response.status,\n )\n }\n\n const data = (await response.json()) as FigmaTokenResponse\n\n // Validate response contains required fields\n if (!data.access_token || !data.refresh_token || !data.expires_in) {\n throw new TokenRefreshError('Invalid token response: missing required fields')\n }\n\n // Convert response to our internal token format\n const expiresAt = Date.now() + data.expires_in * 1000\n\n return {\n accessToken: data.access_token,\n refreshToken: data.refresh_token,\n expiresAt,\n userId: data.user_id_string,\n }\n } catch (error) {\n if (error instanceof TokenRefreshError) {\n throw error\n }\n\n // Handle network errors and other exceptions\n throw new TokenRefreshError(\n `Failed to refresh token: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n}\n\n/**\n * Exchange an authorization code for OAuth2 tokens\n *\n * This is used during the initial OAuth flow after the user authorizes the app.\n * Uses public client pattern with PKCE (code verifier is required).\n *\n * @param code - Authorization code from OAuth callback\n * @param codeVerifier - PKCE code verifier (required for public clients)\n * @param redirectUri - Redirect URI used in the authorization request\n * @param clientId - OAuth2 client ID (defaults to config)\n * @returns Promise resolving to tokens\n * @throws TokenRefreshError if exchange fails\n */\nexport async function exchangeCodeForTokens(\n code: string,\n codeVerifier: string,\n redirectUri: string = OAUTH_CONFIG.redirectUri,\n clientId: string = OAUTH_CONFIG.clientId,\n): Promise<FigmaTokens> {\n // Prepare form data for token exchange (public client with PKCE)\n const params = new URLSearchParams({\n client_id: clientId,\n code,\n code_verifier: codeVerifier,\n grant_type: 'authorization_code',\n redirect_uri: redirectUri,\n })\n\n try {\n // Public client - no client secret or Basic Auth header needed\n // Security is provided by PKCE (code_verifier in the request body)\n const headers: Record<string, string> = {\n 'Content-Type': 'application/x-www-form-urlencoded',\n }\n\n // Debug logging\n log.debug(\n `Token exchange request: ${JSON.stringify({\n url: OAUTH_CONFIG.tokenUrl,\n headers,\n body: params.toString(),\n })}`,\n )\n\n const response = await fetch(OAUTH_CONFIG.tokenUrl, {\n method: 'POST',\n headers,\n body: params.toString(),\n })\n\n log.debug(\n `Token exchange response: ${JSON.stringify({\n status: response.status,\n statusText: response.statusText,\n headers: Object.fromEntries(response.headers.entries()),\n })}`,\n )\n\n if (!response.ok) {\n const errorText = await response.text()\n log.debug(`Error response body: ${errorText}`)\n\n throw new TokenRefreshError(\n `Token exchange failed: ${response.statusText}. ${errorText}`,\n response.status,\n )\n }\n\n const data = (await response.json()) as FigmaTokenResponse\n\n log.debug(\n `Token response: ${JSON.stringify({\n access_token: data.access_token,\n token_type: data.token_type,\n expires_in: data.expires_in,\n scope: data.scope,\n user_id_string: data.user_id_string,\n refresh_token: data.refresh_token?.substring(0, 10) + '...',\n })}`,\n )\n\n // Validate response contains required fields\n if (!data.access_token || !data.refresh_token || !data.expires_in) {\n throw new TokenRefreshError('Invalid token response: missing required fields')\n }\n\n // Convert response to our internal token format\n const expiresAt = Date.now() + data.expires_in * 1000\n\n return {\n accessToken: data.access_token,\n refreshToken: data.refresh_token,\n expiresAt,\n userId: data.user_id_string,\n }\n } catch (error) {\n if (error instanceof TokenRefreshError) {\n throw error\n }\n\n // Handle network errors and other exceptions\n throw new TokenRefreshError(\n `Failed to exchange code for tokens: ${error instanceof Error ? error.message : 'Unknown error'}`,\n )\n }\n}\n"],"names":["OAUTH_CONFIG","log","TokenRefreshError","Error","message","statusCode","name","refreshAccessToken","refreshToken","clientId","params","URLSearchParams","client_id","grant_type","refresh_token","response","fetch","refreshUrl","method","headers","body","toString","ok","errorText","text","statusText","status","data","json","access_token","expires_in","expiresAt","Date","now","accessToken","userId","user_id_string","error","exchangeCodeForTokens","code","codeVerifier","redirectUri","code_verifier","redirect_uri","debug","JSON","stringify","url","tokenUrl","Object","fromEntries","entries","token_type","scope","substring"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-store.d.ts","sourceRoot":"","sources":["../../src/auth/token-store.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,YAAY,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAA;AAKzF;;;;;;;;;;GAUG;AACH,qBAAa,UAAU;IACrB,OAAO,CAAC,MAAM,CAA4E;gBAE9E,OAAO,CAAC,EAAE,gBAAgB;IAWtC;;;OAGG;IACH,SAAS,IAAI,WAAW,GAAG,IAAI;IAK/B;;;OAGG;IACH,SAAS,CAAC,MAAM,EAAE,WAAW,GAAG,IAAI;IAIpC;;OAEG;IACH,WAAW,IAAI,IAAI;IAInB;;;OAGG;IACH,cAAc,IAAI,OAAO;IAQzB;;;;OAIG;IACH,SAAS,IAAI,OAAO;IAcpB;;;OAGG;IACH,cAAc,IAAI,IAAI,GAAG,MAAM;IAQ/B;;;OAGG;IACH,eAAe,IAAI,IAAI,GAAG,MAAM;IAKhC;;;;;OAKG;IACH,iBAAiB,CAAC,WAAW,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,IAAI;IAe/D;;;OAGG;IACH,cAAc,IAAI,MAAM;IAIxB;;;;;OAKG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI,GAAG,YAAY;IAiBtD;;;;OAIG;IACH,eAAe,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,YAAY,GAAG,IAAI;IAMnE;;;OAGG;IACH,iBAAiB,CAAC,QAAQ,EAAE,MAAM,GAAG,IAAI;IAMzC;;OAEG;IACH,qBAAqB,IAAI,IAAI;IAI7B;;;;;OAKG;IACH,qBAAqB,CAAC,YAAY,EAAE,YAAY,GAAG,OAAO;IAQ1D;;;;OAIG;IACH,oBAAoB,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAQ/C;;;;OAIG;IACH,qBAAqB,CAAC,QAAQ,EAAE,MAAM,GAAG,UAAU,GAAG,IAAI;IAK1D;;;OAGG;IACH,2BAA2B,IAAI,MAAM,EAAE;CAIxC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/token-store.ts"],"sourcesContent":["/* eslint-disable perfectionist/sort-classes */\nimport Conf from 'conf'\n\nimport type { FigmaTokens, JWTPayload, ProjectToken, TokenStoreConfig } from './types.js'\n\nimport { TOKEN_EXPIRY_BUFFER_SECONDS } from '../config/oauth.js'\nimport { deriveEncryptionKey } from './crypto-utils.js'\n\n/**\n * Secure storage manager for Figma OAuth2 tokens\n *\n * Uses the `conf` library to store tokens in an OS-specific secure location:\n * - macOS: ~/Library/Preferences/payloadcms-figma\n * - Linux: ~/.config/payloadcms-figma or $XDG_CONFIG_HOME/payloadcms-figma\n * - Windows: %APPDATA%/payloadcms-figma/Config\n *\n * Tokens are encrypted at rest with a machine-specific key and file permissions\n * are set to 0600 (owner read/write only)\n */\nexport class TokenStore {\n private config: Conf<{ projectTokens: Record<string, ProjectToken>; tokens: FigmaTokens }>\n\n constructor(options?: TokenStoreConfig) {\n this.config = new Conf<{ projectTokens: Record<string, ProjectToken>; tokens: FigmaTokens }>({\n configName: options?.configName || 'payloadcms-figma',\n projectName: 'payloadcms-figma',\n // Enable encryption with machine-specific key for better security\n encryptionKey: options?.encryptionKey || deriveEncryptionKey(),\n // Clear schema to avoid validation issues\n clearInvalidConfig: true,\n })\n }\n\n /**\n * Retrieve stored tokens\n * @returns FigmaTokens if stored, null otherwise\n */\n getTokens(): FigmaTokens | null {\n const tokens = this.config.get('tokens')\n return tokens || null\n }\n\n /**\n * Store OAuth2 tokens securely\n * @param tokens - Figma OAuth2 tokens to store\n */\n setTokens(tokens: FigmaTokens): void {\n this.config.set('tokens', tokens)\n }\n\n /**\n * Clear all stored tokens (used for logout)\n */\n clearTokens(): void {\n this.config.delete('tokens')\n }\n\n /**\n * Check if valid (non-expired) tokens exist\n * @returns true if tokens exist and are not expired\n */\n hasValidTokens(): boolean {\n const tokens = this.getTokens()\n if (!tokens) {\n return false\n }\n return !this.isExpired()\n }\n\n /**\n * Check if the current access token is expired\n * Includes a buffer time to avoid using tokens that are about to expire\n * @returns true if token is expired or will expire within buffer time\n */\n isExpired(): boolean {\n // Access config directly to avoid circular dependency with getTokens()\n const tokens = this.config.get('tokens')\n if (!tokens) {\n return true\n }\n\n const now = Date.now()\n const bufferMs = TOKEN_EXPIRY_BUFFER_SECONDS * 1000\n const expiryWithBuffer = tokens.expiresAt - bufferMs\n\n return now >= expiryWithBuffer\n }\n\n /**\n * Get the access token if it exists and is valid\n * @returns Access token string or null if expired/missing\n */\n getAccessToken(): null | string {\n if (!this.hasValidTokens()) {\n return null\n }\n const tokens = this.getTokens()\n return tokens?.accessToken || null\n }\n\n /**\n * Get the refresh token if it exists\n * @returns Refresh token string or null if missing\n */\n getRefreshToken(): null | string {\n const tokens = this.getTokens()\n return tokens?.refreshToken || null\n }\n\n /**\n * Update just the access token after a refresh\n * Preserves the existing refresh token and other metadata\n * @param accessToken - New access token\n * @param expiresIn - Expiration time in seconds\n */\n updateAccessToken(accessToken: string, expiresIn: number): void {\n const existingTokens = this.getTokens()\n if (!existingTokens) {\n throw new Error('Cannot update access token: no existing tokens found')\n }\n\n const expiresAt = Date.now() + expiresIn * 1000\n\n this.setTokens({\n ...existingTokens,\n accessToken,\n expiresAt,\n })\n }\n\n /**\n * Get the path to the config file (useful for debugging)\n * @returns Absolute path to the token storage file\n */\n getStoragePath(): string {\n return this.config.path\n }\n\n /**\n * Retrieve a project token for a specific tenant\n * Automatically removes expired tokens from storage\n * @param tenantId - The tenant/CMS ID\n * @returns ProjectToken if stored and valid, null otherwise\n */\n getProjectToken(tenantId: string): null | ProjectToken {\n const projectTokens = this.config.get('projectTokens') || {}\n const projectToken = projectTokens[tenantId]\n\n if (!projectToken) {\n return null\n }\n\n // Auto-cleanup expired project token\n if (this.isProjectTokenExpired(projectToken)) {\n this.clearProjectToken(tenantId)\n return null\n }\n\n return projectToken\n }\n\n /**\n * Store a project token for a specific tenant\n * @param tenantId - The tenant/CMS ID\n * @param projectToken - The project token to store\n */\n setProjectToken(tenantId: string, projectToken: ProjectToken): void {\n const projectTokens = this.config.get('projectTokens') || {}\n projectTokens[tenantId] = projectToken\n this.config.set('projectTokens', projectTokens)\n }\n\n /**\n * Clear a project token for a specific tenant\n * @param tenantId - The tenant/CMS ID\n */\n clearProjectToken(tenantId: string): void {\n const projectTokens = this.config.get('projectTokens') || {}\n delete projectTokens[tenantId]\n this.config.set('projectTokens', projectTokens)\n }\n\n /**\n * Clear all project tokens\n */\n clearAllProjectTokens(): void {\n this.config.delete('projectTokens')\n }\n\n /**\n * Check if a project token is expired\n * Includes a buffer time to avoid using tokens that are about to expire\n * @param projectToken - The project token to check\n * @returns true if token is expired or will expire within buffer time\n */\n isProjectTokenExpired(projectToken: ProjectToken): boolean {\n const now = Date.now()\n const bufferMs = TOKEN_EXPIRY_BUFFER_SECONDS * 1000\n const expiryWithBuffer = projectToken.expiresAt - bufferMs\n\n return now >= expiryWithBuffer\n }\n\n /**\n * Check if a valid (non-expired) project token exists for a tenant\n * @param tenantId - The tenant/CMS ID\n * @returns true if token exists and is not expired\n */\n hasValidProjectToken(tenantId: string): boolean {\n const projectToken = this.getProjectToken(tenantId)\n if (!projectToken) {\n return false\n }\n return !this.isProjectTokenExpired(projectToken)\n }\n\n /**\n * Get validated JWT claims from a project token\n * @param tenantId - The tenant/CMS ID\n * @returns JWT payload claims or null if token not found or has no claims\n */\n getProjectTokenClaims(tenantId: string): JWTPayload | null {\n const projectToken = this.getProjectToken(tenantId)\n return projectToken?.claims || null\n }\n\n /**\n * Get all tenant IDs that have stored project tokens\n * @returns Array of tenant IDs\n */\n getAllProjectTokenTenantIds(): string[] {\n const projectTokens = this.config.get('projectTokens') || {}\n return Object.keys(projectTokens)\n }\n}\n"],"names":["Conf","TOKEN_EXPIRY_BUFFER_SECONDS","deriveEncryptionKey","TokenStore","config","options","configName","projectName","encryptionKey","clearInvalidConfig","getTokens","tokens","get","setTokens","set","clearTokens","delete","hasValidTokens","isExpired","now","Date","bufferMs","expiryWithBuffer","expiresAt","getAccessToken","accessToken","getRefreshToken","refreshToken","updateAccessToken","expiresIn","existingTokens","Error","getStoragePath","path","getProjectToken","tenantId","projectTokens","projectToken","isProjectTokenExpired","clearProjectToken","setProjectToken","clearAllProjectTokens","hasValidProjectToken","getProjectTokenClaims","claims","getAllProjectTokenTenantIds","Object","keys"],"mappings":"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"}
|
package/dist/auth/types.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/auth/types.ts"],"names":[],"mappings":"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"}
|
package/dist/auth/types.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/auth/types.ts"],"sourcesContent":["import type {\n ErrorResponsePayloadWithErrMessage,\n ErrorResponsePayloadWithErrorBoolean,\n User,\n} from '@figma/rest-api-spec'\nimport type { JWTPayload as JoseJWTPayload } from 'jose'\n\n/**\n * Standard OAuth2 scopes for user-level permissions\n * @see https://www.figma.com/developers/api#oauth2\n */\nexport type FigmaOAuthScope =\n | 'current_user:read' // Read user name, email, profile image\n | 'file_comments:read' // Read file comments\n | 'file_comments:write' // Post/delete comments and reactions\n | 'file_content:read' // Read file contents (nodes, editor type)\n | 'file_dev_resources:read' // Read dev resources\n | 'file_dev_resources:write' // Write dev resources\n | 'file_metadata:read' // Read file metadata\n | 'file_variables:read' // Read variables (Enterprise only)\n | 'file_variables:write' // Write variables (Enterprise only)\n | 'file_versions:read' // Read version history\n | 'files:read' // @deprecated Read files, projects, users\n | 'library_analytics:read' // Read library analytics\n | 'library_assets:read' // Read published components/styles data\n | 'library_content:read' // Read published components/styles\n | 'projects:read' // List projects and files\n | 'team_library_content:read' // Read team published content\n | 'webhooks:read' // Read webhook metadata\n | 'webhooks:write' // Create/manage webhooks\n\n/**\n * Organization-level OAuth2 scopes\n * Requires organization admin permissions\n */\nexport type FigmaOrgOAuthScope = 'org:activity_log_read' // Read organization activity logs\n\n/**\n * All valid Figma OAuth scopes\n */\nexport type FigmaScope = FigmaOAuthScope | FigmaOrgOAuthScope\n\n/**\n * OAuth tokens returned from Figma API (internal format)\n */\nexport interface FigmaTokens {\n /** OAuth2 access token for making authenticated API requests */\n accessToken: string\n /** Unix timestamp (milliseconds) when the access token expires */\n expiresAt: number\n /** OAuth2 refresh token for obtaining new access tokens */\n refreshToken: string\n /** OAuth scopes granted to this token */\n scopes?: FigmaOAuthScope[]\n /** Token type (typically \"Bearer\") */\n tokenType?: string\n /** Figma user ID string */\n userId?: string\n}\n\n/**\n * Raw token response from Figma OAuth2 token endpoint\n * Response from POST https://api.figma.com/v1/oauth/token\n */\nexport interface FigmaTokenResponse {\n /** OAuth2 access token */\n access_token: string\n /** Token expiration time in seconds */\n expires_in: number\n /** OAuth2 refresh token */\n refresh_token: string\n /** Space-separated list of granted scopes */\n scope?: string\n /** Token type (typically \"Bearer\") */\n token_type?: string\n /** Figma user ID string */\n user_id_string?: string\n}\n\n/**\n * OAuth2 error response\n * @see https://datatracker.ietf.org/doc/html/rfc6749#section-5.2\n */\nexport interface OAuthErrorResponse {\n /** Error code */\n error:\n | 'invalid_client'\n | 'invalid_grant'\n | 'invalid_request'\n | 'invalid_scope'\n | 'unauthorized_client'\n | 'unsupported_grant_type'\n /** Human-readable error description */\n error_description?: string\n /** URI with error information */\n error_uri?: string\n}\n\n/**\n * Parameters for OAuth2 authorization URL\n */\nexport interface OAuthAuthorizationParams {\n /** OAuth2 client ID */\n client_id: string\n /** PKCE code challenge (optional but recommended) */\n code_challenge?: string\n /** PKCE code challenge method (must be S256 if using PKCE) */\n code_challenge_method?: 'S256'\n /** Redirect URI for callback */\n redirect_uri: string\n /** Response type (always \"code\" for authorization code flow) */\n response_type: 'code'\n /** Requested scopes (space-separated) */\n scope: string\n /** State parameter for CSRF protection */\n state: string\n}\n\n/**\n * Parameters for OAuth2 token exchange\n */\nexport interface OAuthTokenExchangeParams {\n /** Authorization code from callback */\n code: string\n /** PKCE code verifier (if PKCE was used) */\n code_verifier?: string\n /** Grant type (always \"authorization_code\") */\n grant_type: 'authorization_code'\n /** Redirect URI (must match authorization request) */\n redirect_uri: string\n}\n\n/**\n * Parameters for OAuth2 token refresh\n */\nexport interface OAuthTokenRefreshParams {\n /** Grant type (always \"refresh_token\") */\n grant_type: 'refresh_token'\n /** Refresh token */\n refresh_token: string\n}\n\n/**\n * Configuration for token storage\n */\nexport interface TokenStoreConfig {\n /** Custom config name (defaults to 'payloadcms-figma') */\n configName?: string\n /** Enable encryption (defaults to true) */\n encryptionKey?: string\n}\n\n/**\n * PKCE (Proof Key for Code Exchange) pair for OAuth2 public clients\n * @see https://datatracker.ietf.org/doc/html/rfc7636\n */\nexport interface PKCEPair {\n /** Code challenge derived from code verifier */\n codeChallenge: string\n /** Code challenge method (always S256) */\n codeChallengeMethod: 'S256'\n /** Code verifier - random string used to generate challenge */\n codeVerifier: string\n}\n\n/**\n * OAuth configuration for Figma API (public client with PKCE)\n *\n * This configuration is for a PUBLIC OAuth client that uses PKCE\n * (Proof Key for Code Exchange) instead of a client secret.\n * Public clients (like CLIs) cannot securely store client secrets.\n */\nexport interface OAuthConfig {\n /** Figma OAuth authorization URL */\n authorizationUrl: string\n /** OAuth2 client ID (public client) */\n clientId: string\n /** OAuth2 redirect URI for callback */\n redirectUri: string\n /** Figma OAuth token refresh URL */\n refreshUrl: string\n /** OAuth2 scopes to request */\n scopes: FigmaOAuthScope[]\n /** Figma OAuth token exchange URL */\n tokenUrl: string\n}\n\n/**\n * Re-export Figma's official types for convenience\n */\nexport type { ErrorResponsePayloadWithErrMessage, ErrorResponsePayloadWithErrorBoolean, User }\n\n/**\n * Type alias for Figma API error responses\n * Combines both error response formats from Figma's REST API\n */\nexport type FigmaErrorResponse =\n | ErrorResponsePayloadWithErrMessage\n | ErrorResponsePayloadWithErrorBoolean\n\n/**\n * Figma user information\n * Re-exported from @figma/rest-api-spec\n */\nexport type FigmaUser = User\n\n/**\n * JWT payload structure from Figma project tokens\n * Extends jose's standard JWTPayload with Figma-specific claims\n */\nexport interface JWTPayload extends JoseJWTPayload {\n [key: string]: unknown\n /** User email address */\n email?: string\n /** Tenant/CMS ID this token is scoped to */\n tenant_id?: string\n}\n\n/**\n * Project token (JWT) for authenticating to Content API\n * Used by local Payload instances to make authenticated requests\n */\nexport interface ProjectToken {\n /** Validated JWT claims */\n claims?: JWTPayload\n /** Unix timestamp (milliseconds) when the token expires (from validated exp claim) */\n expiresAt: number\n /** Tenant/CMS ID this token is scoped to */\n tenantId: string\n /** JWT token string signed by Figma API */\n token: string\n}\n\n/**\n * Raw project token response from Figma API\n * Response from GET https://api.figma.com/v1/cms/:id/token/\n */\nexport interface ProjectTokenResponse {\n /** Response metadata containing the JWT token */\n meta: {\n /** JWT token string */\n token: string\n }\n}\n"],"names":[],"mappings":"AAyOA;;;CAGC,GACD,WAMC"}
|
package/dist/cli.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"cli.d.ts","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"AAaA;;GAEG;AACH,wBAAsB,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC,CAS1C"}
|
package/dist/cli.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/cli.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport arg from 'arg'\nimport pc from 'picocolors'\n\nimport type { CliArgs } from './types.js'\n\nimport { deployCommand } from './commands/deploy.js'\nimport { initCommand } from './commands/init.js'\nimport { listTokensCommand } from './commands/list-tokens.js'\nimport { loginCommand } from './commands/login.js'\nimport { logoutCommand } from './commands/logout.js'\nimport { feedbackOutro, helpMessage } from './utils/messages.js'\n\n/**\n * Entrypoint for bin/cli.js\n */\nexport async function main(): Promise<void> {\n try {\n await new Main().init()\n } catch (e) {\n if (e instanceof Error) {\n // eslint-disable-next-line no-console\n console.error(e.message)\n }\n }\n}\n\nclass Main {\n args: CliArgs\n\n constructor() {\n // @ts-expect-error bad typings\n this.args = arg(\n {\n '--debug': Boolean,\n '--force': Boolean,\n '--help': Boolean,\n '--id': String,\n '--name': String,\n '--skip-auth': Boolean,\n '--yes': Boolean,\n\n // Aliases\n '-f': '--force',\n '-h': '--help',\n '-y': '--yes',\n },\n { permissive: true },\n )\n\n // Set debug flag globally\n if (this.args['--debug']) {\n process.env.DEBUG = 'true'\n }\n }\n\n async init(): Promise<void> {\n try {\n if (this.args['--help']) {\n helpMessage()\n process.exit(0)\n }\n\n // Get the subcommand (first non-flag argument)\n const subcommand = this.args._[0]\n\n // eslint-disable-next-line no-console\n console.log('\\n')\n p.intro(pc.bgCyan(pc.black(' @payloadcms/figma ')))\n\n // Route to appropriate command handler\n switch (subcommand) {\n case 'deploy':\n await deployCommand({\n debug: this.args['--debug'],\n yes: this.args['--yes'],\n })\n break\n\n case 'init':\n await initCommand({\n id: this.args['--id'],\n name: this.args['--name'],\n debug: this.args['--debug'],\n force: this.args['--force'],\n skipAuth: this.args['--skip-auth'],\n })\n break\n\n case 'list-tokens':\n listTokensCommand({\n debug: this.args['--debug'],\n })\n break\n\n case 'login':\n await loginCommand()\n break\n\n case 'logout':\n await logoutCommand({\n debug: this.args['--debug'],\n })\n break\n\n case undefined:\n // No subcommand - show default message\n p.note(\"Let's create a new CMS!\")\n p.outro(feedbackOutro())\n break\n\n default:\n p.log.error(pc.red(`Unknown command: ${subcommand}`))\n p.note('Use --help to see available commands', 'Tip')\n process.exit(1)\n }\n\n process.exit(0)\n } catch (err: unknown) {\n // eslint-disable-next-line no-console\n console.error(err instanceof Error ? err.message : 'An error occurred')\n process.exit(1)\n }\n }\n}\n"],"names":["p","arg","pc","deployCommand","initCommand","listTokensCommand","loginCommand","logoutCommand","feedbackOutro","helpMessage","main","Main","init","e","Error","console","error","message","args","Boolean","String","permissive","process","env","DEBUG","exit","subcommand","_","log","intro","bgCyan","black","debug","yes","id","name","force","skipAuth","undefined","note","outro","red","err"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,SAAS,MAAK;AACrB,OAAOC,QAAQ,aAAY;AAI3B,SAASC,aAAa,QAAQ,uBAAsB;AACpD,SAASC,WAAW,QAAQ,qBAAoB;AAChD,SAASC,iBAAiB,QAAQ,4BAA2B;AAC7D,SAASC,YAAY,QAAQ,sBAAqB;AAClD,SAASC,aAAa,QAAQ,uBAAsB;AACpD,SAASC,aAAa,EAAEC,WAAW,QAAQ,sBAAqB;AAEhE;;CAEC,GACD,OAAO,eAAeC;IACpB,IAAI;QACF,MAAM,IAAIC,OAAOC,IAAI;IACvB,EAAE,OAAOC,GAAG;QACV,IAAIA,aAAaC,OAAO;YACtB,sCAAsC;YACtCC,QAAQC,KAAK,CAACH,EAAEI,OAAO;QACzB;IACF;AACF;AAEA,MAAMN;IACJO,KAAa;IAEb,aAAc;QACZ,+BAA+B;QAC/B,IAAI,CAACA,IAAI,GAAGjB,IACV;YACE,WAAWkB;YACX,WAAWA;YACX,UAAUA;YACV,QAAQC;YACR,UAAUA;YACV,eAAeD;YACf,SAASA;YAET,UAAU;YACV,MAAM;YACN,MAAM;YACN,MAAM;QACR,GACA;YAAEE,YAAY;QAAK;QAGrB,0BAA0B;QAC1B,IAAI,IAAI,CAACH,IAAI,CAAC,UAAU,EAAE;YACxBI,QAAQC,GAAG,CAACC,KAAK,GAAG;QACtB;IACF;IAEA,MAAMZ,OAAsB;QAC1B,IAAI;YACF,IAAI,IAAI,CAACM,IAAI,CAAC,SAAS,EAAE;gBACvBT;gBACAa,QAAQG,IAAI,CAAC;YACf;YAEA,+CAA+C;YAC/C,MAAMC,aAAa,IAAI,CAACR,IAAI,CAACS,CAAC,CAAC,EAAE;YAEjC,sCAAsC;YACtCZ,QAAQa,GAAG,CAAC;YACZ5B,EAAE6B,KAAK,CAAC3B,GAAG4B,MAAM,CAAC5B,GAAG6B,KAAK,CAAC;YAE3B,uCAAuC;YACvC,OAAQL;gBACN,KAAK;oBACH,MAAMvB,cAAc;wBAClB6B,OAAO,IAAI,CAACd,IAAI,CAAC,UAAU;wBAC3Be,KAAK,IAAI,CAACf,IAAI,CAAC,QAAQ;oBACzB;oBACA;gBAEF,KAAK;oBACH,MAAMd,YAAY;wBAChB8B,IAAI,IAAI,CAAChB,IAAI,CAAC,OAAO;wBACrBiB,MAAM,IAAI,CAACjB,IAAI,CAAC,SAAS;wBACzBc,OAAO,IAAI,CAACd,IAAI,CAAC,UAAU;wBAC3BkB,OAAO,IAAI,CAAClB,IAAI,CAAC,UAAU;wBAC3BmB,UAAU,IAAI,CAACnB,IAAI,CAAC,cAAc;oBACpC;oBACA;gBAEF,KAAK;oBACHb,kBAAkB;wBAChB2B,OAAO,IAAI,CAACd,IAAI,CAAC,UAAU;oBAC7B;oBACA;gBAEF,KAAK;oBACH,MAAMZ;oBACN;gBAEF,KAAK;oBACH,MAAMC,cAAc;wBAClByB,OAAO,IAAI,CAACd,IAAI,CAAC,UAAU;oBAC7B;oBACA;gBAEF,KAAKoB;oBACH,uCAAuC;oBACvCtC,EAAEuC,IAAI,CAAC;oBACPvC,EAAEwC,KAAK,CAAChC;oBACR;gBAEF;oBACER,EAAE4B,GAAG,CAACZ,KAAK,CAACd,GAAGuC,GAAG,CAAC,CAAC,iBAAiB,EAAEf,YAAY;oBACnD1B,EAAEuC,IAAI,CAAC,wCAAwC;oBAC/CjB,QAAQG,IAAI,CAAC;YACjB;YAEAH,QAAQG,IAAI,CAAC;QACf,EAAE,OAAOiB,KAAc;YACrB,sCAAsC;YACtC3B,QAAQC,KAAK,CAAC0B,eAAe5B,QAAQ4B,IAAIzB,OAAO,GAAG;YACnDK,QAAQG,IAAI,CAAC;QACf;IACF;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"deploy.d.ts","sourceRoot":"","sources":["../../src/commands/deploy.ts"],"names":[],"mappings":"AAoBA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,wBAAwB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,gCAAgC;IAChC,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AA6BD;;;;GAIG;AACH,wBAAsB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,OAAO,CAAC,IAAI,CAAC,CAyThF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/deploy.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport { spawn } from 'child_process'\nimport path from 'path'\nimport pc from 'picocolors'\nimport { Project } from 'ts-morph'\n\nimport { createDeployment, getTenantDetails, performDeployment } from '../api/control-plane.js'\nimport { getValidAccessToken } from '../auth/oauth-flow.js'\nimport { getValidProjectToken } from '../auth/project-token.js'\nimport { TokenStore } from '../auth/token-store.js'\nimport { collectStaticAssets, createLambdaZip, getFileSize } from '../utils/asset-collection.js'\nimport { detectBuild, getBuildCommand } from '../utils/build-detection.js'\nimport * as log from '../utils/log.js'\nimport { getPackageManager } from '../utils/package-manager.js'\nimport { readFigmaConfig } from '../utils/payload-config-ast.js'\nimport { findPayloadConfig } from '../utils/payload-config-finder.js'\nimport { isInProjectDirectory } from '../utils/project.js'\nimport { uploadLambdaZip, uploadStaticAssets } from '../utils/s3-upload.js'\nimport { loginCommand } from './login.js'\n\n/**\n * Options for deploy command\n */\nexport interface DeployCommandOptions {\n /** Enable debug mode */\n debug?: boolean\n /** Skip confirmation prompts */\n yes?: boolean\n}\n\n/**\n * Format bytes to human-readable string\n */\nfunction formatBytes(bytes: number): string {\n if (bytes === 0) {\n return '0 B'\n }\n const k = 1024\n const sizes = ['B', 'KB', 'MB', 'GB']\n const i = Math.floor(Math.log(bytes) / Math.log(k))\n return `${parseFloat((bytes / Math.pow(k, i)).toFixed(2))} ${sizes[i]}`\n}\n\n/**\n * Format date to human-readable string in local time\n */\nfunction formatDate(date: Date): string {\n return date.toLocaleString('en-US', {\n day: 'numeric',\n hour: 'numeric',\n minute: 'numeric',\n month: 'long',\n timeZoneName: 'short',\n year: 'numeric',\n })\n}\n\n/**\n * Execute the deploy command\n *\n * @param options - Command options\n */\nexport async function deployCommand(options: DeployCommandOptions): Promise<void> {\n const projectPath = process.cwd()\n const spinner = p.spinner()\n\n try {\n // ===== PRE-FLIGHT CHECKS =====\n\n // Check if in project directory\n if (!(await isInProjectDirectory(projectPath))) {\n p.log.error(pc.red(\"✗ 'deploy' command is not available outside of a Payload project.\"))\n p.note(\n 'Create a project or connect an existing one to Figma: npx @payloadcms/figma init',\n 'Tip',\n )\n process.exit(1)\n }\n\n // Find and read payload config\n const configPath = await findPayloadConfig(projectPath)\n if (!configPath) {\n p.log.error(pc.red('✗ payload.config.ts not found'))\n p.note('Run npx @payloadcms/figma init to configure your project.', 'Tip')\n process.exit(1)\n }\n\n // Parse config with ts-morph\n const project = new Project({ skipAddingFilesFromTsConfig: true })\n const sourceFile = project.addSourceFileAtPath(configPath)\n\n // Read figma configuration from buildConfig\n const config = readFigmaConfig(sourceFile)\n if (!config || !config.tenantId) {\n p.log.error(pc.red('✗ No figma configuration found in payload.config.ts'))\n p.note('Run npx @payloadcms/figma init to configure your project.', 'Tip')\n process.exit(1)\n }\n\n // Check authentication\n const tokenStore = new TokenStore()\n\n let accessToken = await getValidAccessToken(tokenStore)\n if (!accessToken) {\n p.log.message('Please log in to continue')\n await loginCommand()\n accessToken = await getValidAccessToken(tokenStore)\n if (!accessToken) {\n p.log.error(pc.red('✗ Authentication failed'))\n process.exit(1)\n }\n }\n\n // Get project token\n try {\n await getValidProjectToken(tokenStore, config.tenantId)\n } catch (error) {\n p.log.error(pc.yellow('⚠ Project token invalid'))\n throw error\n }\n\n // ===== BUILD VALIDATION =====\n\n spinner.start('Checking for build...')\n let buildInfo = await detectBuild(projectPath)\n\n if (!buildInfo) {\n spinner.stop(pc.yellow('⚠ No build found for this project.'))\n\n // Try to find build command\n const buildCmd = await getBuildCommand(projectPath)\n\n if (!buildCmd) {\n p.log.error('No build script found in package.json')\n p.note('Add a build script to package.json: \"build\": \"next build\"', 'Tip')\n process.exit(1)\n }\n\n // Prompt to run build\n if (!options.yes) {\n const shouldBuild = await p.confirm({\n initialValue: true,\n message: `Build command found in package.json. Run it?`,\n })\n\n if (p.isCancel(shouldBuild) || !shouldBuild) {\n p.log.message('Cancelling deployment...')\n process.exit(0)\n }\n }\n\n // Run build\n const packageManager = await getPackageManager(projectPath)\n const buildCommand = `${packageManager} run build`\n spinner.stop(`Running ${buildCommand}...\\n`)\n\n try {\n // Stream build output to user with formatting\n const buildProcess = spawn(packageManager, ['run', 'build'], {\n cwd: projectPath,\n stdio: ['ignore', 'pipe', 'pipe'],\n })\n\n // Indent and dim output\n buildProcess.stdout?.on('data', (data) => {\n const lines = data.toString().split('\\n')\n lines.forEach((line: string) => {\n if (line.trim()) {\n // eslint-disable-next-line no-console\n console.log(pc.dim(` ${line}`)) // Standard output\n }\n })\n })\n\n buildProcess.stderr?.on('data', (data) => {\n const lines = data.toString().split('\\n')\n lines.forEach((line: string) => {\n if (line.trim()) {\n // eslint-disable-next-line no-console\n console.log(pc.dim(` ${line}`)) // Standard error\n }\n })\n })\n\n const exitCode = await new Promise<number>((resolve) => {\n buildProcess.on('close', resolve)\n })\n\n if (exitCode !== 0) {\n throw new Error(`Build process exited with code ${exitCode}`)\n }\n\n p.log.success(pc.green('✓ Build completed'))\n } catch (error) {\n p.log.error(pc.red('✗ Build failed'))\n if (error instanceof Error && options.debug) {\n log.error(`Build error: ${error.message}`)\n }\n process.exit(1)\n }\n\n // Re-check for build\n buildInfo = await detectBuild(projectPath)\n if (!buildInfo) {\n p.log.error(pc.red('✗ Build completed but standalone build not found'))\n p.note('Ensure next.config.js has output: \"standalone\"', 'Check Lambda Configuration')\n process.exit(1)\n }\n } else {\n spinner.stop(pc.green('✓ Build found'))\n p.note(\n [\n `${pc.cyan('Build ID:')} ${buildInfo.buildId}`,\n `${pc.cyan('Date:')} ${formatDate(buildInfo.timestamp)}`,\n ].join('\\n'),\n 'Build Details',\n )\n }\n\n // ===== DEPLOYMENT PREPARATION =====\n\n // Create Lambda zip\n spinner.start('Creating deployment package...')\n try {\n await createLambdaZip(projectPath)\n spinner.stop(pc.green('✓ Deployment package created'))\n } catch (error) {\n spinner.stop(pc.red('✗ Failed to create deployment package'))\n throw error\n }\n\n // Collect static assets\n spinner.start('Collecting static assets...')\n const staticAssets = await collectStaticAssets(projectPath)\n const zipPath = path.join(projectPath, 'lambda.zip')\n const zipSize = await getFileSize(zipPath)\n spinner.stop(pc.green(`✓ ${staticAssets.length} static assets detected`))\n\n log.debug(`Lambda zip size: ${formatBytes(zipSize)}`)\n log.debug(`Static assets: ${staticAssets.length} files`)\n\n // ===== DEPLOYMENT CONFIRMATION =====\n\n if (!options.yes) {\n p.note(\n [\n `${pc.cyan('Build ID:')} ${buildInfo.buildId}`,\n `${pc.cyan('Date:')} ${formatDate(buildInfo.timestamp)}`,\n `${pc.cyan('Code size:')} ${formatBytes(zipSize)}`,\n `${pc.cyan('Static assets:')} ${staticAssets.length} files`,\n ].join('\\n'),\n 'Details',\n )\n\n const shouldDeploy = await p.confirm({\n initialValue: true,\n message: 'Deploy this build to Figma?',\n })\n\n if (p.isCancel(shouldDeploy) || !shouldDeploy) {\n p.log.message('Cancelling deployment...')\n process.exit(0)\n }\n }\n\n // ===== DEPLOYMENT EXECUTION =====\n\n // Step 1: Create deployment\n spinner.start('Creating deployment...')\n let deploymentId: string\n let codeUploadUrl: string\n let staticAssetUploadUrls: Record<string, string>\n\n try {\n const createResponse = await createDeployment(accessToken, config.tenantId, {\n staticAssets,\n })\n\n deploymentId = createResponse.deploymentId\n codeUploadUrl = createResponse.codeUploadUrl\n staticAssetUploadUrls = createResponse.staticAssetUploadUrls\n\n log.debug(`Deployment ID: ${deploymentId}`)\n } catch (error) {\n spinner.stop(pc.red('✗ Failed to create deployment'))\n throw error\n }\n\n // Step 2: Upload code\n spinner.message(`Uploading code (${formatBytes(zipSize)})...`)\n try {\n await uploadLambdaZip(zipPath, codeUploadUrl)\n spinner.stop(pc.green(`✓ Code uploaded (${formatBytes(zipSize)})`))\n } catch (error) {\n spinner.stop(pc.red('✗ Failed to upload code'))\n throw error\n }\n\n // Step 3: Upload static assets\n if (staticAssets.length > 0) {\n spinner.start('Uploading static assets...')\n\n try {\n const uploadResults = await uploadStaticAssets(\n projectPath,\n staticAssetUploadUrls,\n (uploaded, total) => {\n spinner.message(`Uploading static assets (${uploaded}/${total})...`)\n },\n )\n\n if (uploadResults.assetsFailed > 0) {\n spinner.stop(\n pc.yellow(\n `⚠ ${uploadResults.assetsUploaded}/${staticAssets.length} assets uploaded (${uploadResults.assetsFailed} failed)`,\n ),\n )\n p.log.warning(\n `${uploadResults.assetsFailed} assets failed to upload. Deployment may be incomplete.`,\n )\n } else {\n spinner.stop(\n pc.green(\n `✓ Static assets uploaded (${uploadResults.assetsUploaded} files, ${formatBytes(uploadResults.totalBytesUploaded)})`,\n ),\n )\n }\n } catch (error) {\n spinner.stop(pc.red('✗ Failed to upload assets'))\n throw error\n }\n }\n\n // Step 4: Perform deployment\n spinner.start('Performing deployment...')\n try {\n await performDeployment(accessToken, config.tenantId, {\n deploymentId,\n })\n spinner.stop(pc.green('✓ Deployment initiated'))\n } catch (error) {\n spinner.stop(pc.red('✗ Failed to perform deployment'))\n throw error\n }\n\n // TODO: Add deployment progress tracking\n // Future: Poll deployment status and show progress\n // API endpoint: GET /v1/tenant/{tenant_id}/deploy/{deployment_id}/status\n\n // Success output\n p.log.message('This usually takes 2-3 minutes to complete.')\n\n // Get tenant details for URL\n try {\n const tenant = await getTenantDetails(accessToken, config.tenantId)\n if (tenant.domain) {\n p.log.message(`View: ${pc.cyan(`https://${tenant.domain}/`)}`)\n }\n } catch {\n // Non-critical - just skip URL display\n }\n\n p.note(\n `Manage your deployment at:\\n${pc.cyan(`https://cms.figma.com/manage/tenants/${config.tenantId}`)}`,\n 'Next Steps',\n )\n } catch (error) {\n spinner.stop(pc.red('✗ Failed'))\n const message = error instanceof Error ? error.message : 'Unknown error'\n p.log.error(pc.red(`✗ ${message}`))\n if (options.debug && error instanceof Error && error.stack) {\n log.error(`Stack trace: ${error.stack}`)\n }\n process.exit(1)\n }\n}\n"],"names":["p","spawn","path","pc","Project","createDeployment","getTenantDetails","performDeployment","getValidAccessToken","getValidProjectToken","TokenStore","collectStaticAssets","createLambdaZip","getFileSize","detectBuild","getBuildCommand","log","getPackageManager","readFigmaConfig","findPayloadConfig","isInProjectDirectory","uploadLambdaZip","uploadStaticAssets","loginCommand","formatBytes","bytes","k","sizes","i","Math","floor","parseFloat","pow","toFixed","formatDate","date","toLocaleString","day","hour","minute","month","timeZoneName","year","deployCommand","options","projectPath","process","cwd","spinner","error","red","note","exit","configPath","project","skipAddingFilesFromTsConfig","sourceFile","addSourceFileAtPath","config","tenantId","tokenStore","accessToken","message","yellow","start","buildInfo","stop","buildCmd","yes","shouldBuild","confirm","initialValue","isCancel","packageManager","buildCommand","buildProcess","stdio","stdout","on","data","lines","toString","split","forEach","line","trim","console","dim","stderr","exitCode","Promise","resolve","Error","success","green","debug","cyan","buildId","timestamp","join","staticAssets","zipPath","zipSize","length","shouldDeploy","deploymentId","codeUploadUrl","staticAssetUploadUrls","createResponse","uploadResults","uploaded","total","assetsFailed","assetsUploaded","warning","totalBytesUploaded","tenant","domain","stack"],"mappings":"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"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"init.d.ts","sourceRoot":"","sources":["../../src/commands/init.ts"],"names":[],"mappings":"AA6BA;;GAEG;AACH,MAAM,WAAW,kBAAkB;IACjC,wBAAwB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,gDAAgD;IAChD,KAAK,CAAC,EAAE,OAAO,CAAA;IACf,gEAAgE;IAChE,EAAE,CAAC,EAAE,MAAM,CAAA;IACX,qCAAqC;IACrC,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,mDAAmD;IACnD,eAAe,CAAC,EAAE,OAAO,CAAA;IACzB,wDAAwD;IACxD,MAAM,CAAC,EAAE,MAAM,CAAA;IACf,0DAA0D;IAC1D,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,mDAAmD;IACnD,GAAG,CAAC,EAAE,OAAO,CAAA;CACd;AAiDD;;;;;;;;;;GAUG;AACH,wBAAsB,WAAW,CAAC,OAAO,EAAE,kBAAkB,GAAG,OAAO,CAAC,IAAI,CAAC,CAmW5E"}
|
|
@@ -1 +0,0 @@
|
|
|
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 { Tenant } from '../types/config.js'\n\nimport { ControlPlaneError, getTenantDetails } 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 { TokenStore } from '../auth/token-store.js'\nimport { isDebug } from '../utils/is-debug.js'\nimport * as log from '../utils/log.js'\nimport {\n displayManualInstructions,\n ensurePayloadFigmaConfig,\n} from '../utils/payload-config-modifier.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 /** Tenant ID to use (optional - will prompt if not provided) */\n id?: string\n /** Project name (for scaffolding) */\n name?: string\n /** Disable Content System (defaults to enabled) */\n noContentSystem?: boolean\n /** AWS region for deployment (defaults to us-east-1) */\n region?: 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 tenant\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 tenantId - Tenant 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 tenantId: 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, tenantId)\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 * 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 = new TokenStore()\n const s = p.spinner()\n\n let accessToken: string\n\n if (options.skipAuth) {\n // Skip authentication for testing/development\n p.log.warn(pc.yellow('Skipping authentication (--skip-auth mode)'))\n accessToken = 'mock-access-token'\n } else {\n try {\n // Check for valid cached tokens first (no API call needed)\n if (tokenStore.hasValidTokens()) {\n // Use cached token silently - no spinner needed\n accessToken = tokenStore.getAccessToken()!\n } else {\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(pc.yellow('⚠ Not authenticated'))\n p.log.info('Authentication required to continue')\n\n // Prompt user to authenticate now\n const shouldAuth = await p.confirm({\n initialValue: true,\n message: 'Would you like to authenticate now?',\n })\n\n if (p.isCancel(shouldAuth) || !shouldAuth) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n // Run login command\n await loginCommand()\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 accessToken = newToken\n p.log.success(pc.green('✓ Authenticated'))\n } else {\n accessToken = token\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 CMS ID with retry loop\n log.debug('Configuring Project...')\n\n let tenantId = options.id\n let selectedTenant: Tenant | undefined\n\n while (!selectedTenant) {\n // Prompt for ID if not provided\n if (!tenantId) {\n const input = await p.text({\n message: 'Enter your CMS ID:',\n placeholder: 'tenant_abc123',\n validate: (value) => {\n if (!value || typeof value !== 'string') {\n return 'CMS ID is required'\n }\n return undefined\n },\n })\n\n if (p.isCancel(input)) {\n p.cancel('Operation cancelled')\n process.exit(0)\n }\n\n tenantId = input\n }\n\n // Try to fetch tenant details\n try {\n log.debug('Using mock Control Plane API (no real network calls)')\n selectedTenant = await getTenantDetails(accessToken, tenantId)\n log.debug(`Using: ${selectedTenant.domain}`)\n } catch (error) {\n p.log.error(pc.red('✗ Failed to fetch CMS details'))\n\n // Check if permission error (403)\n if (error instanceof ControlPlaneError && error.statusCode === 403) {\n p.log.error('You do not have permission to access the provided CMS ID. Please try again.')\n } else if (error instanceof ControlPlaneError && error.statusCode === 404) {\n p.log.error('Tenant ID not found. Verify the ID is correct.')\n } else {\n p.log.error(error instanceof Error ? error.message : 'Unknown error')\n }\n\n // Clear tenantId to prompt again\n tenantId = undefined\n\n // Ask if they want to retry\n const shouldRetry = await p.confirm({\n initialValue: true,\n message: 'Would you like to try a different CMS ID?',\n })\n\n if (p.isCancel(shouldRetry) || !shouldRetry) {\n p.cancel('Operation cancelled')\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 region: options.region || 'us-east-1',\n tenantId: selectedTenant.id,\n useContentSystem: !options.noContentSystem,\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 } 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 project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, selectedTenant.id, s)\n }\n\n // Success message for existing project\n p.outro(pc.green('✓ Project initialized successfully!'))\n\n const nextSteps = [\n selectedTenant.status === 'provisioning'\n ? 'Wait for CMS provisioning to complete (check status with `@payloadcms/figma list`)'\n : undefined,\n 'Start development server: `pnpm dev`',\n `Access your CMS at: ${pc.cyan(`https://${selectedTenant.domain}`)}`,\n ].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 region: options.region || 'us-east-1',\n tenantId: selectedTenant.id,\n useContentSystem: !options.noContentSystem,\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 // Generate project token (unless skipping auth)\n if (!options.skipAuth) {\n await generateProjectTokenWithFeedback(tokenStore, selectedTenant.id, 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","ControlPlaneError","getTenantDetails","FigmaApiError","getValidAccessToken","getValidProjectToken","ProjectTokenError","TokenStore","isDebug","log","displayManualInstructions","ensurePayloadFigmaConfig","detectPayloadProject","hasRequiredDependencies","initializeGitRepo","installDependencies","isInProjectDirectory","scaffoldProject","validatePayloadVersion","loginCommand","generateProjectTokenWithFeedback","tokenStore","tenantId","spinner","start","projectToken","stop","green","yellow","error","warning","message","note","Error","initCommand","options","s","accessToken","skipAuth","warn","hasValidTokens","getAccessToken","token","info","shouldAuth","confirm","initialValue","isCancel","cancel","process","exit","newToken","success","red","debug","id","selectedTenant","input","text","placeholder","validate","value","undefined","domain","statusCode","shouldRetry","isInProject","projectInfo","hasPayload","payloadVersion","hasDeps","cwd","shouldInstall","packageManager","modResult","region","useContentSystem","noContentSystem","modified","changes","length","forEach","change","dim","warnings","shouldAddPayload","outro","nextSteps","status","cyan","filter","Boolean","join","projectPathInput","projectPath","fullPath","resolve","projectName","name","basename","mkdir","recursive","step","bgGreen","black","relativePath","relative","push"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,cAAa;AAC5B,OAAOC,UAAU,OAAM;AACvB,OAAOC,QAAQ,aAAY;AAI3B,SAASC,iBAAiB,EAAEC,gBAAgB,QAAQ,0BAAyB;AAC7E,SAASC,aAAa,QAAQ,sBAAqB;AACnD,SAASC,mBAAmB,QAAQ,wBAAuB;AAC3D,SAASC,oBAAoB,EAAEC,iBAAiB,QAAQ,2BAA0B;AAClF,SAASC,UAAU,QAAQ,yBAAwB;AACnD,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,YAAYC,SAAS,kBAAiB;AACtC,SACEC,yBAAyB,EACzBC,wBAAwB,QACnB,sCAAqC;AAC5C,SACEC,oBAAoB,EACpBC,uBAAuB,EACvBC,iBAAiB,EACjBC,mBAAmB,EACnBC,oBAAoB,EACpBC,eAAe,EACfC,sBAAsB,QACjB,sBAAqB;AAC5B,SAASC,YAAY,QAAQ,aAAY;AAwBzC;;;;;;;;CAQC,GACD,eAAeC,iCACbC,UAAsB,EACtBC,QAAgB,EAChBC,OAAqC;IAErC,IAAIf,WAAW;QACbe,QAAQC,KAAK,CAAC;IAChB;IAEA,IAAI;QACF,MAAMC,eAAe,MAAMpB,qBAAqBgB,YAAYC;QAC5D,IAAId,WAAW;YACb,IAAIiB,cAAc;gBAChBF,QAAQG,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;YACxB,OAAO;gBACLJ,QAAQG,IAAI,CAAC1B,GAAG4B,MAAM,CAAC;YACzB;QACF;IACF,EAAE,OAAOC,OAAO;QACd,IAAIrB,WAAW;YACbe,QAAQG,IAAI,CAAC1B,GAAG4B,MAAM,CAAC;QACzB;QACA,2CAA2C;QAC3C,IAAIC,iBAAiBvB,qBAAqBuB,iBAAiB1B,eAAe;YACxEM,IAAIqB,OAAO,CAACD,MAAME,OAAO;YACzBlC,EAAEmC,IAAI,CACJ,gIACA;QAEJ,OAAO;YACLvB,IAAIqB,OAAO,CACT,CAAC,kCAAkC,EAAED,iBAAiBI,QAAQJ,MAAME,OAAO,GAAG,iBAAiB;QAEnG;IACA,uEAAuE;IACzE;AACF;AAEA;;;;;;;;;;CAUC,GACD,OAAO,eAAeG,YAAYC,OAA2B;IAC3D,uBAAuB;IACvB,MAAMd,aAAa,IAAId;IACvB,MAAM6B,IAAIvC,EAAE0B,OAAO;IAEnB,IAAIc;IAEJ,IAAIF,QAAQG,QAAQ,EAAE;QACpB,8CAA8C;QAC9CzC,EAAEY,GAAG,CAAC8B,IAAI,CAACvC,GAAG4B,MAAM,CAAC;QACrBS,cAAc;IAChB,OAAO;QACL,IAAI;YACF,2DAA2D;YAC3D,IAAIhB,WAAWmB,cAAc,IAAI;gBAC/B,gDAAgD;gBAChDH,cAAchB,WAAWoB,cAAc;YACzC,OAAO;gBACL,8DAA8D;gBAC9DL,EAAEZ,KAAK,CAAC;gBACR,MAAMkB,QAAQ,MAAMtC,oBAAoBiB;gBACxC,IAAI,CAACqB,OAAO;oBACVN,EAAEV,IAAI,CAAC1B,GAAG4B,MAAM,CAAC;oBACjB/B,EAAEY,GAAG,CAACkC,IAAI,CAAC;oBAEX,kCAAkC;oBAClC,MAAMC,aAAa,MAAM/C,EAAEgD,OAAO,CAAC;wBACjCC,cAAc;wBACdf,SAAS;oBACX;oBAEA,IAAIlC,EAAEkD,QAAQ,CAACH,eAAe,CAACA,YAAY;wBACzC/C,EAAEmD,MAAM,CAAC;wBACTC,QAAQC,IAAI,CAAC;oBACf;oBAEA,oBAAoB;oBACpB,MAAM/B;oBAEN,uBAAuB;oBACvB,MAAMgC,WAAW,MAAM/C,oBAAoBiB;oBAC3C,IAAI,CAAC8B,UAAU;wBACbtD,EAAEY,GAAG,CAACoB,KAAK,CAAC;wBACZoB,QAAQC,IAAI,CAAC;oBACf;oBACAb,cAAcc;oBACdtD,EAAEY,GAAG,CAAC2C,OAAO,CAACpD,GAAG2B,KAAK,CAAC;gBACzB,OAAO;oBACLU,cAAcK;oBACdN,EAAEV,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;gBAClB;YACF;QACF,EAAE,OAAOE,OAAO;YACdO,EAAEV,IAAI,CAAC1B,GAAGqD,GAAG,CAAC;YACd5C,IAAIoB,KAAK,CAACA,iBAAiBI,QAAQJ,MAAME,OAAO,GAAG;YACnDlC,EAAEmC,IAAI,CAAC,oCAAoC;YAC3CiB,QAAQC,IAAI,CAAC;QACf;IACF;IAEA,sDAAsD;IACtD,4FAA4F;IAC5F,4DAA4D;IAE5D,qCAAqC;IACrCzC,IAAI6C,KAAK,CAAC;IAEV,IAAIhC,WAAWa,QAAQoB,EAAE;IACzB,IAAIC;IAEJ,MAAO,CAACA,eAAgB;QACtB,gCAAgC;QAChC,IAAI,CAAClC,UAAU;YACb,MAAMmC,QAAQ,MAAM5D,EAAE6D,IAAI,CAAC;gBACzB3B,SAAS;gBACT4B,aAAa;gBACbC,UAAU,CAACC;oBACT,IAAI,CAACA,SAAS,OAAOA,UAAU,UAAU;wBACvC,OAAO;oBACT;oBACA,OAAOC;gBACT;YACF;YAEA,IAAIjE,EAAEkD,QAAQ,CAACU,QAAQ;gBACrB5D,EAAEmD,MAAM,CAAC;gBACTC,QAAQC,IAAI,CAAC;YACf;YAEA5B,WAAWmC;QACb;QAEA,8BAA8B;QAC9B,IAAI;YACFhD,IAAI6C,KAAK,CAAC;YACVE,iBAAiB,MAAMtD,iBAAiBmC,aAAaf;YACrDb,IAAI6C,KAAK,CAAC,CAAC,OAAO,EAAEE,eAAeO,MAAM,EAAE;QAC7C,EAAE,OAAOlC,OAAO;YACdhC,EAAEY,GAAG,CAACoB,KAAK,CAAC7B,GAAGqD,GAAG,CAAC;YAEnB,kCAAkC;YAClC,IAAIxB,iBAAiB5B,qBAAqB4B,MAAMmC,UAAU,KAAK,KAAK;gBAClEnE,EAAEY,GAAG,CAACoB,KAAK,CAAC;YACd,OAAO,IAAIA,iBAAiB5B,qBAAqB4B,MAAMmC,UAAU,KAAK,KAAK;gBACzEnE,EAAEY,GAAG,CAACoB,KAAK,CAAC;YACd,OAAO;gBACLhC,EAAEY,GAAG,CAACoB,KAAK,CAACA,iBAAiBI,QAAQJ,MAAME,OAAO,GAAG;YACvD;YAEA,iCAAiC;YACjCT,WAAWwC;YAEX,4BAA4B;YAC5B,MAAMG,cAAc,MAAMpE,EAAEgD,OAAO,CAAC;gBAClCC,cAAc;gBACdf,SAAS;YACX;YAEA,IAAIlC,EAAEkD,QAAQ,CAACkB,gBAAgB,CAACA,aAAa;gBAC3CpE,EAAEmD,MAAM,CAAC;gBACTC,QAAQC,IAAI,CAAC;YACf;QACF;IACF;IAEA,6CAA6C;IAC7C,MAAMgB,cAAc,MAAMlD;IAE1B,IAAIkD,aAAa;QACf,oCAAoC;QACpCzD,IAAI6C,KAAK,CAAC;QAEV,iBAAiB;QACjB,MAAMa,cAAc,MAAMvD;QAE1B,IAAIuD,YAAYC,UAAU,EAAE;YAC1B,oCAAoC;YACpC,IAAID,YAAYE,cAAc,IAAI,CAACnD,uBAAuBiD,YAAYE,cAAc,GAAG;gBACrFxE,EAAEY,GAAG,CAAC8B,IAAI,CACRvC,GAAG4B,MAAM,CACP,CAAC,gBAAgB,EAAEuC,YAAYE,cAAc,CAAC,mCAAmC,CAAC;gBAGtFxE,EAAEmC,IAAI,CAAC,4CAA4C;gBACnDiB,QAAQC,IAAI,CAAC;YACf;YAEArD,EAAEY,GAAG,CAAC2C,OAAO,CAACpD,GAAG2B,KAAK,CAAC,CAAC,UAAU,EAAEwC,YAAYE,cAAc,IAAI,YAAY;YAE9E,qBAAqB;YACrBjC,EAAEZ,KAAK,CAAC;YACR,MAAM8C,UAAU,MAAMzD,wBAAwBoC,QAAQsB,GAAG;YACzDnC,EAAEV,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;YAEhB,IAAI,CAAC2C,SAAS;gBACZ,MAAME,gBAAgB,MAAM3E,EAAEgD,OAAO,CAAC;oBACpCC,cAAc;oBACdf,SAAS;gBACX;gBAEA,IAAI,CAAClC,EAAEkD,QAAQ,CAACyB,kBAAkBA,eAAe;oBAC/CpC,EAAEZ,KAAK,CAAC;oBACR,MAAMT,oBAAoBkC,QAAQsB,GAAG,IAAIJ,YAAYM,cAAc,IAAI;oBACvErC,EAAEV,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;gBAClB;YACF;YAEAS,EAAEZ,KAAK,CAAC;YACR,MAAMkD,YAAY,MAAM/D,yBACtBsC,QAAQsB,GAAG,IACXJ,YAAYM,cAAc,IAAI,QAC9B;gBACEE,QAAQxC,QAAQwC,MAAM,IAAI;gBAC1BrD,UAAUkC,eAAeD,EAAE;gBAC3BqB,kBAAkB,CAACzC,QAAQ0C,eAAe;YAC5C;YAGF,IAAI,CAACH,UAAUtB,OAAO,EAAE;gBACtBhB,EAAEV,IAAI,CAAC1B,GAAGqD,GAAG,CAAC;gBACd3C,0BAA0BgE,UAAU7C,KAAK,IAAI;gBAC7CoB,QAAQC,IAAI,CAAC;YACf;YAEA,IAAIwB,UAAUI,QAAQ,EAAE;gBACtB1C,EAAEV,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;gBAChB,IAAI+C,UAAUK,OAAO,CAACC,MAAM,GAAG,GAAG;oBAChCN,UAAUK,OAAO,CAACE,OAAO,CAAC,CAACC,SAAWzE,IAAI6C,KAAK,CAACtD,GAAGmF,GAAG,CAAC,CAAC,GAAG,EAAED,QAAQ;gBACvE;YACF,OAAO;gBACL9C,EAAEV,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;YAClB;YAEA,0BAA0B;YAC1B,IAAI+C,UAAUU,QAAQ,IAAIV,UAAUU,QAAQ,CAACJ,MAAM,GAAG,GAAG;gBACvDN,UAAUU,QAAQ,CAACH,OAAO,CAAC,CAACnD;oBAC1BjC,EAAEY,GAAG,CAAC8B,IAAI,CAACvC,GAAG4B,MAAM,CAAC,CAAC,EAAE,EAAEE,SAAS;gBACrC;YACF;QACF,OAAO;YACL,yDAAyD;YACzDjC,EAAEY,GAAG,CAAC8B,IAAI,CAACvC,GAAG4B,MAAM,CAAC;YAErB,MAAMyD,mBAAmB,MAAMxF,EAAEgD,OAAO,CAAC;gBACvCC,cAAc;gBACdf,SAAS;YACX;YAEA,IAAIlC,EAAEkD,QAAQ,CAACsC,mBAAmB;gBAChCxF,EAAEmD,MAAM,CAAC;gBACTC,QAAQC,IAAI,CAAC;YACf;YAEA,IAAI,CAACmC,kBAAkB;gBACrBxF,EAAEY,GAAG,CAACoB,KAAK,CAAC;gBACZoB,QAAQC,IAAI,CAAC;YACf;YAEA,6DAA6D;YAC7DrD,EAAEY,GAAG,CAACoB,KAAK,CAAC;YACZhC,EAAEmC,IAAI,CAAC,6DAA6D;YACpEiB,QAAQC,IAAI,CAAC;QACf;QAEA,gDAAgD;QAChD,IAAI,CAACf,QAAQG,QAAQ,EAAE;YACrB,MAAMlB,iCAAiCC,YAAYmC,eAAeD,EAAE,EAAEnB;QACxE;QAEA,uCAAuC;QACvCvC,EAAEyF,KAAK,CAACtF,GAAG2B,KAAK,CAAC;QAEjB,MAAM4D,YAAY;YAChB/B,eAAegC,MAAM,KAAK,iBACtB,uFACA1B;YACJ;YACA,CAAC,oBAAoB,EAAE9D,GAAGyF,IAAI,CAAC,CAAC,QAAQ,EAAEjC,eAAeO,MAAM,EAAE,GAAG;SACrE,CAAC2B,MAAM,CAACC;QAET9F,EAAEmC,IAAI,CAACuD,UAAUK,IAAI,CAAC,OAAO;IAC/B,OAAO;QACL,+BAA+B;QAC/B,2DAA2D;QAE3D,kBAAkB;QAClB,MAAMC,mBAAmB,MAAMhG,EAAE6D,IAAI,CAAC;YACpCZ,cAAc;YACdf,SAAS;YACT4B,aAAa;YACbC,UAAU,CAACC;gBACT,IAAI,CAACA,OAAO;oBACV,OAAO;gBACT;gBACA,mCAAmC;gBACnC,OAAOC;YACT;QACF;QAEA,IAAIjE,EAAEkD,QAAQ,CAAC8C,mBAAmB;YAChChG,EAAEmD,MAAM,CAAC;YACTC,QAAQC,IAAI,CAAC;QACf;QAEA,MAAM4C,cAAcD;QACpB,MAAME,WAAWhG,KAAKiG,OAAO,CAAC/C,QAAQsB,GAAG,IAAIuB;QAE7C,uCAAuC;QACvC,MAAMG,cAAc9D,QAAQ+D,IAAI,IAAInG,KAAKoG,QAAQ,CAACJ;QAElD,mBAAmB;QACnB,IAAI;YACF,MAAMjG,GAAGsG,KAAK,CAACL,UAAU;gBAAEM,WAAW;YAAK;QAC7C,EAAE,OAAOxE,OAAO;YACdhC,EAAEY,GAAG,CAACoB,KAAK,CACT,CAAC,4BAA4B,EAAEA,iBAAiBI,QAAQJ,MAAME,OAAO,GAAG,iBAAiB;YAE3FkB,QAAQC,IAAI,CAAC;QACf;QAEA,mBAAmB;QACnBd,EAAEZ,KAAK,CAAC;QACR,IAAI;YACF,MAAMP,gBAAgB8E,UAAUE;YAChC7D,EAAEV,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;YAEhBS,EAAEZ,KAAK,CAAC;YACR,MAAMT,oBAAoBgF,UAAU;YACpC3D,EAAEV,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;QAClB,EAAE,OAAOE,OAAO;YACdO,EAAEV,IAAI,CAAC1B,GAAGqD,GAAG,CAAC;YACd5C,IAAIoB,KAAK,CAACA,iBAAiBI,QAAQJ,MAAME,OAAO,GAAG;YACnDkB,QAAQC,IAAI,CAAC;QACf;QAEA,+BAA+B;QAC/Bd,EAAEZ,KAAK,CAAC;QACR,MAAMkD,YAAY,MAAM/D,yBAAyBoF,UAAU,QAAQ;YACjEpB,QAAQxC,QAAQwC,MAAM,IAAI;YAC1BrD,UAAUkC,eAAeD,EAAE;YAC3BqB,kBAAkB,CAACzC,QAAQ0C,eAAe;QAC5C;QAEA,IAAI,CAACH,UAAUtB,OAAO,EAAE;YACtBhB,EAAEV,IAAI,CAAC1B,GAAGqD,GAAG,CAAC;YACd3C,0BAA0BgE,UAAU7C,KAAK,IAAI;YAC7CoB,QAAQC,IAAI,CAAC;QACf;QAEA,IAAIwB,UAAUI,QAAQ,EAAE;YACtB1C,EAAEV,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;YAChB,IAAI+C,UAAUK,OAAO,CAACC,MAAM,GAAG,GAAG;gBAChCN,UAAUK,OAAO,CAACE,OAAO,CAAC,CAACC,SAAWzE,IAAI6C,KAAK,CAACtD,GAAGmF,GAAG,CAAC,CAAC,GAAG,EAAED,QAAQ;YACvE;QACF,OAAO;YACL9C,EAAEV,IAAI,CAAC1B,GAAG2B,KAAK,CAAC;QAClB;QAEA,0BAA0B;QAC1B,IAAI+C,UAAUU,QAAQ,IAAIV,UAAUU,QAAQ,CAACJ,MAAM,GAAG,GAAG;YACvDN,UAAUU,QAAQ,CAACH,OAAO,CAAC,CAACnD;gBAC1BjC,EAAEY,GAAG,CAAC8B,IAAI,CAACvC,GAAG4B,MAAM,CAAC,CAAC,EAAE,EAAEE,SAAS;YACrC;QACF;QAEA,gDAAgD;QAChD,IAAI,CAACK,QAAQG,QAAQ,EAAE;YACrB,MAAMlB,iCAAiCC,YAAYmC,eAAeD,EAAE,EAAEnB;QACxE;QAEA,4EAA4E;QAC5EtB,kBAAkBiF;QAElB,kCAAkC;QAClClG,EAAEY,GAAG,CAAC6F,IAAI,CAACtG,GAAGuG,OAAO,CAACvG,GAAGwG,KAAK,CAAC;QAE/B,MAAMC,eAAe1G,KAAK2G,QAAQ,CAACzD,QAAQsB,GAAG,IAAIwB;QAClD,MAAMR,YAAsB,EAAE;QAE9B,iDAAiD;QACjD,IAAIkB,gBAAgBA,iBAAiB,KAAK;YACxClB,UAAUoB,IAAI,CAAC,CAAC,GAAG,EAAEF,cAAc;QACrC;QAEAlB,UAAUoB,IAAI,CACZ,8CACA,IACA,kBACA,kFACA;QAGF9G,EAAEmC,IAAI,CAACuD,UAAUK,IAAI,CAAC,OAAO;QAC7B/F,EAAEyF,KAAK,CAACtF,GAAG2B,KAAK,CAAC;IACnB;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
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 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/list-tokens.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { TokenStore } 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 = new TokenStore()\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","TokenStore","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,UAAU,QAAQ,yBAAwB;AACnD,SAASC,OAAO,QAAQ,uBAAsB;AAC9C,SAASC,eAAe,EAAEC,SAAS,EAAEC,iBAAiB,QAAQ,4BAA2B;AAUzF;;;;;;CAMC,GACD,OAAO,SAASC,kBAAkBC,WAAqC,CAAC,CAAC;IACvE,MAAMC,aAAa,IAAIP;IAEvB,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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"login.d.ts","sourceRoot":"","sources":["../../src/commands/login.ts"],"names":[],"mappings":"AAQA;;;;;GAKG;AACH,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAyBlD"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/login.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { executeOAuthFlow, getValidAccessToken, OAuthFlowError } from '../auth/oauth-flow.js'\nimport { TokenStore } from '../auth/token-store.js'\nimport { OAUTH_CONFIG } from '../config/oauth.js'\nimport * as log from '../utils/log.js'\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(): Promise<void> {\n const tokenStore = new TokenStore()\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 tokenStore,\n })\n}\n\n/**\n * Handle authentication flow\n */\nasync function handleAuthentication({ tokenStore }: { tokenStore: TokenStore }): 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\n p.note(` ${pc.cyan('@payloadcms/figma init')} Create a new CMS instance`, 'Next Steps')\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","TokenStore","OAUTH_CONFIG","log","loginCommand","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;AAE3B,SAASC,gBAAgB,EAAEC,mBAAmB,EAAEC,cAAc,QAAQ,wBAAuB;AAC7F,SAASC,UAAU,QAAQ,yBAAwB;AACnD,SAASC,YAAY,QAAQ,qBAAoB;AACjD,YAAYC,SAAS,kBAAiB;AAEtC;;;;;CAKC,GACD,OAAO,eAAeC;IACpB,MAAMC,aAAa,IAAIJ;IAEvB,kCAAkC;IAClC,IAAI;QACF,MAAMK,gBAAgB,MAAMP,oBAAoBM;QAChD,IAAIC,eAAe;YACjB,MAAMC,SAASF,WAAWG,SAAS;YACnCZ,EAAEO,GAAG,CAACM,IAAI,CAACZ,GAAGa,MAAM,CAAC;YACrB,IAAIH,QAAQI,QAAQ;gBAClBR,IAAIS,IAAI,CAAC,CAAC,SAAS,EAAEL,OAAOI,MAAM,EAAE;YACtC;YACAR,IAAIS,IAAI,CAAC,CAAC,eAAe,EAAEf,GAAGgB,GAAG,CAACR,WAAWS,cAAc,KAAK;YAChElB,EAAEmB,IAAI,CAAC,CAAC,8BAA8B,EAAElB,GAAGmB,IAAI,CAAC,6BAA6B,EAAE;YAC/E;QACF;IACF,EAAE,OAAM;QACN,qDAAqD;QACrDb,IAAIc,OAAO,CAAC;IACd;IAEA,mBAAmB;IACnB,MAAMC,qBAAqB;QACzBb;IACF;AACF;AAEA;;CAEC,GACD,eAAea,qBAAqB,EAAEb,UAAU,EAA8B;IAC5E,IAAI;QACF,qBAAqB;QACrB,MAAMc,SAAS,MAAMrB,iBAAiBO,YAAY;YAChDe,UAAUlB,aAAakB,QAAQ;YAC/BC,aAAanB,aAAamB,WAAW;YACrCC,QAAQpB,aAAaoB,MAAM;QAC7B;QAEA1B,EAAEO,GAAG,CAACoB,OAAO,CAAC1B,GAAG2B,KAAK,CAAC;QAEvB,IAAIL,OAAOR,MAAM,EAAE;YACjBR,IAAIsB,KAAK,CAAC,CAAC,SAAS,EAAEN,OAAOR,MAAM,EAAE;QACvC;QAEAR,IAAIsB,KAAK,CAAC,CAAC,eAAe,EAAE5B,GAAGgB,GAAG,CAACR,WAAWS,cAAc,KAAK;QAEjE,kBAAkB;QAClBlB,EAAEmB,IAAI,CAAC,CAAC,EAAE,EAAElB,GAAGmB,IAAI,CAAC,0BAA0B,2BAA2B,CAAC,EAAE;IAC9E,EAAE,OAAOU,OAAO;QACd,IAAIA,iBAAiB1B,gBAAgB;YACnCG,IAAIuB,KAAK,CAACA,MAAMC,OAAO;YAEvB,IAAID,MAAME,KAAK,EAAE;gBACfzB,IAAIsB,KAAK,CAAC,CAAC,OAAO,EAAEC,MAAME,KAAK,CAACD,OAAO,EAAE;YAC3C;QACF,OAAO;YACLxB,IAAIuB,KAAK,CAACA,iBAAiBG,QAAQH,MAAMC,OAAO,GAAG;QACrD;QAEAG,QAAQC,IAAI,CAAC;IACf;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"logout.d.ts","sourceRoot":"","sources":["../../src/commands/logout.ts"],"names":[],"mappings":"AAMA;;GAEG;AACH,MAAM,WAAW,oBAAoB;IACnC,wBAAwB;IACxB,KAAK,CAAC,EAAE,OAAO,CAAA;CAChB;AAED;;;;;;GAMG;AACH,wBAAsB,aAAa,CAAC,QAAQ,GAAE,oBAAyB,GAAG,OAAO,CAAC,IAAI,CAAC,CAoCtF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/commands/logout.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { TokenStore } from '../auth/token-store.js'\nimport * as log from '../utils/log.js'\n\n/**\n * Options for logout command\n */\nexport interface LogoutCommandOptions {\n /** Enable debug mode */\n debug?: boolean\n}\n\n/**\n * Handle the `@payloadcms/figma logout` command\n *\n * Clears all stored tokens (OAuth and project tokens) after confirmation.\n *\n * @param _options - Command options (unused)\n */\nexport async function logoutCommand(_options: LogoutCommandOptions = {}): Promise<void> {\n const tokenStore = new TokenStore()\n\n const hasTokens = tokenStore.getTokens() !== null\n\n if (!hasTokens) {\n p.log.warn(pc.yellow('No tokens found. Already logged out.'))\n return\n }\n\n // Confirm logout\n const confirmed = await p.confirm({\n initialValue: false,\n message: 'This will clear all OAuth and project tokens. Continue?',\n })\n\n if (p.isCancel(confirmed) || !confirmed) {\n p.log.info('Logout cancelled')\n return\n }\n\n const s = p.spinner()\n s.start('Clearing tokens...')\n\n try {\n // Clear OAuth tokens\n tokenStore.clearTokens()\n // Clear all project tokens\n tokenStore.clearAllProjectTokens()\n s.stop(pc.green('✓ Logged out successfully'))\n p.log.step('All OAuth and project tokens have been cleared')\n } catch (error) {\n s.stop(pc.red('✗ Failed to clear tokens'))\n log.error(error instanceof Error ? error.message : 'Unknown error')\n process.exit(1)\n }\n}\n"],"names":["p","pc","TokenStore","log","logoutCommand","_options","tokenStore","hasTokens","getTokens","warn","yellow","confirmed","confirm","initialValue","message","isCancel","info","s","spinner","start","clearTokens","clearAllProjectTokens","stop","green","step","error","red","Error","process","exit"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,aAAY;AAE3B,SAASC,UAAU,QAAQ,yBAAwB;AACnD,YAAYC,SAAS,kBAAiB;AAUtC;;;;;;CAMC,GACD,OAAO,eAAeC,cAAcC,WAAiC,CAAC,CAAC;IACrE,MAAMC,aAAa,IAAIJ;IAEvB,MAAMK,YAAYD,WAAWE,SAAS,OAAO;IAE7C,IAAI,CAACD,WAAW;QACdP,EAAEG,GAAG,CAACM,IAAI,CAACR,GAAGS,MAAM,CAAC;QACrB;IACF;IAEA,iBAAiB;IACjB,MAAMC,YAAY,MAAMX,EAAEY,OAAO,CAAC;QAChCC,cAAc;QACdC,SAAS;IACX;IAEA,IAAId,EAAEe,QAAQ,CAACJ,cAAc,CAACA,WAAW;QACvCX,EAAEG,GAAG,CAACa,IAAI,CAAC;QACX;IACF;IAEA,MAAMC,IAAIjB,EAAEkB,OAAO;IACnBD,EAAEE,KAAK,CAAC;IAER,IAAI;QACF,qBAAqB;QACrBb,WAAWc,WAAW;QACtB,2BAA2B;QAC3Bd,WAAWe,qBAAqB;QAChCJ,EAAEK,IAAI,CAACrB,GAAGsB,KAAK,CAAC;QAChBvB,EAAEG,GAAG,CAACqB,IAAI,CAAC;IACb,EAAE,OAAOC,OAAO;QACdR,EAAEK,IAAI,CAACrB,GAAGyB,GAAG,CAAC;QACdvB,IAAIsB,KAAK,CAACA,iBAAiBE,QAAQF,MAAMX,OAAO,GAAG;QACnDc,QAAQC,IAAI,CAAC;IACf;AACF"}
|
|
@@ -1 +0,0 @@
|
|
|
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,IAAI,EAAE,MAAM,CACvB,MAAM,GAAG,SAAS,EAClB,IAAI,CAAC,WAAW,EAAE,kBAAkB,GAAG,YAAY,GAAG,UAAU,CAAC,CAYlE,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,YAAY,EAAE,WAe1B,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,2BAA2B,MAAM,CAAA"}
|
package/dist/config/oauth.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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\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: 'https://staging.figma.com/oauth',\n refreshUrl: 'https://api.staging.figma.com/v1/oauth/refresh',\n tokenUrl: '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: process.env.FIGMA_REDIRECT_URI || 'http://localhost:3000/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","URLS","prod","authorizationUrl","refreshUrl","tokenUrl","staging","OAUTH_CONFIG","clientId","process","env","FIGMA_CLIENT_ID","redirectUri","FIGMA_REDIRECT_URI","scopes","TOKEN_EXPIRY_BUFFER_SECONDS"],"mappings":"AAEA,SAASA,gBAAgB,QAAQ,kBAAiB;AAElD,OAAO,MAAMC,OAGT;IACFC,MAAM;QACJC,kBAAkB;QAClBC,YAAY;QACZC,UAAU;IACZ;IACAC,SAAS;QACPH,kBAAkB;QAClBC,YAAY;QACZC,UAAU;IACZ;AACF,EAAC;AAED;;;;;;;;;CASC,GACD,OAAO,MAAME,eAA4B;IACvC,kCAAkC;IAClC,mEAAmE;IACnEC,UAAUC,QAAQC,GAAG,CAACC,eAAe,IAAIX,iBAAiBM,OAAO;IAEjE,8DAA8D;IAC9D,mEAAmE;IAEnEM,aAAaH,QAAQC,GAAG,CAACG,kBAAkB,IAAI;IAE/C,6DAA6D;IAC7DC,QAAQ;QAAC;KAAoB;IAE7B,yEAAyE;IACzE,GAAGb,KAAKK,OAAO;AACjB,EAAC;AAED;;;CAGC,GACD,OAAO,MAAMS,8BAA8B,IAAI,YAAY;CAAb"}
|
package/dist/constants.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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"}
|
package/dist/constants.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
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 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/exports/client.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,0CAA0C,CAAA;AAC7E,OAAO,EAAE,YAAY,EAAE,MAAM,2CAA2C,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/exports/client.ts"],"sourcesContent":["export { DefaultLoginButton } from '../oauth/components/LoginButton/index.js'\nexport { LogoutButton } from '../oauth/components/LogoutButton/index.js'\n"],"names":["DefaultLoginButton","LogoutButton"],"mappings":"AAAA,SAASA,kBAAkB,QAAQ,2CAA0C;AAC7E,SAASC,YAAY,QAAQ,4CAA2C"}
|
package/dist/index.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAA;AACxD,YAAY,EAAE,yBAAyB,EAAE,MAAM,qBAAqB,CAAA;AAGpE,OAAO,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA;AACtD,YAAY,EAAE,WAAW,EAAE,MAAM,0BAA0B,CAAA"}
|
package/dist/index.js.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["// Export database adapter for advanced use cases\nexport { figmaContentSystem } from './plugin/adapter.js'\nexport type { FigmaContentSystemOptions } from './plugin/adapter.js'\n\n// Export buildConfig wrapper and its config type\nexport { buildConfig } from './plugin/build-config.js'\nexport type { FigmaConfig } from './plugin/build-config.js'\n"],"names":["figmaContentSystem","buildConfig"],"mappings":"AAAA,iDAAiD;AACjD,SAASA,kBAAkB,QAAQ,sBAAqB;AAGxD,iDAAiD;AACjD,SAASC,WAAW,QAAQ,2BAA0B"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/oauth/components/LoginButton/index.tsx"],"names":[],"mappings":"AAIA,OAAO,KAA8B,MAAM,OAAO,CAAA;AAElD,OAAO,cAAc,CAAA;AAIrB,KAAK,uBAAuB,GAAG;IAC7B,QAAQ,CAAC,EAAE,OAAO,CAAA;IAClB,YAAY,EAAE,MAAM,CAAA;CACrB,CAAA;AAED,eAAO,MAAM,kBAAkB,EAAE,KAAK,CAAC,EAAE,CAAC,uBAAuB,CAoDhE,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/oauth/components/LoginButton/index.tsx"],"sourcesContent":["'use client'\n\nimport { Button, useConfig } from '@payloadcms/ui'\nimport { useSearchParams } from 'next/navigation.js'\nimport React, { useEffect, useState } from 'react'\n\nimport './index.scss'\n\nconst baseClass = 'oauth-login'\n\ntype DefaultLoginButtonProps = {\n disabled?: boolean\n endpointSlug: string\n}\n\nexport const DefaultLoginButton: React.FC<DefaultLoginButtonProps> = ({\n disabled,\n endpointSlug,\n}: {\n disabled?: boolean\n endpointSlug: string\n}) => {\n const {\n config: {\n admin: { user: userSlug },\n routes: { api },\n serverURL,\n },\n } = useConfig()\n const [authorizeURL, setAuthorizeURL] = useState('')\n\n const searchParams = useSearchParams()\n const payloadRedirect = searchParams.get('redirect')\n\n useEffect(() => {\n if (payloadRedirect && !disabled) {\n // set cookie to redirect to the original page\n document.cookie = `payloadRedirect=${payloadRedirect}; path=/`\n }\n }, [payloadRedirect, disabled])\n\n useEffect(() => {\n const getAuthorizeURL = async () => {\n const serverURLFromWindow = window.location.origin\n const data = await fetch(\n `${serverURL}${api}/${userSlug}/${endpointSlug}/meta?serverURL=${serverURLFromWindow}`,\n ).then((res) => res.json())\n\n if (!disabled) {\n setAuthorizeURL(data.authorizeURL)\n }\n }\n\n void getAuthorizeURL()\n }, [api, serverURL, userSlug, disabled, endpointSlug])\n\n if (disabled) {\n return null\n }\n\n return (\n <div className={baseClass}>\n <Button className={`${baseClass}__btn`} el=\"anchor\" url={authorizeURL}>\n Log in\n </Button>\n </div>\n )\n}\n"],"names":["Button","useConfig","useSearchParams","React","useEffect","useState","baseClass","DefaultLoginButton","disabled","endpointSlug","config","admin","user","userSlug","routes","api","serverURL","authorizeURL","setAuthorizeURL","searchParams","payloadRedirect","get","document","cookie","getAuthorizeURL","serverURLFromWindow","window","location","origin","data","fetch","then","res","json","div","className","el","url"],"mappings":"AAAA;;AAEA,SAASA,MAAM,EAAEC,SAAS,QAAQ,iBAAgB;AAClD,SAASC,eAAe,QAAQ,qBAAoB;AACpD,OAAOC,SAASC,SAAS,EAAEC,QAAQ,QAAQ,QAAO;AAElD,OAAO,eAAc;AAErB,MAAMC,YAAY;AAOlB,OAAO,MAAMC,qBAAwD,CAAC,EACpEC,QAAQ,EACRC,YAAY,EAIb;IACC,MAAM,EACJC,QAAQ,EACNC,OAAO,EAAEC,MAAMC,QAAQ,EAAE,EACzBC,QAAQ,EAAEC,GAAG,EAAE,EACfC,SAAS,EACV,EACF,GAAGf;IACJ,MAAM,CAACgB,cAAcC,gBAAgB,GAAGb,SAAS;IAEjD,MAAMc,eAAejB;IACrB,MAAMkB,kBAAkBD,aAAaE,GAAG,CAAC;IAEzCjB,UAAU;QACR,IAAIgB,mBAAmB,CAACZ,UAAU;YAChC,8CAA8C;YAC9Cc,SAASC,MAAM,GAAG,CAAC,gBAAgB,EAAEH,gBAAgB,QAAQ,CAAC;QAChE;IACF,GAAG;QAACA;QAAiBZ;KAAS;IAE9BJ,UAAU;QACR,MAAMoB,kBAAkB;YACtB,MAAMC,sBAAsBC,OAAOC,QAAQ,CAACC,MAAM;YAClD,MAAMC,OAAO,MAAMC,MACjB,GAAGd,YAAYD,IAAI,CAAC,EAAEF,SAAS,CAAC,EAAEJ,aAAa,gBAAgB,EAAEgB,qBAAqB,EACtFM,IAAI,CAAC,CAACC,MAAQA,IAAIC,IAAI;YAExB,IAAI,CAACzB,UAAU;gBACbU,gBAAgBW,KAAKZ,YAAY;YACnC;QACF;QAEA,KAAKO;IACP,GAAG;QAACT;QAAKC;QAAWH;QAAUL;QAAUC;KAAa;IAErD,IAAID,UAAU;QACZ,OAAO;IACT;IAEA,qBACE,KAAC0B;QAAIC,WAAW7B;kBACd,cAAA,KAACN;YAAOmC,WAAW,GAAG7B,UAAU,KAAK,CAAC;YAAE8B,IAAG;YAASC,KAAKpB;sBAAc;;;AAK7E,EAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../../src/oauth/components/LogoutButton/index.tsx"],"names":[],"mappings":"AAGA,OAAO,KAAK,MAAM,OAAO,CAAA;AAGzB,OAAO,cAAc,CAAA;AAIrB,eAAO,MAAM,YAAY,EAAE,KAAK,CAAC,EAAE,CAAC;IAAE,QAAQ,CAAC,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,CA2D/E,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/oauth/components/LogoutButton/index.tsx"],"sourcesContent":["'use client'\n\nimport { Logout, useConfig } from '@payloadcms/ui'\nimport React from 'react'\n\nimport { getAdminPath } from '../../utilities/getAdminPath.js'\nimport './index.scss'\n\nconst baseClass = 'oauth-logout'\n\nexport const LogoutButton: React.FC<{ disabled?: boolean; endpointSlug: string }> = ({\n disabled,\n endpointSlug,\n}) => {\n const {\n config,\n config: {\n admin: { user: userSlug },\n routes: { api },\n serverURL,\n },\n } = useConfig()\n\n const [redirect, setRedirect] = React.useState('')\n React.useEffect(() => {\n const protocol = window.location.protocol\n const domain = window.location.hostname\n const port = window.location.port\n\n let redirectToSet = `${protocol}//${domain}`\n if (port) {\n redirectToSet += `:${port}`\n }\n\n redirectToSet += getAdminPath(config)\n\n // eslint-disable-next-line @eslint-react/hooks-extra/no-direct-set-state-in-use-effect\n setRedirect(redirectToSet)\n }, [config])\n\n if (!redirect) {\n return null\n }\n\n if (disabled) {\n return <Logout />\n }\n\n return (\n <div className={baseClass}>\n <a\n aria-label=\"Logout\"\n href={`${serverURL}${api}/${userSlug}/${endpointSlug}/logout?redirect=${redirect}`}\n >\n <svg\n className=\"icon icon--logout\"\n fill=\"none\"\n viewBox=\"0 0 25 25\"\n xmlns=\"http://www.w3.org/2000/svg\"\n >\n <path className=\"stroke\" d=\"M10 5H18V19H10\" />\n <g>\n <path className=\"stroke\" d=\"M8 8.5L4.46447 12.0355L8 15.5711\" />\n <line className=\"stroke\" x1=\"5\" x2=\"13\" y1=\"12\" y2=\"12\" />\n </g>\n </svg>\n </a>\n </div>\n )\n}\n"],"names":["Logout","useConfig","React","getAdminPath","baseClass","LogoutButton","disabled","endpointSlug","config","admin","user","userSlug","routes","api","serverURL","redirect","setRedirect","useState","useEffect","protocol","window","location","domain","hostname","port","redirectToSet","div","className","a","aria-label","href","svg","fill","viewBox","xmlns","path","d","g","line","x1","x2","y1","y2"],"mappings":"AAAA;;AAEA,SAASA,MAAM,EAAEC,SAAS,QAAQ,iBAAgB;AAClD,OAAOC,WAAW,QAAO;AAEzB,SAASC,YAAY,QAAQ,kCAAiC;AAC9D,OAAO,eAAc;AAErB,MAAMC,YAAY;AAElB,OAAO,MAAMC,eAAuE,CAAC,EACnFC,QAAQ,EACRC,YAAY,EACb;IACC,MAAM,EACJC,MAAM,EACNA,QAAQ,EACNC,OAAO,EAAEC,MAAMC,QAAQ,EAAE,EACzBC,QAAQ,EAAEC,GAAG,EAAE,EACfC,SAAS,EACV,EACF,GAAGb;IAEJ,MAAM,CAACc,UAAUC,YAAY,GAAGd,MAAMe,QAAQ,CAAC;IAC/Cf,MAAMgB,SAAS,CAAC;QACd,MAAMC,WAAWC,OAAOC,QAAQ,CAACF,QAAQ;QACzC,MAAMG,SAASF,OAAOC,QAAQ,CAACE,QAAQ;QACvC,MAAMC,OAAOJ,OAAOC,QAAQ,CAACG,IAAI;QAEjC,IAAIC,gBAAgB,GAAGN,SAAS,EAAE,EAAEG,QAAQ;QAC5C,IAAIE,MAAM;YACRC,iBAAiB,CAAC,CAAC,EAAED,MAAM;QAC7B;QAEAC,iBAAiBtB,aAAaK;QAE9B,uFAAuF;QACvFQ,YAAYS;IACd,GAAG;QAACjB;KAAO;IAEX,IAAI,CAACO,UAAU;QACb,OAAO;IACT;IAEA,IAAIT,UAAU;QACZ,qBAAO,KAACN;IACV;IAEA,qBACE,KAAC0B;QAAIC,WAAWvB;kBACd,cAAA,KAACwB;YACCC,cAAW;YACXC,MAAM,GAAGhB,YAAYD,IAAI,CAAC,EAAEF,SAAS,CAAC,EAAEJ,aAAa,iBAAiB,EAAEQ,UAAU;sBAElF,cAAA,MAACgB;gBACCJ,WAAU;gBACVK,MAAK;gBACLC,SAAQ;gBACRC,OAAM;;kCAEN,KAACC;wBAAKR,WAAU;wBAASS,GAAE;;kCAC3B,MAACC;;0CACC,KAACF;gCAAKR,WAAU;gCAASS,GAAE;;0CAC3B,KAACE;gCAAKX,WAAU;gCAASY,IAAG;gCAAIC,IAAG;gCAAKC,IAAG;gCAAKC,IAAG;;;;;;;;AAM/D,EAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"defaults.d.ts","sourceRoot":"","sources":["../../src/oauth/defaults.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,UAAU,EAAE,SAAS,EAAQ,MAAM,SAAS,CAAA;AAI5E,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAA;AAIhD,eAAO,MAAM,YAAY,UAAiC,CAAA;AAE1D,eAAO,MAAM,oBAAoB,EAAE,SAQlC,CAAA;AAED,eAAO,MAAM,aAAa,iDAKrB;IACD,UAAU,EAAE,gBAAgB,CAAA;IAC5B,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,UAAU,GAAG,SAAS,CAAA;CACtC,KAAG,cAiFH,CAAA"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/oauth/defaults.ts"],"sourcesContent":["import type { CollectionConfig, EmailField, TextField, User } from 'payload'\n\nimport { v4 as uuid } from 'uuid'\n\nimport type { VerifyFunction } from './types.js'\n\nimport { hasUserTokenPropsChanged } from './utilities/hasUserTokenPropsChanged.js'\n\nexport const defaultScope = ['openid', 'profile', 'email']\n\nexport const defaultUsernameField: TextField = {\n name: 'preferredUsername',\n type: 'text',\n admin: {\n position: 'sidebar',\n readOnly: true,\n },\n unique: true,\n}\n\nexport const defaultVerify =\n ({\n collection,\n strategyName,\n usernameField,\n }: {\n collection: CollectionConfig\n strategyName: string\n usernameField: EmailField | TextField\n }): VerifyFunction =>\n async ({ payload, token }) => {\n let tokenUsername = 'preferred_username'\n\n if (usernameField.name !== 'preferredUsername') {\n tokenUsername = usernameField.name\n }\n\n if (!token[tokenUsername]) {\n return {\n user: null,\n }\n }\n\n let user: null | User = null\n const depth = typeof collection.auth === 'object' ? collection.auth.depth : undefined\n\n try {\n const results = await payload.find({\n collection: collection.slug,\n depth,\n limit: 1,\n pagination: false,\n where: {\n [usernameField.name]: { equals: token[tokenUsername] },\n },\n })\n\n if (results.docs.length > 0) {\n user = results.docs[0] as User\n // Update user with new token data\n if (hasUserTokenPropsChanged(user, token)) {\n user = (await payload.update({\n id: user.id,\n collection: collection.slug,\n data: {\n ...token,\n },\n depth,\n })) as User\n }\n } else {\n const newUser = {\n email: token.preferredUsername || token.email,\n [usernameField.name]: token[tokenUsername],\n ...token,\n }\n\n if (typeof collection.auth === 'object' && !collection.auth.disableLocalStrategy) {\n newUser.password = uuid()\n }\n\n user = (await payload.create({\n collection: collection.slug,\n data: newUser,\n depth,\n })) as User\n }\n } catch (err: unknown) {\n payload.logger.error({\n err,\n msg: 'Error verifying user from defaultVerify.',\n })\n return {\n user: null,\n }\n }\n\n if (user) {\n user.collection = collection.slug\n user._strategy = strategyName\n user.exp = token.exp\n\n return {\n user,\n }\n }\n\n return {\n user: null,\n }\n }\n"],"names":["v4","uuid","hasUserTokenPropsChanged","defaultScope","defaultUsernameField","name","type","admin","position","readOnly","unique","defaultVerify","collection","strategyName","usernameField","payload","token","tokenUsername","user","depth","auth","undefined","results","find","slug","limit","pagination","where","equals","docs","length","update","id","data","newUser","email","preferredUsername","disableLocalStrategy","password","create","err","logger","error","msg","_strategy","exp"],"mappings":"AAEA,SAASA,MAAMC,IAAI,QAAQ,OAAM;AAIjC,SAASC,wBAAwB,QAAQ,0CAAyC;AAElF,OAAO,MAAMC,eAAe;IAAC;IAAU;IAAW;CAAQ,CAAA;AAE1D,OAAO,MAAMC,uBAAkC;IAC7CC,MAAM;IACNC,MAAM;IACNC,OAAO;QACLC,UAAU;QACVC,UAAU;IACZ;IACAC,QAAQ;AACV,EAAC;AAED,OAAO,MAAMC,gBACX,CAAC,EACCC,UAAU,EACVC,YAAY,EACZC,aAAa,EAKd,GACD,OAAO,EAAEC,OAAO,EAAEC,KAAK,EAAE;QACvB,IAAIC,gBAAgB;QAEpB,IAAIH,cAAcT,IAAI,KAAK,qBAAqB;YAC9CY,gBAAgBH,cAAcT,IAAI;QACpC;QAEA,IAAI,CAACW,KAAK,CAACC,cAAc,EAAE;YACzB,OAAO;gBACLC,MAAM;YACR;QACF;QAEA,IAAIA,OAAoB;QACxB,MAAMC,QAAQ,OAAOP,WAAWQ,IAAI,KAAK,WAAWR,WAAWQ,IAAI,CAACD,KAAK,GAAGE;QAE5E,IAAI;YACF,MAAMC,UAAU,MAAMP,QAAQQ,IAAI,CAAC;gBACjCX,YAAYA,WAAWY,IAAI;gBAC3BL;gBACAM,OAAO;gBACPC,YAAY;gBACZC,OAAO;oBACL,CAACb,cAAcT,IAAI,CAAC,EAAE;wBAAEuB,QAAQZ,KAAK,CAACC,cAAc;oBAAC;gBACvD;YACF;YAEA,IAAIK,QAAQO,IAAI,CAACC,MAAM,GAAG,GAAG;gBAC3BZ,OAAOI,QAAQO,IAAI,CAAC,EAAE;gBACtB,kCAAkC;gBAClC,IAAI3B,yBAAyBgB,MAAMF,QAAQ;oBACzCE,OAAQ,MAAMH,QAAQgB,MAAM,CAAC;wBAC3BC,IAAId,KAAKc,EAAE;wBACXpB,YAAYA,WAAWY,IAAI;wBAC3BS,MAAM;4BACJ,GAAGjB,KAAK;wBACV;wBACAG;oBACF;gBACF;YACF,OAAO;gBACL,MAAMe,UAAU;oBACdC,OAAOnB,MAAMoB,iBAAiB,IAAIpB,MAAMmB,KAAK;oBAC7C,CAACrB,cAAcT,IAAI,CAAC,EAAEW,KAAK,CAACC,cAAc;oBAC1C,GAAGD,KAAK;gBACV;gBAEA,IAAI,OAAOJ,WAAWQ,IAAI,KAAK,YAAY,CAACR,WAAWQ,IAAI,CAACiB,oBAAoB,EAAE;oBAChFH,QAAQI,QAAQ,GAAGrC;gBACrB;gBAEAiB,OAAQ,MAAMH,QAAQwB,MAAM,CAAC;oBAC3B3B,YAAYA,WAAWY,IAAI;oBAC3BS,MAAMC;oBACNf;gBACF;YACF;QACF,EAAE,OAAOqB,KAAc;YACrBzB,QAAQ0B,MAAM,CAACC,KAAK,CAAC;gBACnBF;gBACAG,KAAK;YACP;YACA,OAAO;gBACLzB,MAAM;YACR;QACF;QAEA,IAAIA,MAAM;YACRA,KAAKN,UAAU,GAAGA,WAAWY,IAAI;YACjCN,KAAK0B,SAAS,GAAG/B;YACjBK,KAAK2B,GAAG,GAAG7B,MAAM6B,GAAG;YAEpB,OAAO;gBACL3B;YACF;QACF;QAEA,OAAO;YACLA,MAAM;QACR;IACF,EAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"getLoginEndpoint.d.ts","sourceRoot":"","sources":["../../../src/oauth/endpoints/getLoginEndpoint.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,gBAAgB,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAA;AAMzD,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,sBAAsB,CAAA;AACpD,OAAO,KAAK,EAEV,iBAAiB,EACjB,aAAa,EAEd,MAAM,aAAa,CAAA;AAcpB,UAAU,IAAI;IACZ,UAAU,EAAE,gBAAgB,CAAA;IAC5B,iBAAiB,EAAE,iBAAiB,CAAA;IACpC,YAAY,EAAE,MAAM,CAAA;IACpB,aAAa,EAAE,aAAa,CAAA;IAC5B,QAAQ,EAAE,QAAQ,CAAA;CACnB;AAID,eAAO,MAAM,gBAAgB,8EAM1B,IAAI,KAAG,QA+OR,CAAA"}
|