@payloadcms/figma 0.0.1-alpha.49 → 0.0.1-alpha.50

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (267) hide show
  1. package/dist/api/control-plane.d.ts +23 -14
  2. package/dist/api/control-plane.js +23 -22
  3. package/dist/api/figma-api.js +3 -5
  4. package/dist/auth/project-token.js +2 -2
  5. package/dist/auth/token-store.d.ts +29 -2
  6. package/dist/auth/token-store.js +38 -1
  7. package/dist/auth/types.d.ts +10 -0
  8. package/dist/cli.js +18 -9
  9. package/dist/commands/debug.js +31 -26
  10. package/dist/commands/deploy.d.ts +3 -1
  11. package/dist/commands/deploy.js +27 -15
  12. package/dist/commands/env.d.ts +13 -0
  13. package/dist/commands/env.js +88 -0
  14. package/dist/commands/init.d.ts +2 -0
  15. package/dist/commands/init.js +49 -52
  16. package/dist/commands/list-tokens.js +2 -2
  17. package/dist/commands/login.js +3 -3
  18. package/dist/commands/logout.js +2 -2
  19. package/dist/config/oauth.d.ts +1 -1
  20. package/dist/config/oauth.js +3 -4
  21. package/dist/constants.d.ts +11 -7
  22. package/dist/constants.js +14 -9
  23. package/dist/db-content-api/index.js +6 -11
  24. package/dist/oauth/strategy/index.js +2 -2
  25. package/dist/oauth/utilities/refreshTokens.js +2 -2
  26. package/dist/plugin/build-config.d.ts +0 -10
  27. package/dist/plugin/build-config.js +57 -22
  28. package/dist/templates/.env.example +4 -10
  29. package/dist/types.d.ts +2 -0
  30. package/dist/utils/cache-bootstrap.d.ts +8 -0
  31. package/dist/utils/cache-bootstrap.js +18 -0
  32. package/dist/utils/messages.js +15 -2
  33. package/dist/utils/resolve-environment.d.ts +14 -0
  34. package/dist/utils/resolve-environment.js +28 -0
  35. package/package.json +3 -2
  36. package/dist/api/control-plane.d.ts.map +0 -1
  37. package/dist/api/control-plane.js.map +0 -1
  38. package/dist/api/figma-api.d.ts.map +0 -1
  39. package/dist/api/figma-api.js.map +0 -1
  40. package/dist/auth/browser.d.ts.map +0 -1
  41. package/dist/auth/browser.js.map +0 -1
  42. package/dist/auth/callback-server.d.ts.map +0 -1
  43. package/dist/auth/callback-server.js.map +0 -1
  44. package/dist/auth/crypto-utils.d.ts.map +0 -1
  45. package/dist/auth/crypto-utils.js.map +0 -1
  46. package/dist/auth/jwt-validator.d.ts.map +0 -1
  47. package/dist/auth/jwt-validator.js.map +0 -1
  48. package/dist/auth/oauth-flow.d.ts.map +0 -1
  49. package/dist/auth/oauth-flow.js.map +0 -1
  50. package/dist/auth/pkce.d.ts.map +0 -1
  51. package/dist/auth/pkce.js.map +0 -1
  52. package/dist/auth/project-token.d.ts.map +0 -1
  53. package/dist/auth/project-token.js.map +0 -1
  54. package/dist/auth/refresh.d.ts.map +0 -1
  55. package/dist/auth/refresh.js.map +0 -1
  56. package/dist/auth/token-store.d.ts.map +0 -1
  57. package/dist/auth/token-store.js.map +0 -1
  58. package/dist/auth/types.d.ts.map +0 -1
  59. package/dist/auth/types.js.map +0 -1
  60. package/dist/cli.d.ts.map +0 -1
  61. package/dist/cli.js.map +0 -1
  62. package/dist/commands/build-lambda-zip.d.ts.map +0 -1
  63. package/dist/commands/build-lambda-zip.js.map +0 -1
  64. package/dist/commands/debug.d.ts.map +0 -1
  65. package/dist/commands/debug.js.map +0 -1
  66. package/dist/commands/deploy.d.ts.map +0 -1
  67. package/dist/commands/deploy.js.map +0 -1
  68. package/dist/commands/init.d.ts.map +0 -1
  69. package/dist/commands/init.js.map +0 -1
  70. package/dist/commands/list-tokens.d.ts.map +0 -1
  71. package/dist/commands/list-tokens.js.map +0 -1
  72. package/dist/commands/login.d.ts.map +0 -1
  73. package/dist/commands/login.js.map +0 -1
  74. package/dist/commands/logout.d.ts.map +0 -1
  75. package/dist/commands/logout.js.map +0 -1
  76. package/dist/config/oauth.d.ts.map +0 -1
  77. package/dist/config/oauth.js.map +0 -1
  78. package/dist/constants.d.ts.map +0 -1
  79. package/dist/constants.js.map +0 -1
  80. package/dist/db-content-api/generated/content-api-types.d.ts.map +0 -1
  81. package/dist/db-content-api/generated/content-api-types.js.map +0 -1
  82. package/dist/db-content-api/index.d.ts.map +0 -1
  83. package/dist/db-content-api/index.js.map +0 -1
  84. package/dist/db-content-api/temp-utilities/slug.d.ts.map +0 -1
  85. package/dist/db-content-api/temp-utilities/slug.js.map +0 -1
  86. package/dist/db-content-api/temp-utilities/sorting.d.ts.map +0 -1
  87. package/dist/db-content-api/temp-utilities/sorting.js.map +0 -1
  88. package/dist/db-content-api/temp-utilities/types.d.ts.map +0 -1
  89. package/dist/db-content-api/temp-utilities/types.js.map +0 -1
  90. package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts.map +0 -1
  91. package/dist/db-content-api/temp-utilities/unwrapDocument.js.map +0 -1
  92. package/dist/db-content-api/utilities/auth.d.ts.map +0 -1
  93. package/dist/db-content-api/utilities/auth.js.map +0 -1
  94. package/dist/db-content-api/utilities/data/applyDefaults.d.ts.map +0 -1
  95. package/dist/db-content-api/utilities/data/applyDefaults.js.map +0 -1
  96. package/dist/db-content-api/utilities/data/castFieldValue.d.ts.map +0 -1
  97. package/dist/db-content-api/utilities/data/castFieldValue.js.map +0 -1
  98. package/dist/db-content-api/utilities/data/index.d.ts.map +0 -1
  99. package/dist/db-content-api/utilities/data/index.js.map +0 -1
  100. package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts.map +0 -1
  101. package/dist/db-content-api/utilities/data/removeVirtualFields.js.map +0 -1
  102. package/dist/db-content-api/utilities/data/stripFields.d.ts.map +0 -1
  103. package/dist/db-content-api/utilities/data/stripFields.js.map +0 -1
  104. package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts.map +0 -1
  105. package/dist/db-content-api/utilities/data/transformPublishedLocale.js.map +0 -1
  106. package/dist/db-content-api/utilities/joins.d.ts.map +0 -1
  107. package/dist/db-content-api/utilities/joins.js.map +0 -1
  108. package/dist/db-content-api/utilities/locale/index.d.ts.map +0 -1
  109. package/dist/db-content-api/utilities/locale/index.js.map +0 -1
  110. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts.map +0 -1
  111. package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js.map +0 -1
  112. package/dist/db-content-api/utilities/meta/buildMeta.d.ts.map +0 -1
  113. package/dist/db-content-api/utilities/meta/buildMeta.js.map +0 -1
  114. package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts.map +0 -1
  115. package/dist/db-content-api/utilities/meta/buildPathTypes.js.map +0 -1
  116. package/dist/db-content-api/utilities/where.d.ts.map +0 -1
  117. package/dist/db-content-api/utilities/where.js.map +0 -1
  118. package/dist/endpoints/health.d.ts.map +0 -1
  119. package/dist/endpoints/health.js.map +0 -1
  120. package/dist/endpoints/schema.d.ts.map +0 -1
  121. package/dist/endpoints/schema.js.map +0 -1
  122. package/dist/exports/client.d.ts.map +0 -1
  123. package/dist/exports/client.js.map +0 -1
  124. package/dist/index.d.ts.map +0 -1
  125. package/dist/index.js.map +0 -1
  126. package/dist/oauth/components/FigmaAvatar/index.d.ts.map +0 -1
  127. package/dist/oauth/components/FigmaAvatar/index.js.map +0 -1
  128. package/dist/oauth/components/FigmaAvatarCell/index.d.ts.map +0 -1
  129. package/dist/oauth/components/FigmaAvatarCell/index.js.map +0 -1
  130. package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts.map +0 -1
  131. package/dist/oauth/components/FigmaAvatarPlaceholder/index.js.map +0 -1
  132. package/dist/oauth/components/LoginButton/index.d.ts.map +0 -1
  133. package/dist/oauth/components/LoginButton/index.js.map +0 -1
  134. package/dist/oauth/components/LogoutButton/index.d.ts.map +0 -1
  135. package/dist/oauth/components/LogoutButton/index.js.map +0 -1
  136. package/dist/oauth/defaults.d.ts.map +0 -1
  137. package/dist/oauth/defaults.js.map +0 -1
  138. package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +0 -1
  139. package/dist/oauth/endpoints/getLoginEndpoint.js.map +0 -1
  140. package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +0 -1
  141. package/dist/oauth/endpoints/getLogoutEndpoint.js.map +0 -1
  142. package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +0 -1
  143. package/dist/oauth/endpoints/getMetaEndpoint.js.map +0 -1
  144. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +0 -1
  145. package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +0 -1
  146. package/dist/oauth/exports/client.d.ts.map +0 -1
  147. package/dist/oauth/exports/client.js.map +0 -1
  148. package/dist/oauth/hooks/afterLogout.d.ts.map +0 -1
  149. package/dist/oauth/hooks/afterLogout.js.map +0 -1
  150. package/dist/oauth/hooks/me.d.ts.map +0 -1
  151. package/dist/oauth/hooks/me.js.map +0 -1
  152. package/dist/oauth/hooks/refresh.d.ts.map +0 -1
  153. package/dist/oauth/hooks/refresh.js.map +0 -1
  154. package/dist/oauth/index.d.ts.map +0 -1
  155. package/dist/oauth/index.js.map +0 -1
  156. package/dist/oauth/strategy/index.d.ts.map +0 -1
  157. package/dist/oauth/strategy/index.js.map +0 -1
  158. package/dist/oauth/types.d.ts.map +0 -1
  159. package/dist/oauth/types.js.map +0 -1
  160. package/dist/oauth/utilities/clearCookie.d.ts.map +0 -1
  161. package/dist/oauth/utilities/clearCookie.js.map +0 -1
  162. package/dist/oauth/utilities/createCookieOptions.d.ts.map +0 -1
  163. package/dist/oauth/utilities/createCookieOptions.js.map +0 -1
  164. package/dist/oauth/utilities/createDebugLogger.d.ts.map +0 -1
  165. package/dist/oauth/utilities/createDebugLogger.js.map +0 -1
  166. package/dist/oauth/utilities/extractOrigin.d.ts.map +0 -1
  167. package/dist/oauth/utilities/extractOrigin.js.map +0 -1
  168. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +0 -1
  169. package/dist/oauth/utilities/getAdminCollectionSlug.js.map +0 -1
  170. package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +0 -1
  171. package/dist/oauth/utilities/getAuthorizeURL.js.map +0 -1
  172. package/dist/oauth/utilities/getCookieExpiration.d.ts.map +0 -1
  173. package/dist/oauth/utilities/getCookieExpiration.js.map +0 -1
  174. package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +0 -1
  175. package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +0 -1
  176. package/dist/oauth/utilities/getTokenExp.d.ts.map +0 -1
  177. package/dist/oauth/utilities/getTokenExp.js.map +0 -1
  178. package/dist/oauth/utilities/getUsernameField.d.ts.map +0 -1
  179. package/dist/oauth/utilities/getUsernameField.js.map +0 -1
  180. package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +0 -1
  181. package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +0 -1
  182. package/dist/oauth/utilities/isDuplicateKeyError.d.ts.map +0 -1
  183. package/dist/oauth/utilities/isDuplicateKeyError.js.map +0 -1
  184. package/dist/oauth/utilities/mergeHeaders.d.ts.map +0 -1
  185. package/dist/oauth/utilities/mergeHeaders.js.map +0 -1
  186. package/dist/oauth/utilities/refreshTokens.d.ts.map +0 -1
  187. package/dist/oauth/utilities/refreshTokens.js.map +0 -1
  188. package/dist/plugin/adapter.d.ts.map +0 -1
  189. package/dist/plugin/adapter.js.map +0 -1
  190. package/dist/plugin/build-config.d.ts.map +0 -1
  191. package/dist/plugin/build-config.js.map +0 -1
  192. package/dist/storage-content-api/api-types.d.ts.map +0 -1
  193. package/dist/storage-content-api/api-types.js.map +0 -1
  194. package/dist/storage-content-api/client-uploads/ClientUploadHandler.d.ts.map +0 -1
  195. package/dist/storage-content-api/client-uploads/ClientUploadHandler.js.map +0 -1
  196. package/dist/storage-content-api/client-uploads/generateSignedURL.d.ts.map +0 -1
  197. package/dist/storage-content-api/client-uploads/generateSignedURL.js.map +0 -1
  198. package/dist/storage-content-api/client.d.ts.map +0 -1
  199. package/dist/storage-content-api/client.js.map +0 -1
  200. package/dist/storage-content-api/generateURL.d.ts.map +0 -1
  201. package/dist/storage-content-api/generateURL.js.map +0 -1
  202. package/dist/storage-content-api/handleDelete.d.ts.map +0 -1
  203. package/dist/storage-content-api/handleDelete.js.map +0 -1
  204. package/dist/storage-content-api/handleUpload.d.ts.map +0 -1
  205. package/dist/storage-content-api/handleUpload.js.map +0 -1
  206. package/dist/storage-content-api/index.d.ts.map +0 -1
  207. package/dist/storage-content-api/index.js.map +0 -1
  208. package/dist/storage-content-api/staticHandler.d.ts.map +0 -1
  209. package/dist/storage-content-api/staticHandler.js.map +0 -1
  210. package/dist/storage-content-api/types.d.ts.map +0 -1
  211. package/dist/storage-content-api/types.js.map +0 -1
  212. package/dist/storage-content-api/utilities/getSafeFilename.d.ts.map +0 -1
  213. package/dist/storage-content-api/utilities/getSafeFilename.js.map +0 -1
  214. package/dist/storage-content-api/utilities/index.d.ts.map +0 -1
  215. package/dist/storage-content-api/utilities/index.js.map +0 -1
  216. package/dist/types/config.d.ts.map +0 -1
  217. package/dist/types/config.js.map +0 -1
  218. package/dist/types.d.ts.map +0 -1
  219. package/dist/types.js.map +0 -1
  220. package/dist/utils/asset-collection.d.ts.map +0 -1
  221. package/dist/utils/asset-collection.js.map +0 -1
  222. package/dist/utils/build-detection.d.ts.map +0 -1
  223. package/dist/utils/build-detection.js.map +0 -1
  224. package/dist/utils/build-lambda-zip.d.ts.map +0 -1
  225. package/dist/utils/build-lambda-zip.js.map +0 -1
  226. package/dist/utils/config.d.ts.map +0 -1
  227. package/dist/utils/config.js.map +0 -1
  228. package/dist/utils/download-template.d.ts.map +0 -1
  229. package/dist/utils/download-template.js.map +0 -1
  230. package/dist/utils/env-management.d.ts.map +0 -1
  231. package/dist/utils/env-management.js.map +0 -1
  232. package/dist/utils/format-env-suffix.d.ts.map +0 -1
  233. package/dist/utils/format-env-suffix.js.map +0 -1
  234. package/dist/utils/format.d.ts.map +0 -1
  235. package/dist/utils/format.js.map +0 -1
  236. package/dist/utils/formatter.d.ts.map +0 -1
  237. package/dist/utils/formatter.js.map +0 -1
  238. package/dist/utils/git.d.ts.map +0 -1
  239. package/dist/utils/git.js.map +0 -1
  240. package/dist/utils/is-debug.d.ts.map +0 -1
  241. package/dist/utils/is-debug.js.map +0 -1
  242. package/dist/utils/lambda-config.d.ts.map +0 -1
  243. package/dist/utils/lambda-config.js.map +0 -1
  244. package/dist/utils/log.d.ts.map +0 -1
  245. package/dist/utils/log.js.map +0 -1
  246. package/dist/utils/messages.d.ts.map +0 -1
  247. package/dist/utils/messages.js.map +0 -1
  248. package/dist/utils/package-manager.d.ts.map +0 -1
  249. package/dist/utils/package-manager.js.map +0 -1
  250. package/dist/utils/payload-config-ast.d.ts.map +0 -1
  251. package/dist/utils/payload-config-ast.js.map +0 -1
  252. package/dist/utils/payload-config-finder.d.ts.map +0 -1
  253. package/dist/utils/payload-config-finder.js.map +0 -1
  254. package/dist/utils/payload-config-modifier.d.ts.map +0 -1
  255. package/dist/utils/payload-config-modifier.js.map +0 -1
  256. package/dist/utils/payload-package-check.d.ts.map +0 -1
  257. package/dist/utils/payload-package-check.js.map +0 -1
  258. package/dist/utils/project.d.ts.map +0 -1
  259. package/dist/utils/project.js.map +0 -1
  260. package/dist/utils/s3-upload.d.ts.map +0 -1
  261. package/dist/utils/s3-upload.js.map +0 -1
  262. package/dist/utils/token-display.d.ts.map +0 -1
  263. package/dist/utils/token-display.js.map +0 -1
  264. package/dist/utils/typescript-validator.d.ts.map +0 -1
  265. package/dist/utils/typescript-validator.js.map +0 -1
  266. package/dist/utils/version-check.d.ts.map +0 -1
  267. package/dist/utils/version-check.js.map +0 -1
