@payloadcms/figma 0.1.0-alpha.3 → 0.1.0-alpha.5

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 (116) hide show
  1. package/dist/api/check-project-subdomain-availability.d.ts +12 -0
  2. package/dist/api/check-project-subdomain-availability.js +32 -0
  3. package/dist/api/control-plane-error.d.ts +6 -0
  4. package/dist/api/control-plane-error.js +8 -0
  5. package/dist/api/control-plane-fetch.d.ts +7 -0
  6. package/dist/api/control-plane-fetch.js +37 -0
  7. package/dist/api/control-plane.d.ts +0 -8
  8. package/dist/api/control-plane.js +1 -47
  9. package/dist/api/create-project.d.ts +18 -0
  10. package/dist/api/create-project.js +37 -0
  11. package/dist/api/list-project-workspaces.d.ts +8 -0
  12. package/dist/api/list-project-workspaces.js +28 -0
  13. package/dist/api/project-resource-type.d.ts +1 -0
  14. package/dist/api/project-resource-type.js +1 -0
  15. package/dist/auth/headless-oauth-flow.d.ts +23 -0
  16. package/dist/auth/headless-oauth-flow.js +69 -0
  17. package/dist/auth/oauth-flow.d.ts +2 -0
  18. package/dist/auth/oauth-flow.js +13 -8
  19. package/dist/auth/token-store.d.ts +4 -1
  20. package/dist/auth/token-store.js +14 -0
  21. package/dist/auth/types.d.ts +12 -0
  22. package/dist/cli.d.ts +10 -1
  23. package/dist/cli.js +39 -4
  24. package/dist/commands/bootstrap.js +2 -1
  25. package/dist/commands/deploy.d.ts +10 -0
  26. package/dist/commands/deploy.js +39 -11
  27. package/dist/commands/detect-project-resource-type.d.ts +3 -0
  28. package/dist/commands/detect-project-resource-type.js +28 -0
  29. package/dist/commands/init.d.ts +2 -2
  30. package/dist/commands/init.js +163 -78
  31. package/dist/commands/login.d.ts +11 -1
  32. package/dist/commands/login.js +66 -4
  33. package/dist/commands/prompt-to-create-project/format-project-subdomain.d.ts +1 -0
  34. package/dist/commands/prompt-to-create-project/format-project-subdomain.js +3 -0
  35. package/dist/commands/prompt-to-create-project/format-unavailable-subdomain-reason.d.ts +1 -0
  36. package/dist/commands/prompt-to-create-project/format-unavailable-subdomain-reason.js +7 -0
  37. package/dist/commands/prompt-to-create-project/get-default-project-name.d.ts +1 -0
  38. package/dist/commands/prompt-to-create-project/get-default-project-name.js +13 -0
  39. package/dist/commands/prompt-to-create-project/prompt-for-available-subdomain.d.ts +7 -0
  40. package/dist/commands/prompt-to-create-project/prompt-for-available-subdomain.js +32 -0
  41. package/dist/commands/prompt-to-create-project/resolve-project-region.d.ts +8 -0
  42. package/dist/commands/prompt-to-create-project/resolve-project-region.js +27 -0
  43. package/dist/commands/prompt-to-create-project/resolve-project-subdomain.d.ts +9 -0
  44. package/dist/commands/prompt-to-create-project/resolve-project-subdomain.js +54 -0
  45. package/dist/commands/prompt-to-create-project/resolve-text-input.d.ts +9 -0
  46. package/dist/commands/prompt-to-create-project/resolve-text-input.js +23 -0
  47. package/dist/commands/prompt-to-create-project/resolve-workspace-plan-key.d.ts +12 -0
  48. package/dist/commands/prompt-to-create-project/resolve-workspace-plan-key.js +36 -0
  49. package/dist/commands/prompt-to-create-project/validate-subdomain.d.ts +1 -0
  50. package/dist/commands/prompt-to-create-project/validate-subdomain.js +9 -0
  51. package/dist/commands/prompt-to-create-project.d.ts +24 -0
  52. package/dist/commands/prompt-to-create-project.js +69 -0
  53. package/dist/commands/setup-agent.d.ts +12 -0
  54. package/dist/commands/setup-agent.js +123 -0
  55. package/dist/commands/write-project-configuration.d.ts +12 -0
  56. package/dist/commands/write-project-configuration.js +16 -0
  57. package/dist/db-content-api/index.js +52 -33
  58. package/dist/db-content-api/utilities/data/injectGlobalType.d.ts +6 -0
  59. package/dist/db-content-api/utilities/data/injectGlobalType.js +11 -0
  60. package/dist/db-content-api/utilities/isRecord.d.ts +9 -0
  61. package/dist/db-content-api/utilities/isRecord.js +19 -0
  62. package/dist/db-content-api/utilities/joins.js +5 -1
  63. package/dist/db-content-api/utilities/meta/resolvesToRelationshipValue.d.ts +10 -0
  64. package/dist/db-content-api/utilities/meta/resolvesToRelationshipValue.js +95 -0
  65. package/dist/db-content-api/utilities/meta/stringifyIdsInWhere.d.ts +9 -0
  66. package/dist/db-content-api/utilities/meta/stringifyIdsInWhere.js +112 -0
  67. package/dist/db-content-api/utilities/where.d.ts +2 -6
  68. package/dist/db-content-api/utilities/where.js +20 -9
  69. package/dist/exports/views.d.ts +1 -0
  70. package/dist/exports/views.js +1 -0
  71. package/dist/imageSizeOptions.d.ts +23 -0
  72. package/dist/imageSizeOptions.js +26 -0
  73. package/dist/index.d.ts +1 -0
  74. package/dist/lib/write-agent-config.d.ts +12 -0
  75. package/dist/lib/write-agent-config.js +52 -0
  76. package/dist/oauth/defaults.d.ts +1 -0
  77. package/dist/oauth/defaults.js +1 -0
  78. package/dist/oauth/endpoints/getLoginEndpoint.js +7 -2
  79. package/dist/oauth/index.js +24 -9
  80. package/dist/oauth/utilities/getAdminCollectionSlug.d.ts +1 -1
  81. package/dist/oauth/utilities/getAuthorizeURL.d.ts +3 -0
  82. package/dist/oauth/utilities/getAuthorizeURL.js +8 -2
  83. package/dist/plugin/build-config.js +22 -9
  84. package/dist/plugin/cloud-limits/CloudLimitModal/index.d.ts +2 -3
  85. package/dist/plugin/cloud-limits/CloudLimitModal/index.js +4 -16
  86. package/dist/plugin/cloud-limits/CloudLimitModal/index.scss +5 -0
  87. package/dist/plugin/cloud-limits/CloudLimitProvider/index.d.ts +0 -3
  88. package/dist/plugin/cloud-limits/CloudLimitProvider/index.js +65 -124
  89. package/dist/plugin/cloud-limits/LimitReachedView/index.css +14 -0
  90. package/dist/plugin/cloud-limits/LimitReachedView/index.d.ts +4 -0
  91. package/dist/plugin/cloud-limits/LimitReachedView/index.js +52 -0
  92. package/dist/plugin/cloud-limits/SlugRegistryContext/index.d.ts +7 -2
  93. package/dist/plugin/cloud-limits/SlugTracker/index.d.ts +0 -8
  94. package/dist/plugin/cloud-limits/SlugTracker/index.js +14 -10
  95. package/dist/plugin/cloud-limits/routes.d.ts +2 -0
  96. package/dist/plugin/cloud-limits/routes.js +4 -0
  97. package/dist/plugin/cloud-limits/server/redirectInitialAutosaveCreate.d.ts +9 -0
  98. package/dist/plugin/cloud-limits/server/redirectInitialAutosaveCreate.js +28 -0
  99. package/dist/plugin/cloud-limits/shared.d.ts +1 -1
  100. package/dist/plugin/cloud-limits/shared.js +25 -0
  101. package/dist/plugin/cloud-limits/utilities/cloudLimitInterceptor.d.ts +2 -0
  102. package/dist/plugin/cloud-limits/utilities/cloudLimitInterceptor.js +134 -0
  103. package/dist/plugin/cloud-limits/utilities/toasts.d.ts +4 -0
  104. package/dist/plugin/cloud-limits/utilities/toasts.js +19 -0
  105. package/dist/skills/deploy-to-figma/SKILL.md +234 -0
  106. package/dist/skills/deploy-to-figma/references/cli-reference.md +146 -0
  107. package/dist/types.d.ts +9 -0
  108. package/dist/utils/lambda-config.js +4 -14
  109. package/dist/utils/messages.js +22 -3
  110. package/dist/utils/payload-generate.d.ts +10 -0
  111. package/dist/utils/payload-generate.js +59 -0
  112. package/dist/utils/pnpm-builds.d.ts +14 -0
  113. package/dist/utils/pnpm-builds.js +125 -0
  114. package/package.json +9 -1
  115. package/dist/lib/download-skill.d.ts +0 -12
  116. package/dist/lib/download-skill.js +0 -77
