@payloadcms/figma 0.0.1-alpha.9 → 0.1.0-alpha.0
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 +7574 -0
- package/dist/db-content-api/generated/content-api-types.js +5 -0
- package/dist/db-content-api/index.d.ts +37 -0
- package/dist/db-content-api/index.js +938 -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/data/applyDefaults.d.ts +6 -0
- package/dist/db-content-api/utilities/data/applyDefaults.js +75 -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/index.d.ts +48 -0
- package/dist/db-content-api/utilities/data/index.js +299 -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/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 +100 -0
- package/dist/db-content-api/utilities/joins.d.ts +52 -0
- package/dist/db-content-api/utilities/joins.js +137 -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/buildLocalizedPaths.d.ts +10 -0
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +71 -0
- package/dist/db-content-api/utilities/meta/buildMeta.d.ts +41 -0
- package/dist/db-content-api/utilities/meta/buildMeta.js +39 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts +16 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.js +243 -0
- package/dist/db-content-api/utilities/meta/buildUniquePaths.d.ts +12 -0
- package/dist/db-content-api/utilities/meta/buildUniquePaths.js +60 -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 +55 -0
- package/dist/db-content-api/utilities/schema/buildDocumentSchema.js +182 -0
- package/dist/db-content-api/utilities/where.d.ts +19 -0
- package/dist/db-content-api/utilities/where.js +106 -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
|
@@ -5,10 +5,11 @@
|
|
|
5
5
|
* to the Content API. Project tokens are scoped to a specific tenant/CMS
|
|
6
6
|
* and have a shorter lifespan (15-30 minutes) than OAuth tokens.
|
|
7
7
|
*/ import { getProjectToken as fetchProjectToken } from '../api/figma-api.js';
|
|
8
|
-
import {
|
|
8
|
+
import { PROJECT_TOKEN_EXPIRY_BUFFER_SECONDS } from '../config/oauth.js';
|
|
9
|
+
import { getInfraEnvironment } from '../constants.js';
|
|
9
10
|
import * as log from '../utils/log.js';
|
|
10
|
-
import { JWTValidationError,
|
|
11
|
-
import {
|
|
11
|
+
import { JWTValidationError, validateContentApiToken } from './jwt-validator.js';
|
|
12
|
+
import { getValidCredential } from './oauth-flow.js';
|
|
12
13
|
/**
|
|
13
14
|
* Error during project token operations
|
|
14
15
|
*/ export class ProjectTokenError extends Error {
|
|
@@ -18,6 +19,21 @@ import { getValidAccessToken } from './oauth-flow.js';
|
|
|
18
19
|
this.name = 'ProjectTokenError';
|
|
19
20
|
}
|
|
20
21
|
}
|
|
22
|
+
const projectTokenCache = new Map();
|
|
23
|
+
const inFlightRefreshes = new Map();
|
|
24
|
+
function buildCacheKey(params) {
|
|
25
|
+
const projectId = params.projectInfo?.projectId ?? '';
|
|
26
|
+
const environmentName = params.projectInfo?.environmentName ?? '';
|
|
27
|
+
return `${params.tenantId}::${projectId}::${environmentName}`;
|
|
28
|
+
}
|
|
29
|
+
function isCachedTokenValid(entry) {
|
|
30
|
+
const bufferMs = PROJECT_TOKEN_EXPIRY_BUFFER_SECONDS * 1000;
|
|
31
|
+
return Date.now() < entry.expiresAt - bufferMs;
|
|
32
|
+
}
|
|
33
|
+
/** Test-only: clears the in-memory token cache and any in-flight refresh promises. */ export function __resetProjectTokenCacheForTests() {
|
|
34
|
+
projectTokenCache.clear();
|
|
35
|
+
inFlightRefreshes.clear();
|
|
36
|
+
}
|
|
21
37
|
/**
|
|
22
38
|
* Parse JWT claims from token without validation
|
|
23
39
|
* Used for mock tokens where signature validation is not needed
|
|
@@ -43,89 +59,181 @@ import { getValidAccessToken } from './oauth-flow.js';
|
|
|
43
59
|
}
|
|
44
60
|
}
|
|
45
61
|
/**
|
|
46
|
-
* Get a valid project token for a tenant, refreshing if necessary
|
|
62
|
+
* Get a valid project token for a tenant, refreshing if necessary.
|
|
47
63
|
*
|
|
48
|
-
*
|
|
49
|
-
* 1.
|
|
50
|
-
* 2.
|
|
51
|
-
*
|
|
52
|
-
*
|
|
53
|
-
*
|
|
64
|
+
* Lookup order:
|
|
65
|
+
* 1. Module-level in-memory cache (no I/O on hits).
|
|
66
|
+
* 2. In-flight refresh map — concurrent callers with no cached entry share a single
|
|
67
|
+
* refresh promise, so the project-token endpoint is only hit once per cache key.
|
|
68
|
+
* 3. Persisted (`conf`-backed) token store — picks up tokens minted by sibling processes.
|
|
69
|
+
* 4. Figma API — fetch + JWT validation, then write to both the persisted store and
|
|
70
|
+
* the in-memory cache.
|
|
54
71
|
*
|
|
55
72
|
* The project token is used by local Payload instances to authenticate
|
|
56
73
|
* requests to the Content API without requiring a round-trip to Sinatra.
|
|
57
74
|
*
|
|
58
|
-
* @param tokenStore - Token store for persisting tokens
|
|
59
|
-
* @param tenantId -
|
|
75
|
+
* @param params.tokenStore - Token store for persisting tokens
|
|
76
|
+
* @param params.tenantId - Optional tenant/CMS ID; resolved from stored bootstrap data when omitted
|
|
77
|
+
* @param params.projectInfo - Optional project scope (defaults to env vars)
|
|
60
78
|
* @returns Promise resolving to JWT token string or null if failed
|
|
61
79
|
* @throws {ProjectTokenError} If token generation fails
|
|
62
|
-
*/ export async function getValidProjectToken(
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
return projectToken?.token || null;
|
|
80
|
+
*/ export async function getValidProjectToken({ projectInfo, tenantId, tokenStore }) {
|
|
81
|
+
if (process.env.FIGMA_CONTENT_API_ACCESS_KEY) {
|
|
82
|
+
log.debug('FIGMA_CONTENT_API_ACCESS_KEY is set; skipping project token retrieval from API');
|
|
83
|
+
return null;
|
|
67
84
|
}
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
} catch (error) {
|
|
74
|
-
throw new ProjectTokenError('Failed to get valid access token for project token refresh', error instanceof Error ? error : undefined);
|
|
85
|
+
const resolvedTenantId = tenantId ?? tokenStore.getTenantId({
|
|
86
|
+
projectInfo
|
|
87
|
+
});
|
|
88
|
+
if (!resolvedTenantId) {
|
|
89
|
+
throw new ProjectTokenError('tenantId was not provided and could not be resolved from bootstrap data');
|
|
75
90
|
}
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
91
|
+
const cacheKey = buildCacheKey({
|
|
92
|
+
projectInfo,
|
|
93
|
+
tenantId: resolvedTenantId
|
|
94
|
+
});
|
|
95
|
+
const cached = projectTokenCache.get(cacheKey);
|
|
96
|
+
if (cached && isCachedTokenValid(cached)) {
|
|
97
|
+
return cached.token;
|
|
79
98
|
}
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
99
|
+
const inFlight = inFlightRefreshes.get(cacheKey);
|
|
100
|
+
if (inFlight) {
|
|
101
|
+
return inFlight;
|
|
102
|
+
}
|
|
103
|
+
// The IIFE references this holder so it can check whether it is still the
|
|
104
|
+
// active refresh before writing back to the caches. Without this guard a
|
|
105
|
+
// stale in-flight refresh could clobber a fresh token written by a later
|
|
106
|
+
// refresh (e.g. one triggered by `refreshProjectToken`).
|
|
107
|
+
const handle = {};
|
|
108
|
+
handle.promise = (async ()=>{
|
|
109
|
+
if (tokenStore.hasValidProjectToken({
|
|
110
|
+
projectInfo
|
|
111
|
+
})) {
|
|
112
|
+
const stored = tokenStore.getProjectToken({
|
|
113
|
+
projectInfo
|
|
114
|
+
});
|
|
115
|
+
if (stored?.token && inFlightRefreshes.get(cacheKey) === handle.promise) {
|
|
116
|
+
projectTokenCache.set(cacheKey, {
|
|
117
|
+
expiresAt: stored.expiresAt,
|
|
118
|
+
token: stored.token
|
|
119
|
+
});
|
|
120
|
+
return stored.token;
|
|
121
|
+
}
|
|
122
|
+
if (stored?.token) {
|
|
123
|
+
return stored.token;
|
|
124
|
+
}
|
|
125
|
+
// hasValidProjectToken said yes but getProjectToken returned no token —
|
|
126
|
+
// store was likely cleared by another process between calls. Fall through
|
|
127
|
+
// to fetch so the caller still gets a token.
|
|
128
|
+
log.warning(`Stored project token vanished between hasValidProjectToken and getProjectToken (cacheKey=${cacheKey}); re-fetching`);
|
|
129
|
+
}
|
|
130
|
+
let credential;
|
|
131
|
+
try {
|
|
132
|
+
credential = await getValidCredential(tokenStore);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
throw new ProjectTokenError('Failed to get valid access token for project token refresh', error instanceof Error ? error : undefined);
|
|
135
|
+
}
|
|
136
|
+
if (!credential) {
|
|
137
|
+
return null;
|
|
138
|
+
}
|
|
139
|
+
let fetchedToken;
|
|
91
140
|
try {
|
|
92
|
-
|
|
93
|
-
} catch (
|
|
94
|
-
//
|
|
95
|
-
|
|
96
|
-
|
|
141
|
+
fetchedToken = await fetchProjectToken(credential, resolvedTenantId);
|
|
142
|
+
} catch (error) {
|
|
143
|
+
// Let API errors (e.g. FigmaApiError) propagate raw so callers can
|
|
144
|
+
// branch on status codes — but log context for debugging.
|
|
145
|
+
log.debug(`fetchProjectToken failed (cacheKey=${cacheKey}, tenantId=${resolvedTenantId}): ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
146
|
+
throw error;
|
|
147
|
+
}
|
|
148
|
+
const hasEnvToken = !!process.env.FIGMA_MOCK_PROJECT_TOKEN_VALUE;
|
|
149
|
+
const shouldMock = process.env.FIGMA_MOCK_PROJECT_TOKEN !== 'false';
|
|
150
|
+
let validatedClaims;
|
|
151
|
+
if (hasEnvToken || shouldMock) {
|
|
152
|
+
log.debug('Skipping JWT validation for mock/env project token');
|
|
153
|
+
validatedClaims = parseJWTClaims(fetchedToken.token);
|
|
154
|
+
} else {
|
|
155
|
+
try {
|
|
156
|
+
validatedClaims = await validateContentApiToken({
|
|
157
|
+
audience: resolvedTenantId,
|
|
158
|
+
environment: getInfraEnvironment(),
|
|
159
|
+
token: fetchedToken.token
|
|
160
|
+
});
|
|
161
|
+
} catch (validationError) {
|
|
162
|
+
if (validationError instanceof JWTValidationError) {
|
|
163
|
+
throw new ProjectTokenError(`Project token validation failed: ${validationError.message}`, validationError);
|
|
164
|
+
}
|
|
165
|
+
throw validationError;
|
|
97
166
|
}
|
|
98
|
-
|
|
167
|
+
}
|
|
168
|
+
if (typeof validatedClaims.exp !== 'number' || !Number.isFinite(validatedClaims.exp)) {
|
|
169
|
+
throw new ProjectTokenError('Project token missing or invalid expiration (exp) claim');
|
|
170
|
+
}
|
|
171
|
+
const expiresAt = validatedClaims.exp * 1000;
|
|
172
|
+
if (inFlightRefreshes.get(cacheKey) !== handle.promise) {
|
|
173
|
+
log.debug(`Project token refresh superseded; not persisting (cacheKey=${cacheKey})`);
|
|
174
|
+
return fetchedToken.token;
|
|
175
|
+
}
|
|
176
|
+
try {
|
|
177
|
+
tokenStore.setProjectToken({
|
|
178
|
+
projectInfo,
|
|
179
|
+
token: {
|
|
180
|
+
claims: validatedClaims,
|
|
181
|
+
expiresAt,
|
|
182
|
+
tenantId: resolvedTenantId,
|
|
183
|
+
token: fetchedToken.token
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
} catch (error) {
|
|
187
|
+
// Persistence is best-effort: a failure here (disk full, permissions,
|
|
188
|
+
// corrupt conf entry) shouldn't lose the freshly-minted token. Log and
|
|
189
|
+
// populate the in-memory cache so this process can still use it.
|
|
190
|
+
log.error(`Failed to persist project token to store (cacheKey=${cacheKey}): ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
191
|
+
}
|
|
192
|
+
projectTokenCache.set(cacheKey, {
|
|
193
|
+
expiresAt,
|
|
194
|
+
token: fetchedToken.token
|
|
195
|
+
});
|
|
196
|
+
return fetchedToken.token;
|
|
197
|
+
})();
|
|
198
|
+
inFlightRefreshes.set(cacheKey, handle.promise);
|
|
199
|
+
try {
|
|
200
|
+
return await handle.promise;
|
|
201
|
+
} finally{
|
|
202
|
+
if (inFlightRefreshes.get(cacheKey) === handle.promise) {
|
|
203
|
+
inFlightRefreshes.delete(cacheKey);
|
|
99
204
|
}
|
|
100
205
|
}
|
|
101
|
-
// Ensure exp claim is present
|
|
102
|
-
if (!validatedClaims.exp) {
|
|
103
|
-
throw new ProjectTokenError('Project token missing expiration (exp) claim');
|
|
104
|
-
}
|
|
105
|
-
// Store the project token with validated expiration and claims
|
|
106
|
-
tokenStore.setProjectToken(tenantId, {
|
|
107
|
-
claims: validatedClaims,
|
|
108
|
-
expiresAt: validatedClaims.exp * 1000,
|
|
109
|
-
tenantId,
|
|
110
|
-
token: projectToken.token
|
|
111
|
-
});
|
|
112
|
-
return projectToken.token;
|
|
113
206
|
}
|
|
114
207
|
/**
|
|
115
|
-
*
|
|
208
|
+
* Force-refresh a project token, bypassing all cache layers.
|
|
116
209
|
*
|
|
117
|
-
*
|
|
118
|
-
*
|
|
210
|
+
* Invalidates the in-memory cache entry, the in-flight refresh promise (so a
|
|
211
|
+
* concurrently-running refresh that may already be returning a soon-to-be-stale
|
|
212
|
+
* token is dropped from the dedup map), and the persisted token store. Then
|
|
213
|
+
* delegates to {@link getValidProjectToken} to mint a fresh token.
|
|
119
214
|
*
|
|
120
|
-
* @param tokenStore - Token store for persisting tokens
|
|
121
|
-
* @param tenantId -
|
|
215
|
+
* @param params.tokenStore - Token store for persisting tokens
|
|
216
|
+
* @param params.tenantId - Optional tenant/CMS ID; resolved from stored bootstrap data when omitted
|
|
217
|
+
* @param params.projectInfo - Optional project scope (defaults to env vars)
|
|
122
218
|
* @returns Promise resolving to JWT token string or null if failed
|
|
123
219
|
* @throws {ProjectTokenError} If token refresh fails
|
|
124
|
-
*/ export async function refreshProjectToken(
|
|
125
|
-
|
|
126
|
-
tokenStore.
|
|
127
|
-
|
|
128
|
-
|
|
220
|
+
*/ export async function refreshProjectToken(params) {
|
|
221
|
+
const { projectInfo, tenantId, tokenStore } = params;
|
|
222
|
+
const resolvedTenantId = tenantId ?? tokenStore.getTenantId({
|
|
223
|
+
projectInfo
|
|
224
|
+
});
|
|
225
|
+
if (resolvedTenantId) {
|
|
226
|
+
const cacheKey = buildCacheKey({
|
|
227
|
+
projectInfo,
|
|
228
|
+
tenantId: resolvedTenantId
|
|
229
|
+
});
|
|
230
|
+
projectTokenCache.delete(cacheKey);
|
|
231
|
+
// Drop any in-flight refresh so getValidProjectToken below cannot return
|
|
232
|
+
// a soon-to-be-stale token via the dedup map.
|
|
233
|
+
inFlightRefreshes.delete(cacheKey);
|
|
234
|
+
}
|
|
235
|
+
tokenStore.clearProjectToken({
|
|
236
|
+
projectInfo
|
|
237
|
+
});
|
|
238
|
+
return getValidProjectToken(params);
|
|
129
239
|
}
|
|
130
|
-
|
|
131
|
-
//# sourceMappingURL=project-token.js.map
|
package/dist/auth/refresh.d.ts
CHANGED
|
@@ -4,7 +4,8 @@ import type { FigmaTokens } from './types.js';
|
|
|
4
4
|
*/
|
|
5
5
|
export declare class TokenRefreshError extends Error {
|
|
6
6
|
statusCode?: number | undefined;
|
|
7
|
-
|
|
7
|
+
errorCode?: string | undefined;
|
|
8
|
+
constructor(message: string, statusCode?: number | undefined, errorCode?: string | undefined);
|
|
8
9
|
}
|
|
9
10
|
/**
|
|
10
11
|
* Refresh an expired OAuth2 access token using a refresh token
|
|
@@ -32,4 +33,3 @@ export declare function refreshAccessToken(refreshToken: string, clientId?: stri
|
|
|
32
33
|
* @throws TokenRefreshError if exchange fails
|
|
33
34
|
*/
|
|
34
35
|
export declare function exchangeCodeForTokens(code: string, codeVerifier: string, redirectUri?: string, clientId?: string): Promise<FigmaTokens>;
|
|
35
|
-
//# sourceMappingURL=refresh.d.ts.map
|
package/dist/auth/refresh.js
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
/* eslint-disable perfectionist/sort-objects */ import {
|
|
1
|
+
/* eslint-disable perfectionist/sort-objects */ import { getOAuthConfig } from '../config/oauth.js';
|
|
2
2
|
import * as log from '../utils/log.js';
|
|
3
3
|
/**
|
|
4
4
|
* Error thrown when token refresh fails
|
|
5
5
|
*/ export class TokenRefreshError extends Error {
|
|
6
6
|
statusCode;
|
|
7
|
-
|
|
8
|
-
|
|
7
|
+
errorCode;
|
|
8
|
+
constructor(message, statusCode, errorCode){
|
|
9
|
+
super(message), this.statusCode = statusCode, this.errorCode = errorCode;
|
|
9
10
|
this.name = 'TokenRefreshError';
|
|
10
11
|
}
|
|
11
12
|
}
|
|
@@ -19,15 +20,17 @@ import * as log from '../utils/log.js';
|
|
|
19
20
|
* @param clientId - OAuth2 client ID (defaults to config)
|
|
20
21
|
* @returns Promise resolving to new tokens
|
|
21
22
|
* @throws TokenRefreshError if refresh fails
|
|
22
|
-
*/ export async function refreshAccessToken(refreshToken, clientId
|
|
23
|
+
*/ export async function refreshAccessToken(refreshToken, clientId) {
|
|
24
|
+
const oauthConfig = getOAuthConfig();
|
|
25
|
+
const resolvedClientId = clientId ?? oauthConfig.clientId;
|
|
23
26
|
// Prepare form data for token refresh request (public client)
|
|
24
27
|
const params = new URLSearchParams({
|
|
25
|
-
client_id:
|
|
28
|
+
client_id: resolvedClientId,
|
|
26
29
|
grant_type: 'refresh_token',
|
|
27
30
|
refresh_token: refreshToken
|
|
28
31
|
});
|
|
29
32
|
try {
|
|
30
|
-
const response = await fetch(
|
|
33
|
+
const response = await fetch(oauthConfig.refreshUrl, {
|
|
31
34
|
method: 'POST',
|
|
32
35
|
headers: {
|
|
33
36
|
'Content-Type': 'application/x-www-form-urlencoded'
|
|
@@ -36,7 +39,14 @@ import * as log from '../utils/log.js';
|
|
|
36
39
|
});
|
|
37
40
|
if (!response.ok) {
|
|
38
41
|
const errorText = await response.text();
|
|
39
|
-
|
|
42
|
+
let errorCode;
|
|
43
|
+
try {
|
|
44
|
+
const parsed = JSON.parse(errorText);
|
|
45
|
+
errorCode = parsed.error;
|
|
46
|
+
} catch {
|
|
47
|
+
// Not JSON, leave errorCode undefined
|
|
48
|
+
}
|
|
49
|
+
throw new TokenRefreshError(`Token refresh failed: ${response.statusText}. ${errorText}`, response.status, errorCode);
|
|
40
50
|
}
|
|
41
51
|
const data = await response.json();
|
|
42
52
|
// Validate response contains required fields
|
|
@@ -71,14 +81,17 @@ import * as log from '../utils/log.js';
|
|
|
71
81
|
* @param clientId - OAuth2 client ID (defaults to config)
|
|
72
82
|
* @returns Promise resolving to tokens
|
|
73
83
|
* @throws TokenRefreshError if exchange fails
|
|
74
|
-
*/ export async function exchangeCodeForTokens(code, codeVerifier, redirectUri
|
|
84
|
+
*/ export async function exchangeCodeForTokens(code, codeVerifier, redirectUri, clientId) {
|
|
85
|
+
const oauthConfig = getOAuthConfig();
|
|
86
|
+
const resolvedRedirectUri = redirectUri ?? oauthConfig.redirectUri;
|
|
87
|
+
const resolvedClientId = clientId ?? oauthConfig.clientId;
|
|
75
88
|
// Prepare form data for token exchange (public client with PKCE)
|
|
76
89
|
const params = new URLSearchParams({
|
|
77
|
-
client_id:
|
|
90
|
+
client_id: resolvedClientId,
|
|
78
91
|
code,
|
|
79
92
|
code_verifier: codeVerifier,
|
|
80
93
|
grant_type: 'authorization_code',
|
|
81
|
-
redirect_uri:
|
|
94
|
+
redirect_uri: resolvedRedirectUri
|
|
82
95
|
});
|
|
83
96
|
try {
|
|
84
97
|
// Public client - no client secret or Basic Auth header needed
|
|
@@ -88,11 +101,11 @@ import * as log from '../utils/log.js';
|
|
|
88
101
|
};
|
|
89
102
|
// Debug logging
|
|
90
103
|
log.debug(`Token exchange request: ${JSON.stringify({
|
|
91
|
-
url:
|
|
104
|
+
url: oauthConfig.tokenUrl,
|
|
92
105
|
headers,
|
|
93
106
|
body: params.toString()
|
|
94
107
|
})}`);
|
|
95
|
-
const response = await fetch(
|
|
108
|
+
const response = await fetch(oauthConfig.tokenUrl, {
|
|
96
109
|
method: 'POST',
|
|
97
110
|
headers,
|
|
98
111
|
body: params.toString()
|
|
@@ -136,5 +149,3 @@ import * as log from '../utils/log.js';
|
|
|
136
149
|
throw new TokenRefreshError(`Failed to exchange code for tokens: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
137
150
|
}
|
|
138
151
|
}
|
|
139
|
-
|
|
140
|
-
//# sourceMappingURL=refresh.js.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
import type { BootstrapData, FigmaTokens, ProjectToken } from './types.js';
|
|
2
|
+
export type LegacyStoreSchema = {
|
|
3
|
+
bootstrapData?: Record<string, BootstrapData>;
|
|
4
|
+
projectTokens?: Record<string, ProjectToken>;
|
|
5
|
+
tokens?: FigmaTokens;
|
|
6
|
+
};
|
|
7
|
+
export type MigrationCheckParams = {
|
|
8
|
+
checkFileExists?: (filePath: string) => boolean;
|
|
9
|
+
legacyFilePath: string;
|
|
10
|
+
newOAuthFilePath: string;
|
|
11
|
+
};
|
|
12
|
+
export type MigrateOAuthParams = {
|
|
13
|
+
encryptionKey: string;
|
|
14
|
+
legacyConfigName: string;
|
|
15
|
+
legacyCwd?: string;
|
|
16
|
+
newOAuthConfigName: string;
|
|
17
|
+
newOAuthCwd: string;
|
|
18
|
+
projectName: string;
|
|
19
|
+
};
|
|
20
|
+
/**
|
|
21
|
+
* Check if migration is needed.
|
|
22
|
+
* Returns true only when legacy file exists AND new oauth file does not.
|
|
23
|
+
*/
|
|
24
|
+
export declare function needsMigration(params: MigrationCheckParams): boolean;
|
|
25
|
+
/**
|
|
26
|
+
* Migrate OAuth tokens from legacy store to new oauth store.
|
|
27
|
+
* Reads from legacy location, writes to new location with root-level keys.
|
|
28
|
+
*
|
|
29
|
+
* `clearInvalidConfig` is deliberately OFF so a transient decrypt error does
|
|
30
|
+
* not wipe the legacy file — older CLI versions elsewhere on disk still read
|
|
31
|
+
* it. If we cannot open the file, we log and skip migration.
|
|
32
|
+
*/
|
|
33
|
+
export declare function migrateOAuth(params: MigrateOAuthParams): void;
|
|
34
|
+
export type ResolveProjectStorePath = (scope: {
|
|
35
|
+
environmentName: string;
|
|
36
|
+
projectId: string;
|
|
37
|
+
}) => {
|
|
38
|
+
configName: string;
|
|
39
|
+
cwd: string;
|
|
40
|
+
};
|
|
41
|
+
export type MigrateProjectDataParams = {
|
|
42
|
+
encryptionKey: string;
|
|
43
|
+
legacyConfigName: string;
|
|
44
|
+
legacyCwd?: string;
|
|
45
|
+
projectName: string;
|
|
46
|
+
resolveProjectStorePath: ResolveProjectStorePath;
|
|
47
|
+
};
|
|
48
|
+
/**
|
|
49
|
+
* Migrate per-project bootstrap data and project tokens from the legacy
|
|
50
|
+
* combined store into individual per-project stores.
|
|
51
|
+
*
|
|
52
|
+
* Walks legacy `bootstrapData` (keyed by `projectId:environmentName`), writes
|
|
53
|
+
* each entry into its own project store file, and stashes the matching
|
|
54
|
+
* `projectToken` (looked up by `bootstrapData.contentSystemId`) alongside it.
|
|
55
|
+
* Target files that already exist are left alone.
|
|
56
|
+
*/
|
|
57
|
+
export declare function migrateProjectData(params: MigrateProjectDataParams): void;
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import Conf from 'conf';
|
|
2
|
+
import fsSync from 'node:fs';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import * as log from '../utils/log.js';
|
|
5
|
+
const OAUTH_STORE_SCHEMA_VERSION = 1;
|
|
6
|
+
const PROJECT_STORE_SCHEMA_VERSION = 1;
|
|
7
|
+
/**
|
|
8
|
+
* Check if migration is needed.
|
|
9
|
+
* Returns true only when legacy file exists AND new oauth file does not.
|
|
10
|
+
*/ export function needsMigration(params) {
|
|
11
|
+
const checkExists = params.checkFileExists ?? fsSync.existsSync;
|
|
12
|
+
const newExists = checkExists(params.newOAuthFilePath);
|
|
13
|
+
if (newExists) {
|
|
14
|
+
return false;
|
|
15
|
+
}
|
|
16
|
+
return checkExists(params.legacyFilePath);
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Migrate OAuth tokens from legacy store to new oauth store.
|
|
20
|
+
* Reads from legacy location, writes to new location with root-level keys.
|
|
21
|
+
*
|
|
22
|
+
* `clearInvalidConfig` is deliberately OFF so a transient decrypt error does
|
|
23
|
+
* not wipe the legacy file — older CLI versions elsewhere on disk still read
|
|
24
|
+
* it. If we cannot open the file, we log and skip migration.
|
|
25
|
+
*/ export function migrateOAuth(params) {
|
|
26
|
+
const legacyConfig = openLegacyConfig({
|
|
27
|
+
encryptionKey: params.encryptionKey,
|
|
28
|
+
legacyConfigName: params.legacyConfigName,
|
|
29
|
+
legacyCwd: params.legacyCwd,
|
|
30
|
+
projectName: params.projectName
|
|
31
|
+
});
|
|
32
|
+
if (!legacyConfig) {
|
|
33
|
+
return;
|
|
34
|
+
}
|
|
35
|
+
const legacyTokens = safeGet(legacyConfig, 'tokens');
|
|
36
|
+
if (!legacyTokens) {
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
// Ensure target directory exists
|
|
40
|
+
if (!fsSync.existsSync(params.newOAuthCwd)) {
|
|
41
|
+
fsSync.mkdirSync(params.newOAuthCwd, {
|
|
42
|
+
recursive: true
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
const newOAuthConfig = new Conf({
|
|
46
|
+
configName: params.newOAuthConfigName,
|
|
47
|
+
cwd: params.newOAuthCwd,
|
|
48
|
+
encryptionKey: params.encryptionKey,
|
|
49
|
+
projectName: params.projectName
|
|
50
|
+
});
|
|
51
|
+
// Write root-level keys
|
|
52
|
+
newOAuthConfig.set('_schemaVersion', OAUTH_STORE_SCHEMA_VERSION);
|
|
53
|
+
newOAuthConfig.set('accessToken', legacyTokens.accessToken);
|
|
54
|
+
newOAuthConfig.set('expiresAt', legacyTokens.expiresAt);
|
|
55
|
+
newOAuthConfig.set('refreshToken', legacyTokens.refreshToken);
|
|
56
|
+
if (legacyTokens.scopes) {
|
|
57
|
+
newOAuthConfig.set('scopes', legacyTokens.scopes);
|
|
58
|
+
}
|
|
59
|
+
if (legacyTokens.tokenType) {
|
|
60
|
+
newOAuthConfig.set('tokenType', legacyTokens.tokenType);
|
|
61
|
+
}
|
|
62
|
+
if (legacyTokens.userId) {
|
|
63
|
+
newOAuthConfig.set('userId', legacyTokens.userId);
|
|
64
|
+
}
|
|
65
|
+
// Leave the legacy file untouched so older CLI versions installed in other
|
|
66
|
+
// projects on the same machine can keep reading their last known state.
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Migrate per-project bootstrap data and project tokens from the legacy
|
|
70
|
+
* combined store into individual per-project stores.
|
|
71
|
+
*
|
|
72
|
+
* Walks legacy `bootstrapData` (keyed by `projectId:environmentName`), writes
|
|
73
|
+
* each entry into its own project store file, and stashes the matching
|
|
74
|
+
* `projectToken` (looked up by `bootstrapData.contentSystemId`) alongside it.
|
|
75
|
+
* Target files that already exist are left alone.
|
|
76
|
+
*/ export function migrateProjectData(params) {
|
|
77
|
+
const legacyConfig = openLegacyConfig({
|
|
78
|
+
encryptionKey: params.encryptionKey,
|
|
79
|
+
legacyConfigName: params.legacyConfigName,
|
|
80
|
+
legacyCwd: params.legacyCwd,
|
|
81
|
+
projectName: params.projectName
|
|
82
|
+
});
|
|
83
|
+
if (!legacyConfig) {
|
|
84
|
+
return;
|
|
85
|
+
}
|
|
86
|
+
const bootstrapData = safeGet(legacyConfig, 'bootstrapData') || {};
|
|
87
|
+
const projectTokens = safeGet(legacyConfig, 'projectTokens') || {};
|
|
88
|
+
if (Object.keys(bootstrapData).length === 0 && Object.keys(projectTokens).length === 0) {
|
|
89
|
+
return;
|
|
90
|
+
}
|
|
91
|
+
for (const [key, bootstrap] of Object.entries(bootstrapData)){
|
|
92
|
+
const separatorIdx = key.indexOf(':');
|
|
93
|
+
if (separatorIdx === -1) {
|
|
94
|
+
continue;
|
|
95
|
+
}
|
|
96
|
+
const projectId = key.slice(0, separatorIdx);
|
|
97
|
+
const environmentName = key.slice(separatorIdx + 1);
|
|
98
|
+
if (!projectId || !environmentName) {
|
|
99
|
+
continue;
|
|
100
|
+
}
|
|
101
|
+
const { configName, cwd } = params.resolveProjectStorePath({
|
|
102
|
+
environmentName,
|
|
103
|
+
projectId
|
|
104
|
+
});
|
|
105
|
+
const targetPath = path.join(cwd, `${configName}.json`);
|
|
106
|
+
if (fsSync.existsSync(targetPath)) {
|
|
107
|
+
continue;
|
|
108
|
+
}
|
|
109
|
+
if (!fsSync.existsSync(cwd)) {
|
|
110
|
+
fsSync.mkdirSync(cwd, {
|
|
111
|
+
recursive: true
|
|
112
|
+
});
|
|
113
|
+
}
|
|
114
|
+
const projectConfig = new Conf({
|
|
115
|
+
configName,
|
|
116
|
+
cwd,
|
|
117
|
+
encryptionKey: params.encryptionKey,
|
|
118
|
+
projectName: params.projectName
|
|
119
|
+
});
|
|
120
|
+
projectConfig.set('_schemaVersion', PROJECT_STORE_SCHEMA_VERSION);
|
|
121
|
+
projectConfig.set('bootstrapData', bootstrap);
|
|
122
|
+
const legacyProjectToken = bootstrap.contentSystemId ? projectTokens[bootstrap.contentSystemId] : undefined;
|
|
123
|
+
if (legacyProjectToken) {
|
|
124
|
+
projectConfig.set('projectToken', legacyProjectToken);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
// Leave the legacy file untouched so older CLI versions installed in other
|
|
128
|
+
// projects on the same machine can keep reading their last known state.
|
|
129
|
+
}
|
|
130
|
+
function safeGet(config, key) {
|
|
131
|
+
try {
|
|
132
|
+
return config.get(key);
|
|
133
|
+
} catch (error) {
|
|
134
|
+
log.debug(`Migration read failed (key: ${String(key)}). ` + `File: ${config.path}. ` + `Error: ${error instanceof Error ? error.message : 'Unknown'}`);
|
|
135
|
+
return undefined;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Open the legacy Conf store without `clearInvalidConfig`, so a decrypt
|
|
140
|
+
* error does not destroy the file. Returns null when the file cannot be
|
|
141
|
+
* opened — callers treat that as "nothing to migrate, leave file alone".
|
|
142
|
+
*/ function openLegacyConfig(params) {
|
|
143
|
+
try {
|
|
144
|
+
return new Conf({
|
|
145
|
+
configName: params.legacyConfigName,
|
|
146
|
+
cwd: params.legacyCwd,
|
|
147
|
+
encryptionKey: params.encryptionKey,
|
|
148
|
+
projectName: params.projectName
|
|
149
|
+
});
|
|
150
|
+
} catch (error) {
|
|
151
|
+
log.debug(`Legacy token store could not be opened; skipping migration and leaving file intact. ` + `Error: ${error instanceof Error ? error.message : 'Unknown'}`);
|
|
152
|
+
return null;
|
|
153
|
+
}
|
|
154
|
+
}
|