@@ -78,15 +78,6 @@ export interface PerformDeploymentApiResponse {
78
78
  };
79
79
  status: number;
80
80
  }
81
- /**
82
- * Response from getDatasetInfo endpoint
83
- */
84
- export type DatasetInfo = {
85
- cmsId: string;
86
- oauthClientId: string;
87
- oauthClientSecret: string;
88
- tenantId: string;
89
- };
90
81
  /**
91
82
  * List all tenant instances for the authenticated user
92
83
  * Maps to: GET /v1/tenant
@@ -134,12 +125,30 @@ export declare function createDeployment(accessToken: string, tenantId: string,
134
125
  */
135
126
  export declare function performDeployment(accessToken: string, tenantId: string, options: PerformDeploymentOptions): Promise<PerformDeploymentResponse>;
136
127
  /**
137
- * Get dataset info including tenant ID and OAuth credentials
138
- * Maps to: GET /v1/cms/dataset/:datasetId
128
+ * A single environment returned by the bootstrap endpoint
129
+ */
130
+ export type BootstrapEnvironment = {
131
+ contentSystemId: string;
132
+ name: string;
133
+ tenantInstanceId: string;
134
+ };
135
+ /**
136
+ * Response from the bootstrap endpoint (camelCased)
137
+ */
138
+ export type BootstrapInfo = {
139
+ environments: BootstrapEnvironment[];
140
+ oauthCredentials: {
141
+ oauthClientId: string;
142
+ oauthClientSecret: string;
143
+ };
144
+ };
145
+ /**
146
+ * Get bootstrap info for a CMS resource
147
+ * Maps to: GET /v1/cms/:cmsResourceId/bootstrap
139
148
  *
140
149
  * @param accessToken - OAuth access token
141
- * @param datasetId - Content System ID (dataset ID)
142
- * @returns Dataset info with tenant ID and OAuth credentials
150
+ * @param cmsResourceId - CMS Resource ID (project ID)
151
+ * @param environmentName - Optional environment name filter
143
152
  */