@@ -0,0 +1,23 @@
1
+ import type { RequestInitCfPropertiesImage } from '@cloudflare/workers-types';
2
+ type CloudflareWorkerImageOptions = RequestInitCfPropertiesImage;
3
+ export declare const supportedCloudflareImageOptionKeys: readonly ["anim", "background", "blur", "border", "brightness", "compression", "contrast", "dpr", "fit", "flip", "format", "gamma", "gravity", "height", "metadata", "quality", "rotate", "saturation", "segment", "sharpen", "trim", "upscale", "width", "zoom"];
4
+ type SupportedCloudflareImageOptionKey = (typeof supportedCloudflareImageOptionKeys)[number];
5
+ type SupportedCloudflareImageOptions = Pick<CloudflareWorkerImageOptions, SupportedCloudflareImageOptionKey>;
6
+ type CloudflareImageSizeFormat = Exclude<NonNullable<SupportedCloudflareImageOptions['format']>, 'json' | 'svg'>;
7
+ type CloudflareImageSizeOptionsExceptFormat = Omit<SupportedCloudflareImageOptions, 'format'>;
8
+ /**
9
+ * Options accepted for a reusable Payload image-size preset.
10
+ *
11
+ * Presets can control the generated image, but cannot use remote overlays or
12
+ * forward authentication to an image origin. Formats that do not produce a
13
+ * supported stored image are also excluded.
14
+ */
15
+ export type CloudflareImageSizeOptions = {
16
+ format?: CloudflareImageSizeFormat;
17
+ } & CloudflareImageSizeOptionsExceptFormat;
18
+ declare module 'payload' {
19
+ interface RegisteredImageSizeOptions {
20
+ figma: CloudflareImageSizeOptions;
21
+ }
22
+ }
23
+ export {};
@@ -0,0 +1,26 @@
1
+ export const supportedCloudflareImageOptionKeys = [
2
+ 'anim',
3
+ 'background',
4
+ 'blur',
5
+ 'border',
6
+ 'brightness',
7
+ 'compression',
8
+ 'contrast',
9
+ 'dpr',
10
+ 'fit',
11
+ 'flip',
12
+ 'format',
13
+ 'gamma',
14
+ 'gravity',
15
+ 'height',
16
+ 'metadata',
17
+ 'quality',
18
+ 'rotate',
19
+ 'saturation',
20
+ 'segment',
21
+ 'sharpen',
22
+ 'trim',
23
+ 'upscale',
24
+ 'width',
25
+ 'zoom'
26
+ ];
package/dist/index.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  export { contentAPIAdapter } from './db-content-api/index.js';
2
+ export type { CloudflareImageSizeOptions } from './imageSizeOptions.js';
2
3
  export { figmaContentSystem } from './plugin/adapter.js';
