@payloadcms/figma 0.0.1-alpha.9 → 0.1.0-alpha.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/control-plane.d.ts +56 -7
- package/dist/api/control-plane.js +188 -74
- package/dist/api/error-response.d.ts +36 -0
- package/dist/api/error-response.js +66 -0
- package/dist/api/figma-api.d.ts +24 -3
- package/dist/api/figma-api.js +110 -34
- package/dist/auth/browser.d.ts +0 -1
- package/dist/auth/browser.js +0 -2
- package/dist/auth/callback-server.d.ts +19 -8
- package/dist/auth/callback-server.js +72 -32
- package/dist/auth/credentials.d.ts +20 -0
- package/dist/auth/credentials.js +19 -0
- package/dist/auth/crypto-utils.d.ts +28 -1
- package/dist/auth/crypto-utils.js +132 -23
- package/dist/auth/jwt-validator.d.ts +23 -6
- package/dist/auth/jwt-validator.js +35 -9
- package/dist/auth/oauth-flow.d.ts +19 -4
- package/dist/auth/oauth-flow.js +151 -34
- package/dist/auth/paste-code.d.ts +33 -0
- package/dist/auth/paste-code.js +87 -0
- package/dist/auth/pkce.d.ts +0 -1
- package/dist/auth/pkce.js +0 -2
- package/dist/auth/project-token.d.ts +32 -17
- package/dist/auth/project-token.js +176 -68
- package/dist/auth/refresh.d.ts +2 -2
- package/dist/auth/refresh.js +25 -14
- package/dist/auth/token-store-migration.d.ts +57 -0
- package/dist/auth/token-store-migration.js +154 -0
- package/dist/auth/token-store.d.ts +63 -98
- package/dist/auth/token-store.js +405 -124
- package/dist/auth/types.d.ts +40 -6
- package/dist/auth/types.js +1 -3
- package/dist/cli.d.ts +0 -1
- package/dist/cli.js +102 -8
- package/dist/commands/bootstrap.d.ts +17 -0
- package/dist/commands/bootstrap.js +88 -0
- package/dist/commands/build-lambda-zip.d.ts +4 -0
- package/dist/commands/build-lambda-zip.js +17 -0
- package/dist/commands/debug.d.ts +7 -0
- package/dist/commands/debug.js +178 -0
- package/dist/commands/deploy.d.ts +11 -1
- package/dist/commands/deploy.js +193 -153
- package/dist/commands/dump-tokens.d.ts +11 -0
- package/dist/commands/dump-tokens.js +67 -0
- package/dist/commands/env.d.ts +12 -0
- package/dist/commands/env.js +86 -0
- package/dist/commands/init.d.ts +9 -6
- package/dist/commands/init.js +232 -152
- package/dist/commands/list-tokens.d.ts +3 -4
- package/dist/commands/list-tokens.js +24 -11
- package/dist/commands/login.d.ts +8 -2
- package/dist/commands/login.js +34 -18
- package/dist/commands/logout.d.ts +5 -5
- package/dist/commands/logout.js +77 -17
- package/dist/commands/upgrade.d.ts +4 -0
- package/dist/commands/upgrade.js +329 -0
- package/dist/commands/upload-schema.d.ts +8 -0
- package/dist/commands/upload-schema.js +91 -0
- package/dist/config/oauth.d.ts +17 -12
- package/dist/config/oauth.js +38 -39
- package/dist/constants.d.ts +63 -19
- package/dist/constants.js +158 -20
- package/dist/db-content-api/generated/content-api-types.d.ts +8215 -0
- package/dist/db-content-api/generated/content-api-types.js +5 -0
- package/dist/db-content-api/index.d.ts +40 -0
- package/dist/db-content-api/index.js +883 -0
- package/dist/db-content-api/temp-utilities/slug.d.ts +1 -0
- package/dist/db-content-api/temp-utilities/slug.js +1 -0
- package/dist/db-content-api/temp-utilities/sorting.d.ts +2 -0
- package/dist/db-content-api/temp-utilities/sorting.js +37 -0
- package/dist/db-content-api/temp-utilities/types.d.ts +21 -0
- package/dist/db-content-api/temp-utilities/types.js +13 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +38 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.js +62 -0
- package/dist/db-content-api/utilities/auth.d.ts +29 -0
- package/dist/db-content-api/utilities/auth.js +82 -0
- package/dist/db-content-api/utilities/clientVersionHeaders.d.ts +7 -0
- package/dist/db-content-api/utilities/clientVersionHeaders.js +15 -0
- package/dist/db-content-api/utilities/data/applyDefaults.d.ts +6 -0
- package/dist/db-content-api/utilities/data/applyDefaults.js +75 -0
- package/dist/db-content-api/utilities/data/atomicOperations.d.ts +16 -0
- package/dist/db-content-api/utilities/data/atomicOperations.js +48 -0
- package/dist/db-content-api/utilities/data/castFieldValue.d.ts +10 -0
- package/dist/db-content-api/utilities/data/castFieldValue.js +66 -0
- package/dist/db-content-api/utilities/data/convertRelationshipIds.d.ts +25 -0
- package/dist/db-content-api/utilities/data/convertRelationshipIds.js +109 -0
- package/dist/db-content-api/utilities/data/index.d.ts +48 -0
- package/dist/db-content-api/utilities/data/index.js +315 -0
- package/dist/db-content-api/utilities/data/isLocaleMap.d.ts +10 -0
- package/dist/db-content-api/utilities/data/isLocaleMap.js +13 -0
- package/dist/db-content-api/utilities/data/pointShape.d.ts +3 -0
- package/dist/db-content-api/utilities/data/pointShape.js +43 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +11 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.js +52 -0
- package/dist/db-content-api/utilities/data/resolveFieldLocalization.d.ts +18 -0
- package/dist/db-content-api/utilities/data/resolveFieldLocalization.js +21 -0
- package/dist/db-content-api/utilities/data/richTextShape.d.ts +3 -0
- package/dist/db-content-api/utilities/data/richTextShape.js +56 -0
- package/dist/db-content-api/utilities/data/stripFields.d.ts +47 -0
- package/dist/db-content-api/utilities/data/stripFields.js +170 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +22 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.js +40 -0
- package/dist/db-content-api/utilities/data/validateRelationships.d.ts +6 -0
- package/dist/db-content-api/utilities/data/validateRelationships.js +107 -0
- package/dist/db-content-api/utilities/joins.d.ts +50 -0
- package/dist/db-content-api/utilities/joins.js +124 -0
- package/dist/db-content-api/utilities/locale/index.d.ts +9 -0
- package/dist/db-content-api/utilities/locale/index.js +19 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.d.ts +9 -0
- package/dist/db-content-api/utilities/meta/normalizeLocaleInWhere.js +100 -0
- package/dist/db-content-api/utilities/resolveBlocks.d.ts +19 -0
- package/dist/db-content-api/utilities/resolveBlocks.js +31 -0
- package/dist/db-content-api/utilities/schema/buildDocumentSchema.d.ts +72 -0
- package/dist/db-content-api/utilities/schema/buildDocumentSchema.js +264 -0
- package/dist/db-content-api/utilities/where.d.ts +9 -0
- package/dist/db-content-api/utilities/where.js +95 -0
- package/dist/deploy/schedule-extract-plugin.d.ts +10 -0
- package/dist/deploy/schedule-extract-plugin.js +32 -0
- package/dist/endpoints/health.d.ts +2 -0
- package/dist/endpoints/health.js +9 -0
- package/dist/endpoints/schema.d.ts +2 -0
- package/dist/endpoints/schema.js +27 -0
- package/dist/exports/client.d.ts +2 -1
- package/dist/exports/client.js +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +3 -3
- package/dist/lib/download-skill.d.ts +12 -0
- package/dist/lib/download-skill.js +77 -0
- package/dist/oauth/components/FigmaAvatar/index.d.ts +3 -0
- package/dist/oauth/components/FigmaAvatar/index.js +25 -0
- package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
- package/dist/oauth/components/FigmaAvatarCell/index.d.ts +4 -0
- package/dist/oauth/components/FigmaAvatarCell/index.js +23 -0
- package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +8 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +35 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
- package/dist/oauth/components/LoginButton/iframeAutoLogin.d.ts +81 -0
- package/dist/oauth/components/LoginButton/iframeAutoLogin.js +168 -0
- package/dist/oauth/components/LoginButton/index.d.ts +0 -1
- package/dist/oauth/components/LoginButton/index.js +156 -18
- package/dist/oauth/components/LoginButton/index.scss +75 -3
- package/dist/oauth/components/LogoutButton/index.d.ts +0 -1
- package/dist/oauth/components/LogoutButton/index.js +20 -9
- package/dist/oauth/defaults.d.ts +3 -2
- package/dist/oauth/defaults.js +79 -12
- package/dist/oauth/endpoints/getLoginEndpoint.d.ts +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.js +87 -84
- package/dist/oauth/endpoints/getLogoutEndpoint.d.ts +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -6
- package/dist/oauth/endpoints/getMetaEndpoint.d.ts +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.js +18 -5
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js +11 -4
- package/dist/oauth/exports/client.d.ts +0 -1
- package/dist/oauth/exports/client.js +0 -2
- package/dist/oauth/hooks/afterLogout.d.ts +0 -1
- package/dist/oauth/hooks/afterLogout.js +0 -2
- package/dist/oauth/hooks/me.d.ts +0 -1
- package/dist/oauth/hooks/me.js +0 -2
- package/dist/oauth/hooks/refresh.d.ts +0 -1
- package/dist/oauth/hooks/refresh.js +2 -3
- package/dist/oauth/index.d.ts +0 -1
- package/dist/oauth/index.js +27 -7
- package/dist/oauth/strategy/index.d.ts +0 -3
- package/dist/oauth/strategy/index.js +55 -34
- package/dist/oauth/types.d.ts +23 -7
- package/dist/oauth/types.js +0 -2
- package/dist/oauth/utilities/buildUnauthorizedRedirect.d.ts +14 -0
- package/dist/oauth/utilities/buildUnauthorizedRedirect.js +28 -0
- package/dist/oauth/utilities/clearCookie.d.ts +0 -1
- package/dist/oauth/utilities/clearCookie.js +5 -3
- package/dist/oauth/utilities/createCookieOptions.d.ts +0 -1
- package/dist/oauth/utilities/createCookieOptions.js +9 -4
- package/dist/oauth/utilities/createDebugLogger.d.ts +0 -1
- package/dist/oauth/utilities/createDebugLogger.js +0 -2
- package/dist/oauth/utilities/establishSession.d.ts +22 -0
- package/dist/oauth/utilities/establishSession.js +80 -0
- package/dist/oauth/utilities/exchangeCodeForAccessToken.d.ts +23 -0
- package/dist/oauth/utilities/exchangeCodeForAccessToken.js +26 -0
- package/dist/oauth/utilities/extractOrigin.d.ts +0 -1
- package/dist/oauth/utilities/extractOrigin.js +0 -2
- package/dist/oauth/utilities/figmaHostnames.d.ts +2 -0
- package/dist/oauth/utilities/figmaHostnames.js +24 -0
- package/dist/oauth/utilities/getAdminCollectionSlug.d.ts +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.js +0 -2
- package/dist/oauth/utilities/getAuthorizeURL.d.ts +65 -2
- package/dist/oauth/utilities/getAuthorizeURL.js +57 -4
- package/dist/oauth/utilities/getCookieExpiration.d.ts +0 -1
- package/dist/oauth/utilities/getCookieExpiration.js +0 -2
- package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.js +0 -2
- package/dist/oauth/utilities/getTokenExp.d.ts +0 -1
- package/dist/oauth/utilities/getTokenExp.js +0 -2
- package/dist/oauth/utilities/getUsernameField.d.ts +0 -1
- package/dist/oauth/utilities/getUsernameField.js +0 -2
- package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.js +0 -2
- package/dist/oauth/utilities/isAbsoluteURL.d.ts +1 -0
- package/dist/oauth/utilities/isAbsoluteURL.js +1 -0
- package/dist/oauth/utilities/isDuplicateKeyError.d.ts +6 -0
- package/dist/oauth/utilities/isDuplicateKeyError.js +12 -0
- package/dist/oauth/utilities/mergeHeaders.d.ts +0 -1
- package/dist/oauth/utilities/mergeHeaders.js +0 -2
- package/dist/oauth/utilities/refreshTokens.d.ts +0 -1
- package/dist/oauth/utilities/refreshTokens.js +21 -13
- package/dist/oauth/utilities/withPartitionedCookie.d.ts +19 -0
- package/dist/oauth/utilities/withPartitionedCookie.js +26 -0
- package/dist/oauth/utils/getSearchParam.d.ts +17 -0
- package/dist/oauth/utils/getSearchParam.js +22 -0
- package/dist/plugin/adapter.d.ts +0 -1
- package/dist/plugin/adapter.js +0 -2
- package/dist/plugin/auth-preflight.d.ts +7 -0
- package/dist/plugin/auth-preflight.js +18 -0
- package/dist/plugin/bootstrap-preflight.d.ts +22 -0
- package/dist/plugin/bootstrap-preflight.js +43 -0
- package/dist/plugin/build-config.d.ts +27 -15
- package/dist/plugin/build-config.js +380 -16
- package/dist/plugin/dev-cookie-names.d.ts +13 -0
- package/dist/plugin/dev-cookie-names.js +17 -0
- package/dist/scss.d.js +2 -0
- package/dist/storage-content-api/api-types.d.ts +183 -0
- package/dist/storage-content-api/api-types.js +4 -0
- package/dist/storage-content-api/client-uploads/generate.d.ts +14 -0
- package/dist/storage-content-api/client-uploads/generate.js +69 -0
- package/dist/storage-content-api/client.d.ts +5 -0
- package/dist/storage-content-api/client.js +37 -0
- package/dist/storage-content-api/generateURL.d.ts +6 -0
- package/dist/storage-content-api/generateURL.js +6 -0
- package/dist/storage-content-api/handleDelete.d.ts +7 -0
- package/dist/storage-content-api/handleDelete.js +15 -0
- package/dist/storage-content-api/handleUpload.d.ts +10 -0
- package/dist/storage-content-api/handleUpload.js +162 -0
- package/dist/storage-content-api/index.d.ts +4 -0
- package/dist/storage-content-api/index.js +37 -0
- package/dist/storage-content-api/staticHandler.d.ts +9 -0
- package/dist/storage-content-api/staticHandler.js +61 -0
- package/dist/storage-content-api/types.d.ts +9 -0
- package/dist/storage-content-api/types.js +1 -0
- package/dist/storage-content-api/utilities/getSafeFilename.d.ts +11 -0
- package/dist/storage-content-api/utilities/getSafeFilename.js +59 -0
- package/dist/storage-content-api/utilities/index.d.ts +2 -0
- package/dist/storage-content-api/utilities/index.js +2 -0
- package/dist/storage-content-api/utilities/parseUploadReference.d.ts +17 -0
- package/dist/storage-content-api/utilities/parseUploadReference.js +27 -0
- package/dist/templates/.env.example +5 -0
- package/dist/templates/README.md +19 -0
- package/dist/types/config.d.ts +2 -2
- package/dist/types/config.js +0 -4
- package/dist/types.d.ts +10 -2
- package/dist/types.js +0 -2
- package/dist/utils/adapters/nextjs.d.ts +8 -0
- package/dist/utils/adapters/nextjs.js +61 -0
- package/dist/utils/adapters/nitro.d.ts +8 -0
- package/dist/utils/adapters/nitro.js +172 -0
- package/dist/utils/adapters/vite.d.ts +9 -0
- package/dist/utils/adapters/vite.js +31 -0
- package/dist/utils/asset-collection.d.ts +27 -7
- package/dist/utils/asset-collection.js +59 -32
- package/dist/utils/build-detection.d.ts +5 -12
- package/dist/utils/build-detection.js +74 -13
- package/dist/utils/build-lambda-zip.d.ts +25 -0
- package/dist/utils/build-lambda-zip.js +90 -0
- package/dist/utils/cache-bootstrap.d.ts +7 -0
- package/dist/utils/cache-bootstrap.js +16 -0
- package/dist/utils/config.d.ts +0 -1
- package/dist/utils/config.js +1 -3
- package/dist/utils/deploy-adapter.d.ts +45 -0
- package/dist/utils/deploy-adapter.js +56 -0
- package/dist/utils/download-template.d.ts +9 -2
- package/dist/utils/download-template.js +24 -20
- package/dist/utils/env-management.d.ts +24 -8
- package/dist/utils/env-management.js +119 -66
- package/dist/utils/format-env-suffix.d.ts +11 -0
- package/dist/utils/format-env-suffix.js +11 -0
- package/dist/utils/format.d.ts +0 -1
- package/dist/utils/format.js +0 -2
- package/dist/utils/formatter.d.ts +0 -1
- package/dist/utils/formatter.js +23 -13
- package/dist/utils/fs-utils.d.ts +12 -0
- package/dist/utils/fs-utils.js +55 -0
- package/dist/utils/git.d.ts +0 -1
- package/dist/utils/git.js +0 -2
- package/dist/utils/handle-upgrade.d.ts +8 -0
- package/dist/utils/handle-upgrade.js +39 -0
- package/dist/utils/is-debug.d.ts +0 -1
- package/dist/utils/is-debug.js +0 -2
- package/dist/utils/lambda-config.d.ts +3 -2
- package/dist/utils/lambda-config.js +75 -80
- package/dist/utils/load-payload-config.d.ts +9 -0
- package/dist/utils/load-payload-config.js +27 -0
- package/dist/utils/log.d.ts +0 -1
- package/dist/utils/log.js +0 -2
- package/dist/utils/messages.d.ts +1 -3
- package/dist/utils/messages.js +47 -13
- package/dist/utils/package-manager.d.ts +24 -1
- package/dist/utils/package-manager.js +53 -2
- package/dist/utils/parse-template-spec.d.ts +11 -0
- package/dist/utils/parse-template-spec.js +60 -0
- package/dist/utils/payload-config-ast.d.ts +27 -7
- package/dist/utils/payload-config-ast.js +106 -60
- package/dist/utils/payload-config-finder.d.ts +2 -3
- package/dist/utils/payload-config-finder.js +48 -11
- package/dist/utils/payload-config-modifier.d.ts +1 -2
- package/dist/utils/payload-config-modifier.js +114 -68
- package/dist/utils/payload-package-check.d.ts +28 -3
- package/dist/utils/payload-package-check.js +90 -31
- package/dist/utils/project.d.ts +8 -4
- package/dist/utils/project.js +63 -37
- package/dist/utils/resolve-environment.d.ts +13 -0
- package/dist/utils/resolve-environment.js +29 -0
- package/dist/utils/s3-upload.d.ts +7 -3
- package/dist/utils/s3-upload.js +44 -9
- package/dist/utils/token-display.d.ts +5 -2
- package/dist/utils/token-display.js +49 -24
- package/dist/utils/typescript-validator.d.ts +0 -1
- package/dist/utils/typescript-validator.js +4 -8
- package/dist/utils/version-check.d.ts +2 -0
- package/dist/utils/version-check.js +43 -0
- package/package.json +47 -16
- 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
package/dist/api/figma-api.js
CHANGED
|
@@ -3,7 +3,10 @@
|
|
|
3
3
|
*
|
|
4
4
|
* Client for Figma REST API (Pixie) endpoints
|
|
5
5
|
* Handles project token generation and other CMS-related API calls
|
|
6
|
-
*/ import
|
|
6
|
+
*/ import { getAuthHeaders } from '../auth/credentials.js';
|
|
7
|
+
import { getEnvConfig } from '../constants.js';
|
|
8
|
+
import * as log from '../utils/log.js';
|
|
9
|
+
import { parseControlPlaneApiError } from './error-response.js';
|
|
7
10
|
/**
|
|
8
11
|
* Error thrown when Figma API calls fail
|
|
9
12
|
*/ export class FigmaApiError extends Error {
|
|
@@ -14,19 +17,6 @@
|
|
|
14
17
|
this.name = 'FigmaApiError';
|
|
15
18
|
}
|
|
16
19
|
}
|
|
17
|
-
/**
|
|
18
|
-
* Base URLs for Figma API
|
|
19
|
-
*/ const API_BASE_URLS = {
|
|
20
|
-
prod: 'https://api.figma.com',
|
|
21
|
-
staging: 'https://api.staging.figma.com'
|
|
22
|
-
};
|
|
23
|
-
/**
|
|
24
|
-
* Get the Figma API base URL based on environment
|
|
25
|
-
* TODO: Use this once real API endpoints are available
|
|
26
|
-
*/ function _getApiBaseUrl() {
|
|
27
|
-
// For now, default to staging to match OAuth config
|
|
28
|
-
return process.env.FIGMA_API_BASE_URL || API_BASE_URLS.staging;
|
|
29
|
-
}
|
|
30
20
|
/**
|
|
31
21
|
* Get a project token (JWT) for a specific tenant/CMS
|
|
32
22
|
*
|
|
@@ -34,21 +24,49 @@
|
|
|
34
24
|
* requests to the Content API. The token contains the CMS ID and
|
|
35
25
|
* user identifying information in its claims.
|
|
36
26
|
*
|
|
37
|
-
* Endpoint:
|
|
27
|
+
* Endpoint: POST https://api.figma.com/v1/cms/content-systems/:id/token/
|
|
38
28
|
*
|
|
39
29
|
* @param accessToken - OAuth access token for authentication
|
|
40
30
|
* @param tenantId - The tenant/CMS ID
|
|
41
31
|
* @returns ProjectToken with JWT and expiry information
|
|
42
32
|
* @throws {FigmaApiError} If the API call fails
|
|
43
|
-
*/ export async function getProjectToken(
|
|
44
|
-
// Check
|
|
33
|
+
*/ export async function getProjectToken(credential, tenantId) {
|
|
34
|
+
// Priority 1: Check for direct token value from environment
|
|
35
|
+
const envTokenValue = process.env.FIGMA_MOCK_PROJECT_TOKEN_VALUE;
|
|
36
|
+
if (envTokenValue) {
|
|
37
|
+
log.debug('Using direct project token from FIGMA_MOCK_PROJECT_TOKEN_VALUE');
|
|
38
|
+
try {
|
|
39
|
+
// Parse JWT payload to extract claims
|
|
40
|
+
const parts = envTokenValue.split('.');
|
|
41
|
+
if (parts.length !== 3) {
|
|
42
|
+
throw new Error('Invalid JWT format: must have 3 parts (header.payload.signature)');
|
|
43
|
+
}
|
|
44
|
+
const payload = parts[1];
|
|
45
|
+
const base64 = payload.replace(/-/g, '+').replace(/_/g, '/');
|
|
46
|
+
const paddedBase64 = base64.padEnd(base64.length + (4 - base64.length % 4) % 4, '=');
|
|
47
|
+
const decodedPayload = JSON.parse(Buffer.from(paddedBase64, 'base64').toString('utf-8'));
|
|
48
|
+
if (!decodedPayload.exp || typeof decodedPayload.exp !== 'number') {
|
|
49
|
+
throw new Error('JWT payload missing exp claim');
|
|
50
|
+
}
|
|
51
|
+
// Extract tenant ID from aud claim (use parameter as fallback)
|
|
52
|
+
const extractedTenantId = decodedPayload.aud || tenantId;
|
|
53
|
+
return {
|
|
54
|
+
expiresAt: decodedPayload.exp * 1000,
|
|
55
|
+
tenantId: extractedTenantId,
|
|
56
|
+
token: envTokenValue
|
|
57
|
+
};
|
|
58
|
+
} catch (error) {
|
|
59
|
+
throw new FigmaApiError(`Invalid JWT token in FIGMA_MOCK_PROJECT_TOKEN_VALUE: ${error instanceof Error ? error.message : 'Unknown error'}`, undefined, error instanceof Error ? error : undefined);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
// Priority 2: Check if project token API should be mocked
|
|
45
63
|
// Default to false (use real API)
|
|
46
64
|
const shouldMock = process.env.FIGMA_MOCK_PROJECT_TOKEN === 'true';
|
|
47
65
|
try {
|
|
48
66
|
if (shouldMock) {
|
|
49
67
|
// MOCK IMPLEMENTATION: Generate a mock JWT token for testing
|
|
50
68
|
log.debug('Using mock project token API for getProjectToken (FIGMA_MOCK_PROJECT_TOKEN = "true")');
|
|
51
|
-
const mockToken = createMockJWT(tenantId
|
|
69
|
+
const mockToken = createMockJWT(`csid_${tenantId}`, 25) // 25 minutes expiry
|
|
52
70
|
;
|
|
53
71
|
// Mock response data
|
|
54
72
|
const data = {
|
|
@@ -68,24 +86,20 @@
|
|
|
68
86
|
};
|
|
69
87
|
}
|
|
70
88
|
// REAL API IMPLEMENTATION
|
|
71
|
-
const baseUrl =
|
|
72
|
-
const url = `${baseUrl}/v1/cms/${tenantId}/token/`;
|
|
89
|
+
const baseUrl = getEnvConfig().apiBaseUrl;
|
|
90
|
+
const url = `${baseUrl}/v1/cms/content-systems/${tenantId}/token/`;
|
|
73
91
|
const response = await fetch(url, {
|
|
74
|
-
headers:
|
|
75
|
-
Authorization: `Bearer ${accessToken}`
|
|
76
|
-
},
|
|
92
|
+
headers: getAuthHeaders(credential),
|
|
77
93
|
method: 'POST'
|
|
78
94
|
});
|
|
79
95
|
if (!response.ok) {
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
}
|
|
87
|
-
} catch {
|
|
88
|
-
// Ignore JSON parse errors for error body
|
|
96
|
+
let errorMessage = await parseControlPlaneApiError({
|
|
97
|
+
context: 'get project token',
|
|
98
|
+
response
|
|
99
|
+
});
|
|
100
|
+
// Provide an actionable error for the common misconfiguration case.
|
|
101
|
+
if (response.status === 404) {
|
|
102
|
+
errorMessage = `Content System ID "${tenantId}" not found. Ensure FIGMA_CONTENT_API_CONTENT_SYSTEM_ID is set to a valid content system ID in your .env file.`;
|
|
89
103
|
}
|
|
90
104
|
throw new FigmaApiError(errorMessage, response.status);
|
|
91
105
|
}
|
|
@@ -108,6 +122,36 @@
|
|
|
108
122
|
throw new FigmaApiError(`Failed to get project token: ${error instanceof Error ? error.message : 'Unknown error'}`, undefined, error instanceof Error ? error : undefined);
|
|
109
123
|
}
|
|
110
124
|
}
|
|
125
|
+
export async function getPayloadAdminToken(credential, environmentId) {
|
|
126
|
+
if (process.env.FIGMA_MOCK_PROJECT_TOKEN === 'true') {
|
|
127
|
+
const token = createMockJWT(`eid_${environmentId}`, 25);
|
|
128
|
+
return {
|
|
129
|
+
expiresAt: parseJwtExpiry(token),
|
|
130
|
+
tenantId: environmentId,
|
|
131
|
+
token
|
|
132
|
+
};
|
|
133
|
+
}
|
|
134
|
+
const baseUrl = getEnvConfig().apiBaseUrl;
|
|
135
|
+
const response = await fetch(`${baseUrl}/v1/cms/environments/${environmentId}/admin-token`, {
|
|
136
|
+
headers: getAuthHeaders(credential),
|
|
137
|
+
method: 'POST'
|
|
138
|
+
});
|
|
139
|
+
if (!response.ok) {
|
|
140
|
+
throw new FigmaApiError(await parseControlPlaneApiError({
|
|
141
|
+
context: 'get Payload Admin token',
|
|
142
|
+
response
|
|
143
|
+
}), response.status);
|
|
144
|
+
}
|
|
145
|
+
const data = await response.json();
|
|
146
|
+
if (!data.meta?.token) {
|
|
147
|
+
throw new FigmaApiError('Invalid response: missing token in meta');
|
|
148
|
+
}
|
|
149
|
+
return {
|
|
150
|
+
expiresAt: parseJwtExpiry(data.meta.token),
|
|
151
|
+
tenantId: environmentId,
|
|
152
|
+
token: data.meta.token
|
|
153
|
+
};
|
|
154
|
+
}
|
|
111
155
|
/**
|
|
112
156
|
* Create a mock JWT token for testing
|
|
113
157
|
* TODO: Remove this when real API is available
|
|
@@ -165,5 +209,37 @@
|
|
|
165
209
|
throw new FigmaApiError(`Failed to parse JWT expiry: ${error instanceof Error ? error.message : 'Unknown error'}`, undefined, error instanceof Error ? error : undefined);
|
|
166
210
|
}
|
|
167
211
|
}
|
|
168
|
-
|
|
169
|
-
|
|
212
|
+
/**
|
|
213
|
+
* Get user info from Figma API
|
|
214
|
+
*
|
|
215
|
+
* Endpoint: GET https://api.figma.com/v1/me
|
|
216
|
+
* Requires OAuth access_token (not project token)
|
|
217
|
+
*
|
|
218
|
+
* @param accessToken - OAuth access token for authentication
|
|
219
|
+
* @returns FigmaUserInfo with user profile data
|
|
220
|
+
* @throws {FigmaApiError} If the API call fails
|
|
221
|
+
*/ export async function getUserInfo(credential) {
|
|
222
|
+
const baseUrl = getEnvConfig().apiBaseUrl;
|
|
223
|
+
const url = `${baseUrl}/v1/me`;
|
|
224
|
+
try {
|
|
225
|
+
const response = await fetch(url, {
|
|
226
|
+
headers: getAuthHeaders(credential)
|
|
227
|
+
});
|
|
228
|
+
if (!response.ok) {
|
|
229
|
+
throw new FigmaApiError(await parseControlPlaneApiError({
|
|
230
|
+
context: 'get user info',
|
|
231
|
+
response
|
|
232
|
+
}), response.status);
|
|
233
|
+
}
|
|
234
|
+
const data = await response.json();
|
|
235
|
+
if (!data.id || !data.email || typeof data.handle !== 'string') {
|
|
236
|
+
throw new FigmaApiError('Invalid user info response: missing required fields');
|
|
237
|
+
}
|
|
238
|
+
return data;
|
|
239
|
+
} catch (error) {
|
|
240
|
+
if (error instanceof FigmaApiError) {
|
|
241
|
+
throw error;
|
|
242
|
+
}
|
|
243
|
+
throw new FigmaApiError(`Failed to get user info: ${error instanceof Error ? error.message : 'Unknown error'}`, undefined, error instanceof Error ? error : undefined);
|
|
244
|
+
}
|
|
245
|
+
}
|
package/dist/auth/browser.d.ts
CHANGED
package/dist/auth/browser.js
CHANGED
|
@@ -7,6 +7,14 @@ export interface CallbackResult {
|
|
|
7
7
|
/** State parameter for CSRF verification */
|
|
8
8
|
state: string;
|
|
9
9
|
}
|
|
10
|
+
export type CallbackServerOptions = {
|
|
11
|
+
/** Additional callback ports to try after port. */
|
|
12
|
+
fallbackPorts?: number[];
|
|
13
|
+
/** First callback port to try. Defaults to the configured callback port range. */
|
|
14
|
+
port?: number;
|
|
15
|
+
/** Callback timeout in milliseconds. */
|
|
16
|
+
timeoutMs?: number;
|
|
17
|
+
};
|
|
10
18
|
/**
|
|
11
19
|
* Error from OAuth callback
|
|
12
20
|
*/
|
|
@@ -20,18 +28,18 @@ export declare class CallbackError extends Error {
|
|
|
20
28
|
* Starts a temporary server on localhost to receive the OAuth authorization code.
|
|
21
29
|
* The server automatically shuts down after receiving the callback or on timeout.
|
|
22
30
|
*
|
|
23
|
-
*
|
|
24
|
-
* OS-assigned port
|
|
31
|
+
* Tries the registered localhost callback ports in order. It does not use an
|
|
32
|
+
* OS-assigned random port because OAuth redirect URIs must be registered.
|
|
25
33
|
*/
|
|
26
34
|
export declare class CallbackServer {
|
|
27
35
|
private actualPort?;
|
|
28
|
-
private
|
|
36
|
+
private callbackPorts;
|
|
37
|
+
private readyPromise;
|
|
38
|
+
private rejectReady?;
|
|
39
|
+
private resolveReady?;
|
|
29
40
|
private server;
|
|
30
41
|
private timeoutMs;
|
|
31
|
-
constructor(options?:
|
|
32
|
-
port?: number;
|
|
33
|
-
timeoutMs?: number;
|
|
34
|
-
});
|
|
42
|
+
constructor(options?: CallbackServerOptions);
|
|
35
43
|
/**
|
|
36
44
|
* Render error page shown in browser when auth fails
|
|
37
45
|
*/
|
|
@@ -57,5 +65,8 @@ export declare class CallbackServer {
|
|
|
57
65
|
* @throws CallbackError if callback fails or times out
|
|
58
66
|
*/
|
|
59
67
|
waitForCallback(expectedState: string): Promise<CallbackResult>;
|
|
68
|
+
/**
|
|
69
|
+
* Wait until the callback server is listening.
|
|
70
|
+
*/
|
|
71
|
+
waitUntilReady(): Promise<number>;
|
|
60
72
|
}
|
|
61
|
-
//# sourceMappingURL=callback-server.d.ts.map
|
|
@@ -2,6 +2,7 @@ import { readFileSync } from 'fs';
|
|
|
2
2
|
import { createServer } from 'http';
|
|
3
3
|
import path from 'path';
|
|
4
4
|
import { fileURLToPath } from 'url';
|
|
5
|
+
import { DEFAULT_CALLBACK_PORT, DEFAULT_CALLBACK_PORTS } from '../config/oauth.js';
|
|
5
6
|
const filename = fileURLToPath(import.meta.url);
|
|
6
7
|
const dirname = path.dirname(filename);
|
|
7
8
|
/**
|
|
@@ -19,17 +20,19 @@ const dirname = path.dirname(filename);
|
|
|
19
20
|
* Starts a temporary server on localhost to receive the OAuth authorization code.
|
|
20
21
|
* The server automatically shuts down after receiving the callback or on timeout.
|
|
21
22
|
*
|
|
22
|
-
*
|
|
23
|
-
* OS-assigned port
|
|
23
|
+
* Tries the registered localhost callback ports in order. It does not use an
|
|
24
|
+
* OS-assigned random port because OAuth redirect URIs must be registered.
|
|
24
25
|
*/ export class CallbackServer {
|
|
25
26
|
actualPort;
|
|
26
|
-
|
|
27
|
+
callbackPorts;
|
|
28
|
+
readyPromise = null;
|
|
29
|
+
rejectReady;
|
|
30
|
+
resolveReady;
|
|
27
31
|
server = null;
|
|
28
32
|
timeoutMs;
|
|
29
33
|
constructor(options = {}){
|
|
30
|
-
this.
|
|
34
|
+
this.callbackPorts = resolveCallbackPorts(options);
|
|
31
35
|
this.timeoutMs = options.timeoutMs || 120000; // 2 minutes default
|
|
32
|
-
this.server = createServer();
|
|
33
36
|
}
|
|
34
37
|
/**
|
|
35
38
|
* Render error page shown in browser when auth fails
|
|
@@ -46,7 +49,7 @@ const dirname = path.dirname(filename);
|
|
|
46
49
|
* Get the actual port the server is listening on
|
|
47
50
|
* @returns Port number (may differ from preferred if that was in use)
|
|
48
51
|
*/ getActualPort() {
|
|
49
|
-
return this.actualPort || this.
|
|
52
|
+
return this.actualPort || this.callbackPorts[0];
|
|
50
53
|
}
|
|
51
54
|
/**
|
|
52
55
|
* Stop the server if running
|
|
@@ -64,6 +67,17 @@ const dirname = path.dirname(filename);
|
|
|
64
67
|
* @throws CallbackError if callback fails or times out
|
|
65
68
|
*/ async waitForCallback(expectedState) {
|
|
66
69
|
return new Promise((resolve, reject)=>{
|
|
70
|
+
if (this.server) {
|
|
71
|
+
reject(new CallbackError('Callback server is already running', 'server_error'));
|
|
72
|
+
return;
|
|
73
|
+
}
|
|
74
|
+
this.readyPromise = new Promise((resolveReady, rejectReady)=>{
|
|
75
|
+
this.resolveReady = resolveReady;
|
|
76
|
+
this.rejectReady = rejectReady;
|
|
77
|
+
});
|
|
78
|
+
this.readyPromise.catch(()=>{
|
|
79
|
+
// The caller may only await waitForCallback(); avoid an unhandled rejection.
|
|
80
|
+
});
|
|
67
81
|
const cleanup = (handle)=>{
|
|
68
82
|
clearTimeout(handle);
|
|
69
83
|
if (this.server) {
|
|
@@ -76,8 +90,7 @@ const dirname = path.dirname(filename);
|
|
|
76
90
|
cleanup(timeoutHandle);
|
|
77
91
|
reject(new CallbackError('OAuth authorization timed out. Please try again.', 'timeout'));
|
|
78
92
|
}, this.timeoutMs);
|
|
79
|
-
|
|
80
|
-
this.server = createServer((req, res)=>{
|
|
93
|
+
const handleRequest = (req, res)=>{
|
|
81
94
|
const url = new URL(req.url || '', `http://localhost:${this.getActualPort()}`);
|
|
82
95
|
// Only handle /callback path
|
|
83
96
|
if (url.pathname !== '/callback') {
|
|
@@ -133,36 +146,63 @@ const dirname = path.dirname(filename);
|
|
|
133
146
|
code,
|
|
134
147
|
state
|
|
135
148
|
});
|
|
136
|
-
}
|
|
137
|
-
// Try
|
|
138
|
-
const tryListen = (
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
149
|
+
};
|
|
150
|
+
// Try registered callback ports in order.
|
|
151
|
+
const tryListen = (portIndex)=>{
|
|
152
|
+
const port = this.callbackPorts[portIndex];
|
|
153
|
+
const server = createServer(handleRequest);
|
|
154
|
+
this.server = server;
|
|
155
|
+
server.once('error', (err)=>{
|
|
156
|
+
if (this.server === server) {
|
|
157
|
+
this.server = null;
|
|
158
|
+
}
|
|
159
|
+
if (err.code === 'EADDRINUSE' && portIndex < this.callbackPorts.length - 1) {
|
|
160
|
+
tryListen(portIndex + 1);
|
|
161
|
+
return;
|
|
162
|
+
}
|
|
163
|
+
cleanup(timeoutHandle);
|
|
164
|
+
const callbackError = err.code === 'EADDRINUSE' ? new CallbackError(`OAuth callback ports are all in use: ${this.callbackPorts.join(', ')}. Close the process using one of these ports and run login again.`, 'ports_in_use') : new CallbackError(`Failed to start callback server: ${err.message}`, 'server_error');
|
|
165
|
+
this.rejectReady?.(callbackError);
|
|
166
|
+
reject(callbackError);
|
|
167
|
+
});
|
|
168
|
+
server.listen(port, '127.0.0.1', ()=>{
|
|
169
|
+
if (this.server !== server) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
144
172
|
// Capture the actual port that was assigned
|
|
145
|
-
const addr =
|
|
173
|
+
const addr = server.address();
|
|
146
174
|
if (addr && typeof addr === 'object') {
|
|
147
175
|
this.actualPort = addr.port;
|
|
148
|
-
|
|
149
|
-
});
|
|
150
|
-
// Handle server errors (port in use, etc)
|
|
151
|
-
this.server.once('error', (err)=>{
|
|
152
|
-
if (err.code === 'EADDRINUSE' && !isRetry) {
|
|
153
|
-
// Port in use, try with OS-assigned port (0 = dynamic)
|
|
154
|
-
this.server.removeAllListeners();
|
|
155
|
-
tryListen(0, true);
|
|
156
|
-
} else {
|
|
157
|
-
cleanup(timeoutHandle);
|
|
158
|
-
reject(new CallbackError(`Failed to start callback server: ${err.message}${!isRetry ? ' (tried fallback port)' : ''}`));
|
|
176
|
+
this.resolveReady?.(addr.port);
|
|
159
177
|
}
|
|
160
178
|
});
|
|
161
179
|
};
|
|
162
|
-
// Start with
|
|
163
|
-
tryListen(
|
|
180
|
+
// Start with first configured port
|
|
181
|
+
tryListen(0);
|
|
164
182
|
});
|
|
165
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Wait until the callback server is listening.
|
|
186
|
+
*/ waitUntilReady() {
|
|
187
|
+
if (!this.readyPromise) {
|
|
188
|
+
return Promise.reject(new CallbackError('Callback server has not started', 'server_error'));
|
|
189
|
+
}
|
|
190
|
+
return this.readyPromise;
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
function resolveCallbackPorts(options) {
|
|
194
|
+
if (!options.port && !options.fallbackPorts) {
|
|
195
|
+
return DEFAULT_CALLBACK_PORTS;
|
|
196
|
+
}
|
|
197
|
+
const primaryPort = options.port || DEFAULT_CALLBACK_PORT;
|
|
198
|
+
const ports = uniquePorts([
|
|
199
|
+
primaryPort,
|
|
200
|
+
...options.fallbackPorts || []
|
|
201
|
+
]).slice(0, DEFAULT_CALLBACK_PORTS.length);
|
|
202
|
+
return ports.length > 0 ? ports : DEFAULT_CALLBACK_PORTS;
|
|
203
|
+
}
|
|
204
|
+
function uniquePorts(ports) {
|
|
205
|
+
return [
|
|
206
|
+
...new Set(ports)
|
|
207
|
+
];
|
|
166
208
|
}
|
|
167
|
-
|
|
168
|
-
//# sourceMappingURL=callback-server.js.map
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Access Tokens types for CLI authentication
|
|
3
|
+
*
|
|
4
|
+
* Distinguishes between OAuth tokens (Authorization: Bearer) and
|
|
5
|
+
* Plan Access Tokens (X-Figma-Token header).
|
|
6
|
+
*/
|
|
7
|
+
/**
|
|
8
|
+
* Represents an authenticated credential — either OAuth or PAT
|
|
9
|
+
*/
|
|
10
|
+
export type AuthCredential = {
|
|
11
|
+
token: string;
|
|
12
|
+
type: 'oauth';
|
|
13
|
+
} | {
|
|
14
|
+
token: string;
|
|
15
|
+
type: 'plan_access_token';
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Build the correct auth headers for a credential
|
|
19
|
+
*/
|
|
20
|
+
export declare function getAuthHeaders(credential: AuthCredential): Record<string, string>;
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auth Access Tokens types for CLI authentication
|
|
3
|
+
*
|
|
4
|
+
* Distinguishes between OAuth tokens (Authorization: Bearer) and
|
|
5
|
+
* Plan Access Tokens (X-Figma-Token header).
|
|
6
|
+
*/ /**
|
|
7
|
+
* Represents an authenticated credential — either OAuth or PAT
|
|
8
|
+
*/ /**
|
|
9
|
+
* Build the correct auth headers for a credential
|
|
10
|
+
*/ export function getAuthHeaders(credential) {
|
|
11
|
+
if (credential.type === 'plan_access_token') {
|
|
12
|
+
return {
|
|
13
|
+
'X-Figma-Token': credential.token
|
|
14
|
+
};
|
|
15
|
+
}
|
|
16
|
+
return {
|
|
17
|
+
Authorization: `Bearer ${credential.token}`
|
|
18
|
+
};
|
|
19
|
+
}
|
|
@@ -30,4 +30,31 @@
|
|
|
30
30
|
* @throws Error if unable to derive key due to missing machine information
|
|
31
31
|
*/
|
|
32
32
|
export declare function deriveEncryptionKey(): string;
|
|
33
|
-
|
|
33
|
+
/**
|
|
34
|
+
* @deprecated Exists solely to read token stores written by older versions of
|
|
35
|
+
* this CLI that mixed `os.hostname()` into the encryption-key derivation. macOS
|
|
36
|
+
* rewrites the kernel hostname across DHCP/VPN/sleep events, which made those
|
|
37
|
+
* stores periodically un-decryptable. Used only by the transparent-migration
|
|
38
|
+
* path in `token-store.ts` and should be removed in a future release once
|
|
39
|
+
* upgraded clients are sufficiently common.
|
|
40
|
+
*
|
|
41
|
+
* @returns 64-character hex string (32-byte key) suitable for AES-256
|
|
42
|
+
*/
|
|
43
|
+
export declare function deriveLegacyEncryptionKey(): string;
|
|
44
|
+
/**
|
|
45
|
+
* Get a short hash of the encryption key for diagnostics.
|
|
46
|
+
* Returns first 8 chars of SHA-256 hash — enough to compare across invocations
|
|
47
|
+
* without exposing the actual key.
|
|
48
|
+
*/
|
|
49
|
+
export declare function getEncryptionKeyHash(): string;
|
|
50
|
+
/**
|
|
51
|
+
* Write decrypted versions of all encrypted store files for debugging.
|
|
52
|
+
*
|
|
53
|
+
* For each .json file in the store directory, creates a neighboring .decrypted.json
|
|
54
|
+
* file containing the decrypted contents. Useful for debugging token storage issues.
|
|
55
|
+
*
|
|
56
|
+
* @param rootDir - Root directory of the token store (e.g., ~/Library/Preferences/payloadcms-figma-nodejs)
|
|
57
|
+
* @param encryptionKey - The encryption key used by Conf
|
|
58
|
+
* @returns Array of paths to decrypted files created
|
|
59
|
+
*/
|
|
60
|
+
export declare function exportDecryptedStoreFiles(rootDir: string, encryptionKey: string): string[];
|
|
@@ -1,11 +1,9 @@
|
|
|
1
1
|
import Conf from 'conf';
|
|
2
2
|
import crypto from 'crypto';
|
|
3
|
+
import envPaths from 'env-paths';
|
|
4
|
+
import fsSync from 'node:fs';
|
|
3
5
|
import os from 'os';
|
|
4
|
-
|
|
5
|
-
const cryptoConf = new Conf({
|
|
6
|
-
configName: 'payloadcms-figma-crypto',
|
|
7
|
-
projectName: 'payloadcms-figma'
|
|
8
|
-
});
|
|
6
|
+
import path from 'path';
|
|
9
7
|
/**
|
|
10
8
|
* Get or generate a random salt for key derivation
|
|
11
9
|
*
|
|
@@ -13,15 +11,56 @@ const cryptoConf = new Conf({
|
|
|
13
11
|
* for future use. This ensures the encryption key is unique per machine and not
|
|
14
12
|
* reproducible even if machine identifiers are known.
|
|
15
13
|
*
|
|
14
|
+
* Uses an atomic create-or-read pattern (O_EXCL via `flag: 'wx'`) so concurrent
|
|
15
|
+
* callers — e.g. parallel vitest workers on a fresh CI container — converge on
|
|
16
|
+
* the same salt instead of clobbering each other's writes. Once the file
|
|
17
|
+
* exists, no caller ever overwrites it.
|
|
18
|
+
*
|
|
16
19
|
* @returns 32-byte hex string (64 characters)
|
|
17
20
|
*/ function getOrCreateSalt() {
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
21
|
+
// Path mirrors what `Conf({ projectName: 'payloadcms-figma', configName:
|
|
22
|
+
// 'payloadcms-figma-crypto' })` would produce, so files written by older
|
|
23
|
+
// versions remain readable.
|
|
24
|
+
const configDir = envPaths('payloadcms-figma', {
|
|
25
|
+
suffix: 'nodejs'
|
|
26
|
+
}).config;
|
|
27
|
+
const configPath = path.join(configDir, 'payloadcms-figma-crypto.json');
|
|
28
|
+
const readSalt = ()=>{
|
|
29
|
+
try {
|
|
30
|
+
const parsed = JSON.parse(fsSync.readFileSync(configPath, 'utf8'));
|
|
31
|
+
return typeof parsed.salt === 'string' && parsed.salt.length > 0 ? parsed.salt : undefined;
|
|
32
|
+
} catch (err) {
|
|
33
|
+
if (err.code === 'ENOENT') {
|
|
34
|
+
return undefined;
|
|
35
|
+
}
|
|
36
|
+
throw err;
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
const existing = readSalt();
|
|
40
|
+
if (existing) {
|
|
41
|
+
return existing;
|
|
42
|
+
}
|
|
43
|
+
fsSync.mkdirSync(configDir, {
|
|
44
|
+
recursive: true
|
|
45
|
+
});
|
|
46
|
+
const candidate = crypto.randomBytes(32).toString('hex');
|
|
47
|
+
try {
|
|
48
|
+
fsSync.writeFileSync(configPath, JSON.stringify({
|
|
49
|
+
salt: candidate
|
|
50
|
+
}, null, '\t'), {
|
|
51
|
+
flag: 'wx'
|
|
52
|
+
});
|
|
53
|
+
return candidate;
|
|
54
|
+
} catch (err) {
|
|
55
|
+
if (err.code !== 'EEXIST') {
|
|
56
|
+
throw err;
|
|
57
|
+
}
|
|
58
|
+
const winner = readSalt();
|
|
59
|
+
if (!winner) {
|
|
60
|
+
throw new Error('Failed to read salt after losing create-race');
|
|
61
|
+
}
|
|
62
|
+
return winner;
|
|
23
63
|
}
|
|
24
|
-
return salt;
|
|
25
64
|
}
|
|
26
65
|
/**
|
|
27
66
|
* Gather machine-specific entropy sources
|
|
@@ -33,19 +72,12 @@ const cryptoConf = new Conf({
|
|
|
33
72
|
* @throws Error if unable to gather sufficient entropy
|
|
34
73
|
*/ function gatherMachineEntropy() {
|
|
35
74
|
try {
|
|
36
|
-
const userInfo = os.userInfo();
|
|
37
|
-
const networkInterfaces = os.networkInterfaces();
|
|
38
|
-
// Get MAC address from first available network interface (if available)
|
|
39
|
-
const macAddress = Object.values(networkInterfaces).flat().find((iface)=>iface && !iface.internal && iface.mac !== '00:00:00:00:00:00')?.mac;
|
|
40
75
|
const entropy = [
|
|
41
|
-
os.hostname(),
|
|
42
76
|
os.homedir(),
|
|
43
|
-
userInfo.username,
|
|
77
|
+
os.userInfo().username,
|
|
44
78
|
os.platform(),
|
|
45
|
-
os.arch()
|
|
46
|
-
|
|
47
|
-
].filter(Boolean) // Remove any undefined values
|
|
48
|
-
;
|
|
79
|
+
os.arch()
|
|
80
|
+
];
|
|
49
81
|
if (entropy.length < 4) {
|
|
50
82
|
throw new Error('Insufficient machine entropy available');
|
|
51
83
|
}
|
|
@@ -92,5 +124,82 @@ const cryptoConf = new Conf({
|
|
|
92
124
|
const key = crypto.pbkdf2Sync(machineId, salt, 100000, 32, 'sha256');
|
|
93
125
|
return key.toString('hex');
|
|
94
126
|
}
|
|
95
|
-
|
|
96
|
-
|
|
127
|
+
/**
|
|
128
|
+
* @deprecated Exists solely to read token stores written by older versions of
|
|
129
|
+
* this CLI that mixed `os.hostname()` into the encryption-key derivation. macOS
|
|
130
|
+
* rewrites the kernel hostname across DHCP/VPN/sleep events, which made those
|
|
131
|
+
* stores periodically un-decryptable. Used only by the transparent-migration
|
|
132
|
+
* path in `token-store.ts` and should be removed in a future release once
|
|
133
|
+
* upgraded clients are sufficiently common.
|
|
134
|
+
*
|
|
135
|
+
* @returns 64-character hex string (32-byte key) suitable for AES-256
|
|
136
|
+
*/ export function deriveLegacyEncryptionKey() {
|
|
137
|
+
const entropy = [
|
|
138
|
+
os.hostname(),
|
|
139
|
+
os.homedir(),
|
|
140
|
+
os.userInfo().username,
|
|
141
|
+
os.platform(),
|
|
142
|
+
os.arch()
|
|
143
|
+
];
|
|
144
|
+
const machineId = entropy.join('::');
|
|
145
|
+
const salt = getOrCreateSalt();
|
|
146
|
+
const key = crypto.pbkdf2Sync(machineId, salt, 100000, 32, 'sha256');
|
|
147
|
+
return key.toString('hex');
|
|
148
|
+
}
|
|
149
|
+
/**
|
|
150
|
+
* Get a short hash of the encryption key for diagnostics.
|
|
151
|
+
* Returns first 8 chars of SHA-256 hash — enough to compare across invocations
|
|
152
|
+
* without exposing the actual key.
|
|
153
|
+
*/ export function getEncryptionKeyHash() {
|
|
154
|
+
const key = deriveEncryptionKey();
|
|
155
|
+
return crypto.createHash('sha256').update(key).digest('hex').substring(0, 8);
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* Write decrypted versions of all encrypted store files for debugging.
|
|
159
|
+
*
|
|
160
|
+
* For each .json file in the store directory, creates a neighboring .decrypted.json
|
|
161
|
+
* file containing the decrypted contents. Useful for debugging token storage issues.
|
|
162
|
+
*
|
|
163
|
+
* @param rootDir - Root directory of the token store (e.g., ~/Library/Preferences/payloadcms-figma-nodejs)
|
|
164
|
+
* @param encryptionKey - The encryption key used by Conf
|
|
165
|
+
* @returns Array of paths to decrypted files created
|
|
166
|
+
*/ export function exportDecryptedStoreFiles(rootDir, encryptionKey) {
|
|
167
|
+
const decryptedFiles = [];
|
|
168
|
+
function processDirectory(dir) {
|
|
169
|
+
if (!fsSync.existsSync(dir)) {
|
|
170
|
+
return;
|
|
171
|
+
}
|
|
172
|
+
const entries = fsSync.readdirSync(dir, {
|
|
173
|
+
withFileTypes: true
|
|
174
|
+
});
|
|
175
|
+
for (const entry of entries){
|
|
176
|
+
const fullPath = path.join(dir, entry.name);
|
|
177
|
+
if (entry.isDirectory()) {
|
|
178
|
+
processDirectory(fullPath);
|
|
179
|
+
} else if (entry.name.endsWith('.json') && !entry.name.endsWith('.decrypted.json') && !entry.name.includes('.corrupt-')) {
|
|
180
|
+
try {
|
|
181
|
+
// Extract configName from filename (remove .json extension)
|
|
182
|
+
const configName = entry.name.replace(/\.json$/, '');
|
|
183
|
+
// Create a Conf instance to read/decrypt the file
|
|
184
|
+
const config = new Conf({
|
|
185
|
+
clearInvalidConfig: false,
|
|
186
|
+
configName,
|
|
187
|
+
cwd: dir,
|
|
188
|
+
encryptionKey,
|
|
189
|
+
projectName: 'payloadcms-figma'
|
|
190
|
+
});
|
|
191
|
+
// Read all data from the store (Conf decrypts it)
|
|
192
|
+
const data = config.store;
|
|
193
|
+
// Write decrypted content to neighboring file
|
|
194
|
+
const decryptedPath = fullPath.replace(/\.json$/, '.decrypted.json');
|
|
195
|
+
fsSync.writeFileSync(decryptedPath, JSON.stringify(data, null, 2));
|
|
196
|
+
decryptedFiles.push(decryptedPath);
|
|
197
|
+
} catch {
|
|
198
|
+
// Skip files that can't be decrypted (e.g., crypto config, already unencrypted)
|
|
199
|
+
}
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
processDirectory(rootDir);
|
|
204
|
+
return decryptedFiles;
|
|
205
|
+
}
|