144
- export declare function getDatasetInfo(accessToken: string, datasetId: string): Promise<DatasetInfo>;
153
+ export declare function getBootstrapInfo(accessToken: string, cmsResourceId: string, environmentName?: string): Promise<BootstrapInfo>;
145
154
  //# sourceMappingURL=control-plane.d.ts.map
@@ -2,12 +2,12 @@
2
2
  * Control Plane API Client
3
3
  *
4
4
  * TODO: Replace with real API calls when Control Plane is available
5
- */ import { ENV_CONFIG, getEnvironment } from '../constants.js';
5
+ */ import { getEnvConfig } from '../constants.js';
6
6
  import * as log from '../utils/log.js';
7
7
  /**
8
8
  * Get the Control Plane API base URL based on environment
9
9
  */ function getControlPlaneBaseUrl() {
10
- return process.env.FIGMA_API_BASE_URL || ENV_CONFIG[getEnvironment()].apiBaseUrl;
10
+ return process.env.FIGMA_API_BASE_URL || getEnvConfig().apiBaseUrl;
11
11
  }
12
12
  /**
13
13
  * Error thrown when Control Plane API calls fail
@@ -241,17 +241,21 @@ import * as log from '../utils/log.js';
241
241
  };
242
242
  }
243
243
  /**
244
- * Get dataset info including tenant ID and OAuth credentials
245
- * Maps to: GET /v1/cms/dataset/:datasetId
244
+ * Get bootstrap info for a CMS resource
245
+ * Maps to: GET /v1/cms/:cmsResourceId/bootstrap
246
246
  *
247
247
  * @param accessToken - OAuth access token
248
- * @param datasetId - Content System ID (dataset ID)
249
- * @returns Dataset info with tenant ID and OAuth credentials
250
- */ export async function getDatasetInfo(accessToken, datasetId) {
251
- const url = `${getControlPlaneBaseUrl()}/v1/cms/dataset/${datasetId}`;
252
- log.debug(`Calling getDatasetInfo API at ${url}`);
248
+ * @param cmsResourceId - CMS Resource ID (project ID)
249
+ * @param environmentName - Optional environment name filter
250
+ */ export async function getBootstrapInfo(accessToken, cmsResourceId, environmentName) {
251
+ const baseUrl = getControlPlaneBaseUrl();
252
+ let url = `${baseUrl}/v1/cms/${cmsResourceId}/bootstrap`;
253
+ if (environmentName) {
254
+ url += `?environment_name=${encodeURIComponent(environmentName)}`;
255
+ }
256
+ log.debug(`Calling getBootstrapInfo API at ${url}`);
253
257
  const response = await controlPlaneFetch({
254
- context: 'get dataset info',
258
+ context: 'get bootstrap info',
255
259
  options: {
256
260
  headers: {
257
261
  Authorization: `Bearer ${accessToken}`
@@ -260,19 +264,16 @@ import * as log from '../utils/log.js';
260
264
  url
261
265
  });
262
266
  const data = await response.json();
263
- const sanitizedData = {
264
- ...data,
265
- meta: {
266
- ...data.meta,
267
- oauth_client_secret: '[REDACTED]'
268
- }
269
- };
270
- log.debug(`Dataset API response: ${JSON.stringify(sanitizedData, null, 2)}`);
271
267
  return {
272
- cmsId: data.meta.cms_resource_id,
273
- oauthClientId: data.meta.oauth_client_id,
274
- oauthClientSecret: data.meta.oauth_client_secret,
275
- tenantId: data.meta.tenant_instance_id
268
+ environments: data.meta.environments.map((env)=>({
269
+ name: env.name,
270
+ contentSystemId: env.content_system_id,
271
+ tenantInstanceId: env.tenant_instance_id
272
+ })),
273
+ oauthCredentials: {
274
+ oauthClientId: data.meta.oauth_credentials.oauth_client_id,
275
+ oauthClientSecret: data.meta.oauth_credentials.oauth_client_secret
276
+ }
276
277
  };
277
278
  }
278
279
  const MAX_RETRIES = 3;
@@ -3,7 +3,7 @@
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 { ENV_CONFIG, getEnvironment } from '../constants.js';
6
+ */ import { getEnvConfig } from '../constants.js';
7
7
  import * as log from '../utils/log.js';
8
8
  /**
9
9
  * Error thrown when Figma API calls fail
@@ -84,8 +84,7 @@ import * as log from '../utils/log.js';
84
84
  };
85
85
  }
86
86
  // REAL API IMPLEMENTATION
87
- const env = getEnvironment();
88
- const baseUrl = process.env.FIGMA_API_BASE_URL || ENV_CONFIG[env].apiBaseUrl;
87
+ const baseUrl = process.env.FIGMA_API_BASE_URL || getEnvConfig().apiBaseUrl;
89
88
  const url = `${baseUrl}/v1/cms/${tenantId}/token/`;
90
89
  const response = await fetch(url, {
91
90
  headers: {
@@ -199,8 +198,7 @@ import * as log from '../utils/log.js';
199
198
  * @returns FigmaUserInfo with user profile data
200
199
  * @throws {FigmaApiError} If the API call fails
201
200
  */ export async function getUserInfo(accessToken) {
202
- const env = getEnvironment();
203
- const baseUrl = process.env.FIGMA_API_BASE_URL || ENV_CONFIG[env].apiBaseUrl;
201
+ const baseUrl = process.env.FIGMA_API_BASE_URL || getEnvConfig().apiBaseUrl;
204
202
  const url = `${baseUrl}/v1/me`;
205
203
  try {
206
204
  const response = await fetch(url, {
@@ -5,7 +5,7 @@
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 { getEnvironment } from '../constants.js';
8
+ import { getInfraEnvironment } from '../constants.js';
9
9
  import * as log from '../utils/log.js';
10
10
  import { JWTValidationError, validateProjectToken } from './jwt-validator.js';
11
11
  import { getValidAccessToken } from './oauth-flow.js';
@@ -94,7 +94,7 @@ import { getValidAccessToken } from './oauth-flow.js';
94
94
  } else {
95
95
  // REAL: Validate JWT signature against JWKS
96
96
  try {
97
- validatedClaims = await validateProjectToken(projectToken.token, getEnvironment());
97
+ validatedClaims = await validateProjectToken(projectToken.token, getInfraEnvironment());
98
98
  } catch (validationError) {
99
99
  // Handle validation errors
100
100
  if (validationError instanceof JWTValidationError) {
@@ -1,5 +1,5 @@
1
1
  import type { Environment } from '../constants.js';
2
- import type { FigmaTokens, JWTPayload, ProjectToken, TokenStoreConfig } from './types.js';
2
+ import type { BootstrapData, FigmaTokens, JWTPayload, ProjectToken, TokenStoreConfig } from './types.js';
3
3
  /**
4
4
  * Get the singleton TokenStore instance for an environment
5
5
  * Use this for all production code to ensure a single shared instance per environment
@@ -7,7 +7,7 @@ import type { FigmaTokens, JWTPayload, ProjectToken, TokenStoreConfig } from './
7
7
  * @param environment - The environment to get the token store for
8
8
  * @returns The singleton TokenStore instance for that environment
9
9
  */
10
- export declare function getTokenStore(environment: Environment): TokenStore;
10
+ export declare function getTokenStore(environment?: Environment): TokenStore;
11
11
  /**
12
12
  * Secure storage manager for Figma OAuth2 tokens
13
13
  *
@@ -118,5 +118,32 @@ export declare class TokenStore {
118
118
  * @returns Array of tenant IDs
119
119
  */
120
120
  getAllProjectTokenTenantIds(): string[];
121
+ /**
122
+ * Build the composite key for bootstrap data storage
123
+ * @param projectId - The CMS resource/project ID
124
+ * @param environmentName - The environment name (e.g. 'production', 'staging')
125
+ * @returns Composite key string
126
+ */
127
+ private bootstrapKey;
128
+ /**
129
+ * Retrieve bootstrap data for a project + environment
130
+ * @param projectId - The CMS resource/project ID
131
+ * @param environmentName - The environment name
132
+ * @returns BootstrapData if stored, null otherwise
133
+ */
134
+ getBootstrapData(projectId: string, environmentName: string): BootstrapData | null;
135
+ /**
136
+ * Store bootstrap data for a project + environment
137
+ * @param projectId - The CMS resource/project ID
138
+ * @param environmentName - The environment name
139
+ * @param data - The bootstrap data to store
140
+ */
141
+ setBootstrapData(projectId: string, environmentName: string, data: BootstrapData): void;
142
+ /**
143
+ * Clear bootstrap data for a project + environment
144
+ * @param projectId - The CMS resource/project ID
145
+ * @param environmentName - The environment name
146
+ */
147
+ clearBootstrapData(projectId: string, environmentName: string): void;
121
148
  }
122
149
  //# sourceMappingURL=token-store.d.ts.map
@@ -1,5 +1,6 @@
1
1
  /* eslint-disable perfectionist/sort-classes */ import Conf from 'conf';
2
2
  import { TOKEN_EXPIRY_BUFFER_SECONDS } from '../config/oauth.js';
3
+ import { getInfraEnvironment } from '../constants.js';
3
4
  import { deriveEncryptionKey } from './crypto-utils.js';
4
5
  /**
5
6
  * Environment-keyed instances for singleton pattern
@@ -10,7 +11,7 @@ import { deriveEncryptionKey } from './crypto-utils.js';
10
11
  *
11
12
  * @param environment - The environment to get the token store for
12
13
  * @returns The singleton TokenStore instance for that environment
13
- */ export function getTokenStore(environment) {
14
+ */ export function getTokenStore(environment = getInfraEnvironment()) {
14
15
  if (!instances[environment]) {
15
16
  instances[environment] = new TokenStore({
16
17
  environment
@@ -206,6 +207,42 @@ import { deriveEncryptionKey } from './crypto-utils.js';
206
207
  const projectTokens = this.config.get('projectTokens') || {};
207
208
  return Object.keys(projectTokens);
208
209
  }
210
+ /**
211
+ * Build the composite key for bootstrap data storage
212
+ * @param projectId - The CMS resource/project ID
213
+ * @param environmentName - The environment name (e.g. 'production', 'staging')
214
+ * @returns Composite key string
215
+ */ bootstrapKey(projectId, environmentName) {
216
+ return `${projectId}:${environmentName}`;
217
+ }
218
+ /**
219
+ * Retrieve bootstrap data for a project + environment
220
+ * @param projectId - The CMS resource/project ID
221
+ * @param environmentName - The environment name
222
+ * @returns BootstrapData if stored, null otherwise
223
+ */ getBootstrapData(projectId, environmentName) {
224
+ const allData = this.config.get('bootstrapData') || {};
225
+ return allData[this.bootstrapKey(projectId, environmentName)] || null;
226
+ }
227
+ /**
228
+ * Store bootstrap data for a project + environment
229
+ * @param projectId - The CMS resource/project ID
230
+ * @param environmentName - The environment name
231
+ * @param data - The bootstrap data to store
232
+ */ setBootstrapData(projectId, environmentName, data) {
233
+ const allData = this.config.get('bootstrapData') || {};
234
+ allData[this.bootstrapKey(projectId, environmentName)] = data;
235
+ this.config.set('bootstrapData', allData);
236
+ }
237
+ /**
238
+ * Clear bootstrap data for a project + environment
239
+ * @param projectId - The CMS resource/project ID
240
+ * @param environmentName - The environment name
241
+ */ clearBootstrapData(projectId, environmentName) {
242
+ const allData = this.config.get('bootstrapData') || {};
243
+ delete allData[this.bootstrapKey(projectId, environmentName)];
244
+ this.config.set('bootstrapData', allData);
245
+ }
209
246
  }
210
247
 
211
248
  //# sourceMappingURL=token-store.js.map
@@ -161,6 +161,16 @@ export type FigmaErrorResponse = ErrorResponsePayloadWithErrMessage | ErrorRespo
161
161
  * Re-exported from @figma/rest-api-spec
162
162
  */
163
163
  export type FigmaUser = User;
164
+ /**
165
+ * Bootstrap data cached in the local encrypted store
166
+ * Keyed by projectId:environmentName
167
+ */
168
+ export type BootstrapData = {
169
+ contentSystemId: string;
170
+ oauthClientId: string;
171
+ oauthClientSecret: string;
172
+ tenantInstanceId: string;
173
+ };
164
174
  /**
165
175
  * JWT payload structure from Figma project tokens
166
176
  * Extends jose's standard JWTPayload with Figma-specific claims
package/dist/cli.js CHANGED
@@ -4,11 +4,12 @@ import pc from 'picocolors';
4
4
  import { buildLambdaZipCommand } from './commands/build-lambda-zip.js';
5
5
  import { debugCommand } from './commands/debug.js';
6
6
  import { deployCommand } from './commands/deploy.js';
7
+ import { envCommand } from './commands/env.js';
7
8
  import { initCommand } from './commands/init.js';
8
9
  import { listTokensCommand } from './commands/list-tokens.js';
9
10
  import { loginCommand } from './commands/login.js';
10
11
  import { logoutCommand } from './commands/logout.js';
11
- import { setEnvironment } from './constants.js';
12
+ import { setInfraEnvironment } from './constants.js';
12
13
  import { helpMessage } from './utils/messages.js';
13
14
  /**
14
15
  * Entrypoint for bin/cli.js
@@ -33,6 +34,7 @@ class Main {
33
34
  '--force': Boolean,
34
35
  '--help': Boolean,
35
36
  '--id': String,
37
+ '--infra-env': String,
36
38
  '--name': String,
37
39
  '--skip-auth': Boolean,
38
40
  '--skip-build': Boolean,
@@ -50,16 +52,16 @@ class Main {
50
52
  if (this.args['--debug']) {
51
53
  process.env.DEBUG = 'true';
52
54
  }
53
- // Handle --env flag for environment switching
54
- if (this.args['--env']) {
55
- const envArg = this.args['--env'].toLowerCase();
56
- if (envArg === 'prod' || envArg === 'production') {
57
- setEnvironment('production');
58
- } else if (envArg === 'staging') {
59
- setEnvironment('staging');
55
+ // Handle --infra-env flag for infrastructure environment switching
56
+ if (this.args['--infra-env']) {
57
+ const infraEnvArg = this.args['--infra-env'].toLowerCase();
58
+ if (infraEnvArg === 'prod' || infraEnvArg === 'production') {
59
+ setInfraEnvironment('production');
60
+ } else if (infraEnvArg === 'staging') {
61
+ setInfraEnvironment('staging');
60
62
  } else {
61
63
  // eslint-disable-next-line no-console
62
- console.error(`Invalid --env value: ${this.args['--env']}. Use 'prod' or 'staging'.`);
64
+ console.error(`Invalid --infra-env value: ${this.args['--infra-env']}. Use 'production' or 'staging'.`);
63
65
  process.exit(1);
64
66
  }
65
67
  }
@@ -100,15 +102,22 @@ class Main {
100
102
  await deployCommand({
101
103
  id: this.args['--id'],
102
104
  debug: this.args['--debug'],
105
+ env: this.args['--env'],
103
106
  skipBuild: this.args['--skip-build'],
104
107
  yes: this.args['--yes']
105
108
  });
106
109
  break;
110
+ case 'env':
111
+ await envCommand({
112
+ name: this.args._[1]
113
+ });
114
+ break;
107
115
  case 'init':
108
116
  await initCommand({
109
117
  id: this.args['--id'],
110
118
  name: this.args['--name'],
111
119
  debug: this.args['--debug'],
120
+ env: this.args['--env'],
112
121
  force: this.args['--force'],
113
122
  skipAuth: this.args['--skip-auth']
114
123
  });
@@ -3,7 +3,7 @@ import { createRequire } from 'node:module';
3
3
  import os from 'node:os';
4
4
  import path from 'node:path';
5
5
  import { getTokenStore } from '../auth/token-store.js';
6
- import { getEnvironment } from '../constants.js';
6
+ import { getInfraEnvironment } from '../constants.js';
7
7
  import { getEnvVarSync } from '../utils/env-management.js';
8
8
  import { maskToken } from '../utils/token-display.js';
9
9
  import { getOwnVersion } from '../utils/version-check.js';
@@ -13,7 +13,7 @@ import { getOwnVersion } from '../utils/version-check.js';
13
13
  * Outputs environment, auth, project, and package info for debugging.
14
14
  * All data is local — no network calls are made.
15
15
  */ export async function debugCommand() {
16
- const env = getEnvironment();
16
+ const env = getInfraEnvironment();
17
17
  const tokenStore = getTokenStore(env);
18
18
  const cwd = process.cwd();
19
19
  const lines = [
@@ -28,7 +28,7 @@ import { getOwnVersion } from '../utils/version-check.js';
28
28
  console.log(lines.join('\n'));
29
29
  }
30
30
  function appendSystemSection(lines, env) {
31
- lines.push(`Environment: ${env}`);
31
+ lines.push(`Infra Environment: ${env}`);
32
32
  lines.push(`Node: ${process.version}`);
33
33
  lines.push(`OS: ${os.platform()} ${os.arch()}`);
34
34
  lines.push('');
@@ -53,28 +53,29 @@ function appendAuthSection(lines, tokenStore, cwd) {
53
53
  lines.push('');
54
54
  }
55
55
  function appendProjectSection(lines, tokenStore, cwd) {
56
- const contentSystemId = getEnvVarSync(cwd, 'FIGMA_CONTENT_API_CONTENT_SYSTEM_ID');
57
- const tenantId = getEnvVarSync(cwd, 'FIGMA_TENANT_ID');
58
- const oauthClientId = getEnvVarSync(cwd, 'FIGMA_OAUTH_CLIENT_ID');
56
+ const projectId = getEnvVarSync(cwd, 'FIGMA_PROJECT_ID');
57
+ const environmentName = getEnvVarSync(cwd, 'FIGMA_ENVIRONMENT_NAME');
59
58
  lines.push('Project:');
60
- if (!contentSystemId && !tenantId && !oauthClientId) {
59
+ if (!projectId) {
61
60
  lines.push(" Not initialized (run 'init' first)");
62
61
  lines.push('');
63
62
  return;
64
63
  }
65
- if (contentSystemId) {
66
- lines.push(` Content System ID: ${contentSystemId}`);
67
- }
68
- if (tenantId) {
69
- lines.push(` Tenant ID: ${tenantId}`);
70
- }
71
- if (oauthClientId) {
72
- lines.push(` OAuth Client ID: ${maskToken(oauthClientId)}`);
73
- }
74
- if (contentSystemId) {
75
- const projectToken = tokenStore.getProjectToken(contentSystemId);
76
- if (projectToken) {
77
- lines.push(` Project Token: ${formatExpiryTime(projectToken.expiresAt)}`);
64
+ lines.push(` Project ID: ${projectId}`);
65
+ lines.push(` Environment: ${environmentName ?? '(not set)'}`);
66
+ // Show bootstrap data from local store
67
+ if (projectId && environmentName) {
68
+ const bootstrapData = tokenStore.getBootstrapData(projectId, environmentName);
69
+ if (bootstrapData) {
70
+ lines.push(` Content System ID: ${bootstrapData.contentSystemId}`);
71
+ lines.push(` Tenant Instance ID: ${bootstrapData.tenantInstanceId}`);
72
+ lines.push(` OAuth Client ID: ${maskToken(bootstrapData.oauthClientId)}`);
73
+ const projectToken = tokenStore.getProjectToken(bootstrapData.contentSystemId);
74
+ if (projectToken) {
75
+ lines.push(` Project Token: ${formatExpiryTime(projectToken.expiresAt)}`);
76
+ }
77
+ } else {
78
+ lines.push(' Bootstrap Data: (not cached)');
78
79
  }
79
80
  }
80
81
  lines.push('');
@@ -87,13 +88,17 @@ async function appendPackagesSection(lines) {
87
88
  lines.push(` payload: ${payloadVersion}`);
88
89
  }
89
90
  /**
90
- * Try env-based tenant ID first, then iterate all stored project tokens.
91
+ * Try resolving email from bootstrap data, then iterate all stored project tokens.
91
92
  */ function getEmailFromClaims(tokenStore, cwd) {
92
- const tenantId = getEnvVarSync(cwd, 'FIGMA_TENANT_ID');
93
- if (tenantId) {
94
- const email = tokenStore.getProjectTokenClaims(tenantId)?.email;
95
- if (email) {
96
- return email;
93
+ const projectId = getEnvVarSync(cwd, 'FIGMA_PROJECT_ID');
94
+ const environmentName = getEnvVarSync(cwd, 'FIGMA_ENVIRONMENT_NAME');
95
+ if (projectId && environmentName) {
96
+ const bootstrapData = tokenStore.getBootstrapData(projectId, environmentName);
97
+ if (bootstrapData) {
98
+ const email = tokenStore.getProjectTokenClaims(bootstrapData.contentSystemId)?.email;
99
+ if (email) {
100
+ return email;
101
+ }
97
102
  }
98
103
  }
99
104
  for (const id of tokenStore.getAllProjectTokenTenantIds()){
@@ -4,7 +4,9 @@
4
4
  export interface DeployCommandOptions {
5
5
  /** Enable debug mode */
6
6
  debug?: boolean;
7
- /** Tenant ID */
7
+ /** Figma environment name (e.g. 'production', 'staging') */
8
+ env?: string;
9
+ /** CMS Resource ID (overrides FIGMA_PROJECT_ID) */
8
10
  id?: string;
9
11
  /** Skip the build step (use existing build) */
10
12
  skipBuild?: boolean;
@@ -2,16 +2,17 @@ import * as p from '@clack/prompts';
2
2
  import spawn from 'cross-spawn';
3
3
  import path from 'path';
4
4
  import pc from 'picocolors';
5
- import { ControlPlaneError, createDeployment, getTenantDetails, performDeployment } from '../api/control-plane.js';
5
+ import { ControlPlaneError, createDeployment, getBootstrapInfo, performDeployment } from '../api/control-plane.js';
6
6
  import { getValidAccessToken } from '../auth/oauth-flow.js';
7
7
  import { getTokenStore } from '../auth/token-store.js';
8
- import { CONTENT_SYSTEM_NOT_FOUND_MESSAGE, getEnvironment } from '../constants.js';
8
+ import { CONTENT_SYSTEM_NOT_FOUND_MESSAGE } from '../constants.js';
9
9
  import { collectStaticAssets, createLambdaZip, getFileSize } from '../utils/asset-collection.js';
10
10
  import { detectBuild, getBuildCommand } from '../utils/build-detection.js';
11
11
  import { getEnvVar } from '../utils/env-management.js';
12
12
  import * as log from '../utils/log.js';
13
13
  import { getPackageManager } from '../utils/package-manager.js';
14
14
  import { isInProjectDirectory } from '../utils/project.js';
15
+ import { resolveEnvironment } from '../utils/resolve-environment.js';
15
16
  import { uploadLambdaZip, uploadStaticAssets } from '../utils/s3-upload.js';
16
17
  import { loginCommand } from './login.js';
17
18
  /**
@@ -49,14 +50,17 @@ import { loginCommand } from './login.js';
49
50
  */ export async function deployCommand(options) {
50
51
  const projectPath = process.cwd();
51
52
  const spinner = p.spinner();
52
- let tenantId = options.id;
53
- if (!tenantId) {
54
- tenantId = await getEnvVar(projectPath, 'FIGMA_TENANT_ID') ?? undefined;
53
+ // Resolve project ID
54
+ let projectId = options.id;
55
+ if (!projectId) {
56
+ projectId = await getEnvVar(projectPath, 'FIGMA_PROJECT_ID') ?? undefined;
55
57
  }
56
- if (!tenantId) {
57
- p.log.error(pc.red('✗ Tenant ID not found. Run `@payloadcms/figma init` first.'));
58
+ if (!projectId) {
59
+ p.log.error(pc.red('✗ Project ID not found. Run `@payloadcms/figma init` first, or use --id.'));
58
60
  process.exit(1);
59
61
  }
62
+ // Resolve environment name
63
+ const environmentName = options.env ?? await getEnvVar(projectPath, 'FIGMA_ENVIRONMENT_NAME') ?? undefined;
60
64
  try {
61
65
  // ===== PRE-FLIGHT CHECKS =====
62
66
  // Check if in project directory
@@ -66,7 +70,7 @@ import { loginCommand } from './login.js';
66
70
  process.exit(1);
67
71
  }
68
72
  // Check authentication
69
- const tokenStore = getTokenStore(getEnvironment());
73
+ const tokenStore = getTokenStore();
70
74
  let accessToken = await getValidAccessToken(tokenStore);
71
75
  if (!accessToken) {
72
76
  p.log.message('Please log in to continue');
@@ -77,18 +81,26 @@ import { loginCommand } from './login.js';
77
81
  process.exit(1);
78
82
  }
79
83
  }
80
- // ===== PREFLIGHT: Verify content system exists =====
81
- spinner.start('Verifying content system...');
84
+ // Resolve tenant instance ID via bootstrap
85
+ spinner.start('Resolving deployment target...');
86
+ let tenantInstanceId;
82
87
  try {
83
- await getTenantDetails(accessToken, tenantId);
84
- spinner.stop(pc.green('✓ Content system verified'));
88
+ const bootstrapInfo = await getBootstrapInfo(accessToken, projectId);
89
+ const resolvedEnv = resolveEnvironment({
90
+ environmentName,
91
+ environments: bootstrapInfo.environments
92
+ });
93
+ tenantInstanceId = resolvedEnv.tenantInstanceId;
94
+ spinner.stop(pc.green(`✓ Target: ${resolvedEnv.name}`));
85
95
  } catch (error) {
86
96
  if (error instanceof ControlPlaneError && (error.statusCode === 404 || error.statusCode === 410)) {
87
97
  spinner.stop(pc.red('✗ Content system not found'));
88
98
  p.log.error(pc.red(CONTENT_SYSTEM_NOT_FOUND_MESSAGE));
89
99
  process.exit(1);
90
100
  }
91
- throw error;
101
+ spinner.stop(pc.red('✗ Failed to resolve deployment target'));
102
+ p.log.error(error instanceof Error ? error.message : 'Unknown error');
103
+ process.exit(1);
92
104
  }
93
105
  // ===== BUILD =====
94
106
  let buildInfo;
@@ -201,7 +213,7 @@ import { loginCommand } from './login.js';
201
213
  // ===== DEPLOYMENT EXECUTION =====
202
214
  // Step 1: Create deployment
203
215
  spinner.start('Creating deployment...');
204
- const createResponse = await createDeployment(accessToken, tenantId, {
216
+ const createResponse = await createDeployment(accessToken, tenantInstanceId, {
205
217
  staticAssets
206
218
  });
207
219
  const deploymentId = createResponse.deploymentId;
@@ -227,7 +239,7 @@ import { loginCommand } from './login.js';
227
239
  }
228
240
  // Step 4: Perform deployment
229
241
  spinner.start('Performing deployment...');
230
- const result = await performDeployment(accessToken, tenantId, {
242
+ const result = await performDeployment(accessToken, tenantInstanceId, {
231
243
  deploymentId
232
244
  });
233
245
  const tenantDomains = result.tenantDomains ?? [];
@@ -0,0 +1,13 @@
1
+ export interface EnvCommandOptions {
2
+ /** Environment name to switch to (skips interactive prompt) */
3
+ name?: string;
4
+ }
5
+ /**
6
+ * Handle the `@payloadcms/figma env [name]` command
7
+ *
8
+ * If name is provided, switches directly. Otherwise lists available
9
+ * environments with an interactive picker.
10
+ * Updates FIGMA_ENVIRONMENT_NAME in .env and caches all bootstrap data.
11
+ */
12
+ export declare function envCommand(options: EnvCommandOptions): Promise<void>;
13
+ //# sourceMappingURL=env.d.ts.map