3
4
  export type { FigmaContentSystemOptions } from './plugin/adapter.js';
4
5
  export { buildFigmaConfig } from './plugin/build-config.js';
@@ -0,0 +1,12 @@
1
+ export type WriteAgentConfigResult = {
2
+ agentsMd: 'appended' | 'created' | 'unchanged';
3
+ claudeMd: 'appended' | 'created' | 'unchanged';
4
+ };
5
+ /**
6
+ * Write the root AI-agent pointer files so assistants can find the Payload
7
+ * skill bundled in node_modules. Idempotent: creates when absent, appends the
8
+ * pointer when a file exists without it, and no-ops when already present.
9
+ */
10
+ export declare function writeAgentConfigFiles(args: {
11
+ projectDir: string;
12
+ }): Promise<WriteAgentConfigResult>;
@@ -0,0 +1,52 @@
1
+ import fs from 'fs/promises';
2
+ import path from 'path';
3
+ const SKILL_POINTER_PATH = 'node_modules/payload/skills/payload/SKILL.md';
4
+ const AGENTS_BLOCK = `# AI Agent
5
+
6
+ For any Payload-related work, reference the skill at
7
+ \`${SKILL_POINTER_PATH}\`.
8
+ `;
9
+ const CLAUDE_IMPORT = '@AGENTS.md';
10
+ /**
11
+ * Write the root AI-agent pointer files so assistants can find the Payload
12
+ * skill bundled in node_modules. Idempotent: creates when absent, appends the
13
+ * pointer when a file exists without it, and no-ops when already present.
14
+ */ export async function writeAgentConfigFiles(args) {
15
+ const agentsMd = await ensureFileContains({
16
+ content: AGENTS_BLOCK,
17
+ filePath: path.join(args.projectDir, 'AGENTS.md'),
18
+ marker: SKILL_POINTER_PATH
19
+ });
20
+ const claudeMd = await ensureFileContains({
21
+ content: `${CLAUDE_IMPORT}\n`,
22
+ filePath: path.join(args.projectDir, 'CLAUDE.md'),
23
+ marker: CLAUDE_IMPORT
24
+ });
25
+ return {
26
+ agentsMd,
27
+ claudeMd
28
+ };
29
+ }
30
+ async function ensureFileContains(args) {
31
+ const existing = await readFileOrNull(args.filePath);
32
+ if (existing === null) {
33
+ await fs.writeFile(args.filePath, args.content, 'utf8');
34
+ return 'created';
35
+ }
36
+ if (existing.includes(args.marker)) {
37
+ return 'unchanged';
38
+ }
39
+ const separator = existing.endsWith('\n') ? '\n' : '\n\n';
40
+ await fs.writeFile(args.filePath, `${existing}${separator}${args.content}`, 'utf8');
41
+ return 'appended';
42
+ }
43
+ async function readFileOrNull(filePath) {
44
+ try {
45
+ return await fs.readFile(filePath, 'utf8');
46
+ } catch (err) {
47
+ if (err instanceof Error && 'code' in err && err.code === 'ENOENT') {
48
+ return null;
49
+ }
50
+ throw err;
51
+ }
52
+ }
@@ -1,6 +1,7 @@
1
1
  import type { CollectionConfig, EmailField, TextField } from 'payload';
2
2
  import type { VerifyFunction } from './types.js';
3
3
  export declare const DEFAULT_USER_INFO_COOKIE_NAME = "figma-user-info";
4
+ export declare const FIGMA_OAUTH_CALLBACK_PATH = "/users/sso/login";
4
5
  export declare const defaultScope: string[];
5
6
  export declare const defaultUsernameField: TextField;
6
7
  export declare const defaultVerify: ({ collection, strategyName, userInfoCookieName, usernameField, }: {
@@ -3,6 +3,7 @@ import { v4 as uuid } from 'uuid';
3
3
  import { hasUserTokenPropsChanged } from './utilities/hasUserTokenPropsChanged.js';
4
4
  import { isDuplicateKeyError } from './utilities/isDuplicateKeyError.js';
5
5
  export const DEFAULT_USER_INFO_COOKIE_NAME = 'figma-user-info';
6
+ export const FIGMA_OAUTH_CALLBACK_PATH = '/users/sso/login';
6
7
  function getFigmaUserInfo(headers, cookieName) {
7
8
  try {
8
9
  const cookies = parseCookies(headers);
@@ -6,7 +6,8 @@ import { createDebugLogger } from '../utilities/createDebugLogger.js';
6
6
  import { establishSession } from '../utilities/establishSession.js';
7
7
  import { exchangeCodeForAccessToken } from '../utilities/exchangeCodeForAccessToken.js';
8
8
  import { extractOrigin } from '../utilities/extractOrigin.js';
9
- import { buildCsrfCookieClearHeader, OAUTH_STATE_CSRF_COOKIE_NAME } from '../utilities/getAuthorizeURL.js';
9
+ import { getAdminCollectionSlug } from '../utilities/getAdminCollectionSlug.js';
10
+ import { buildCsrfCookieClearHeader, getOAuthCallbackPath, OAUTH_STATE_CSRF_COOKIE_NAME } from '../utilities/getAuthorizeURL.js';
10
11
  import { isAbsoluteURL } from '../utilities/isAbsoluteURL.js';
11
12
  export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug, pluginOptions, strategy })=>({
12
13
  handler: async (req)=>{
@@ -151,7 +152,11 @@ export const getLoginEndpoint = ({ collection, collectionOptions, endpointSlug,
151
152
  }
152
153
  const redirectUri = formatAdminURL({
153
154
  apiRoute: config.routes?.api || '/api',
154
- path: `/${collection.slug}/${endpointSlug}/login`,
155
+ path: getOAuthCallbackPath({
156
+ adminCollectionSlug: getAdminCollectionSlug(config),
157
+ collection,
158
+ endpointSlug
159
+ }),
155
160
  serverURL: redirectServerURL
156
161
  });
157
162
  debugLogger.info({
@@ -1,5 +1,5 @@
1
1
  import { fieldAffectsData } from 'payload/shared';
2
- import { defaultVerify } from './defaults.js';
2
+ import { defaultVerify, FIGMA_OAUTH_CALLBACK_PATH } from './defaults.js';
3
3
  import { getLoginEndpoint } from './endpoints/getLoginEndpoint.js';
4
4
  import { getLogoutEndpoint } from './endpoints/getLogoutEndpoint.js';
5
5
  import { getMetaEndpoint } from './endpoints/getMetaEndpoint.js';
@@ -50,6 +50,7 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
50
50
  path: '@payloadcms/figma/client#DefaultLoginButton'
51
51
  };
52
52
  }
53
+ let callbackEndpoint;
53
54
  return {
54
55
  ...config,
55
56
  admin: {
@@ -148,6 +149,20 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
148
149
  usernameField
149
150
  })
150
151
  });
152
+ const loginEndpoint = getLoginEndpoint({
153
+ collection: existingCollection,
154
+ collectionOptions,
155
+ endpointSlug,
156
+ pluginOptions,
157
+ strategy
158
+ });
159
+ const collectionCallbackPath = `/${existingCollection.slug}/${endpointSlug}/login`;
160
+ if (existingCollection.slug === adminCollectionSlug && FIGMA_OAUTH_CALLBACK_PATH !== collectionCallbackPath) {
161
+ callbackEndpoint = {
162
+ ...loginEndpoint,
163
+ path: FIGMA_OAUTH_CALLBACK_PATH
164
+ };
165
+ }
151
166
  const authStrategy = {
152
167
  name: `${existingCollection.slug}-${strategyName}`,
153
168
  // Bind 'this' to ensure the authenticate function has the correct context
@@ -180,13 +195,7 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
180
195
  },
181
196
  endpoints: [
182
197
  ...existingCollection.endpoints || [],
183
- getLoginEndpoint({
184
- collection: existingCollection,
185
- collectionOptions,
186
- endpointSlug,
187
- pluginOptions,
188
- strategy
189
- }),
198
+ loginEndpoint,
190
199
  getMetaEndpoint({
191
200
  collection: existingCollection,
192
201
  collectionOptions,
@@ -237,6 +246,12 @@ export const oAuth2Plugin = (pluginOptions)=>(config)=>{
237
246
  ]
238
247
  }
239
248
  };
240
- })
249
+ }),
250
+ endpoints: [
251
+ ...config.endpoints ?? [],
252
+ ...callbackEndpoint ? [
253
+ callbackEndpoint
254
+ ] : []
255
+ ]
241
256
  };
242
257
  };
@@ -1,2 +1,2 @@
1
1
  import type { Config } from 'payload';
2
- export declare const getAdminCollectionSlug: (config: Config) => string;
2
+ export declare const getAdminCollectionSlug: (config: Pick<Config, "admin" | "collections">) => string;
@@ -45,6 +45,9 @@ export interface AuthorizeURLResult {
45
45
  csrfNonce: string;
46
46
  params: AuthorizeURLParams;
47
47
  }
48
+ export declare const getOAuthCallbackPath: ({ adminCollectionSlug, collection, endpointSlug, }: {
49
+ adminCollectionSlug: string;
50
+ } & Pick<Args, "collection" | "endpointSlug">) => `/${string}`;
48
51
  export declare const getAuthorizeURL: ({ collection, collectionOptions, endpointSlug, existingCsrfNonce, failedRedirect, payload, pluginOptions, redirect, serverURLOverride, strategy, }: Args) => Promise<AuthorizeURLResult>;
49
52
  /**
50
53
  * Name of the HttpOnly cookie that carries the browser-bound CSRF nonce
@@ -1,7 +1,9 @@
1
1
  import crypto from 'crypto';
2
2
  import * as QueryString from 'qs-esm';
3
3
  import { v4 as uuid } from 'uuid';
4
- import { defaultScope } from '../defaults.js';
4
+ import { defaultScope, FIGMA_OAUTH_CALLBACK_PATH } from '../defaults.js';
5
+ import { getAdminCollectionSlug } from './getAdminCollectionSlug.js';
6
+ export const getOAuthCallbackPath = ({ adminCollectionSlug, collection, endpointSlug })=>collection.slug === adminCollectionSlug ? FIGMA_OAUTH_CALLBACK_PATH : `/${collection.slug}/${endpointSlug}/login`;
5
7
  export const getAuthorizeURL = async ({ collection, collectionOptions, endpointSlug, existingCsrfNonce, failedRedirect, payload, pluginOptions, redirect, serverURLOverride, strategy })=>{
6
8
  const { redirectServerURL } = pluginOptions;
7
9
  await strategy.ensureMeta();
@@ -30,7 +32,11 @@ export const getAuthorizeURL = async ({ collection, collectionOptions, endpointS
30
32
  state.failedRedirect = failedRedirect;
31
33
  }
32
34
  const baseRedirectURL = redirectServerURL || payload.config.serverURL || state.serverURL;
33
- const loginRedirectURL = encodeURI(`${baseRedirectURL}${payload.config.routes?.api || '/api'}/${collection.slug}/${endpointSlug}/login`);
35
+ const loginRedirectURL = encodeURI(`${baseRedirectURL}${payload.config.routes?.api || '/api'}${getOAuthCallbackPath({
36
+ adminCollectionSlug: getAdminCollectionSlug(payload.config),
37
+ collection,
38
+ endpointSlug
39
+ })}`);
34
40
  const params = {
35
41
  client_id: collectionOptions.clientID,
36
42
  code_challenge,
@@ -11,6 +11,7 @@ import { scheduleExtractPlugin } from '../deploy/schedule-extract-plugin.js';
11
11
  import { health } from '../endpoints/health.js';
12
12
  import { schema } from '../endpoints/schema.js';
13
13
  import { oAuth2Plugin } from '../oauth/index.js';
14
+ import { getAdminCollectionSlug } from '../oauth/utilities/getAdminCollectionSlug.js';
14
15
  import { createStorageClient } from '../storage-content-api/client.js';
15
16
  import { contentApiStorageAdapter } from '../storage-content-api/index.js';
16
17
  import { translations as figmaTranslations } from '../translations/index.js';
@@ -19,6 +20,7 @@ import { getEnvVarSync } from '../utils/env-management.js';
19
20
  import * as log from '../utils/log.js';
20
21
  import { logMissingCliAuth } from './auth-preflight.js';
21
22
  import { logMissingContentSystemId } from './bootstrap-preflight.js';
23
+ import { LIMIT_REACHED_VIEW_KEY, LIMIT_REACHED_VIEW_PATH } from './cloud-limits/routes.js';
22
24
  import { getDevCookieNames } from './dev-cookie-names.js';
23
25
  import { createSandboxUploadFetchPlugin } from './sandbox-upload-fetch.js';
24
26
  /**
@@ -30,7 +32,7 @@ import { createSandboxUploadFetchPlugin } from './sandbox-upload-fetch.js';
30
32
  * KEEP_IN_SYNC(cloudflare/wrangler/sites-worker/src/auth.ts): FIGMA_INTERNAL_FORWARDED_HAS_AUTH_BYPASS_HEADER
31
33
  */ export const FIGMA_INTERNAL_FORWARDED_HAS_AUTH_BYPASS_HEADER = 'figma-internal-forwarded-has-auth-bypass';
32
34
  /**
33
- * Fields added to users collection for Figma profile info
35
+ * Fields added to the configured Payload Admin collection for Figma profile info
34
36
  */ const figmaUserFields = [
35
37
  {
36
38
  name: 'figmaHandle',
@@ -280,7 +282,8 @@ export async function buildFigmaConfig(config) {
280
282
  }
281
283
  // Determine database adapter based on environment
282
284
  let db;
283
- if (config.figma.useContentSystem === false) {
285
+ const usesContentSystem = config.figma.useContentSystem !== false;
286
+ if (!usesContentSystem) {
284
287
  db = config.db;
285
288
  } else if (process.env.FIGMA_CONTENT_API_ACCESS_KEY) {
286
289
  db = contentAPIAdapter({
@@ -316,6 +319,7 @@ export async function buildFigmaConfig(config) {
316
319
  });
317
320
  }
318
321
  const userJobsAccessRun = config.jobs?.access?.run;
322
+ const adminCollectionSlug = getAdminCollectionSlug(config);
319
323
  // Build complete config with Figma platform defaults
320
324
  const configWithFigmaDefaults = {
321
325
  ...config,
@@ -386,7 +390,7 @@ export async function buildFigmaConfig(config) {
386
390
  oAuth2Plugin({
387
391
  collections: [
388
392
  {
389
- slug: 'users',
393
+ slug: adminCollectionSlug,
390
394
  // Use adapter because Figma app doesn't support OIDC scopes
391
395
  authorizationURLParams: {
392
396
  response_mode: 'query',
@@ -414,9 +418,10 @@ export async function buildFigmaConfig(config) {
414
418
  })
415
419
  ]
416
420
  };
417
- // Inject figma fields into users collection
421
+ // Inject Figma-managed identity fields only into the Payload Admin collection.
418
422
  const collections = configWithFigmaDefaults.collections?.map((col)=>{
419
- const withSlugTracker = {
423
+ const views = col.admin?.components?.views;
424
+ const withLimitView = usesContentSystem ? {
420
425
  ...col,
421
426
  admin: {
422
427
  ...col.admin,
@@ -428,20 +433,28 @@ export async function buildFigmaConfig(config) {
428
433
  '@payloadcms/figma/client#FigmaCloudLimitSlugTracker',
429
434
  ...col.admin?.components?.edit?.beforeDocumentControls ?? []
430
435
  ]
436
+ },
437
+ views: {
438
+ ...views,
439
+ [LIMIT_REACHED_VIEW_KEY]: {
440
+ Component: '@payloadcms/figma/views#LimitReachedView',
441
+ exact: true,
442
+ path: LIMIT_REACHED_VIEW_PATH
443
+ }
431
444
  }
432
445
  }
433
446
  }
434
- };
435
- if (col.slug === 'users') {
447
+ } : col;
448
+ if (col.slug === adminCollectionSlug) {
436
449
  return {
437
- ...withSlugTracker,
450
+ ...withLimitView,
438
451
  fields: [
439
452
  ...col.fields || [],
440
453
  ...figmaUserFields
441
454
  ]
442
455
  };
443
456
  }
444
- return withSlugTracker;
457
+ return withLimitView;
445
458
  });
446
459
  if (collections) {
447
460
  configWithFigmaDefaults.collections = collections;
@@ -1,9 +1,8 @@
1
1
  import './index.scss';
2
2
  type Props = {
3
- adminRoute: string;
4
3
  collectionLabel?: string;
5
- collectionSlug?: string;
4
+ collectionListURL?: string;
6
5
  onRetry: () => void;
7
6
  };
8
- export declare function FigmaCloudLimitDocumentCountModal({ adminRoute, collectionLabel, collectionSlug, onRetry, }: Props): import("react").JSX.Element;
7
+ export declare function FigmaCloudLimitDocumentCountModal({ collectionLabel, collectionListURL, onRetry, }: Props): import("react").JSX.Element;
9
8
  export {};
@@ -1,25 +1,13 @@
1
1
  'use client';
2
2
  import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime";
3
3
  import { Button, DialogBody, DialogCancel, DialogFooter, DialogHeader, DialogModal, useModal, useTranslation } from '@payloadcms/ui';
4
- import { useRouter } from 'next/navigation.js';
5
- import { useCallback } from 'react';
6
4
  import { ExternalLinkIcon } from '../icons/ExternalLinkIcon.js';
7
5
  import { cloudLimitDocumentCountModalSlug } from '../shared.js';
8
6
  import './index.scss';
9
7
  const baseClass = 'figma-cloud-limit-modal';
10
- export function FigmaCloudLimitDocumentCountModal({ adminRoute, collectionLabel, collectionSlug, onRetry }) {
8
+ export function FigmaCloudLimitDocumentCountModal({ collectionLabel, collectionListURL, onRetry }) {
11
9
  const { t } = useTranslation();
12
10
  const { closeModal } = useModal();
13
- const router = useRouter();
14
- const handleReviewClick = useCallback(()=>{
15
- closeModal(cloudLimitDocumentCountModalSlug);
16
- router.push(`${adminRoute}/collections/${collectionSlug}`);
17
- }, [
18
- adminRoute,
19
- closeModal,
20
- collectionSlug,
21
- router
22
- ]);
23
11
  return /*#__PURE__*/ _jsxs(DialogModal, {
24
12
  size: "small",
25
13
  slug: cloudLimitDocumentCountModalSlug,
@@ -38,10 +26,10 @@ export function FigmaCloudLimitDocumentCountModal({ adminRoute, collectionLabel,
38
26
  children: /*#__PURE__*/ _jsxs("div", {
39
27
  className: `${baseClass}__footer`,
40
28
  children: [
41
- collectionLabel && collectionSlug ? /*#__PURE__*/ _jsxs("button", {
29
+ collectionLabel && collectionListURL ? /*#__PURE__*/ _jsxs("a", {
42
30
  className: `${baseClass}__review-btn`,
43
- onClick: handleReviewClick,
44
- type: "button",
31
+ href: collectionListURL,
32
+ onClick: ()=>closeModal(cloudLimitDocumentCountModalSlug),
45
33
  children: [
46
34
  /*#__PURE__*/ _jsx("span", {
47
35
  className: `${baseClass}__review-btn-label`,
@@ -23,6 +23,11 @@
23
23
  min-width: 0;
24
24
  padding: 0;
25
25
 
26
+ .btn__content,
27
+ .btn__label {
28
+ min-width: 0;
29
+ }
30
+
26
31
  &:hover {
27
32
  color: var(--ramp-blue-700);
28
33
  }
@@ -1,7 +1,4 @@
1
1
  import type { ReactNode } from 'react';
2
- /**
3
- * Surfaces Content API cloud-limit errors in the admin UI.
4
- */
5
2
  export declare function FigmaCloudLimitProvider({ children }: {
6
3
  children: ReactNode;
7
4
  }): import("react").JSX.Element;