@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.
- package/dist/api/check-project-subdomain-availability.d.ts +12 -0
- package/dist/api/check-project-subdomain-availability.js +32 -0
- package/dist/api/control-plane-error.d.ts +6 -0
- package/dist/api/control-plane-error.js +8 -0
- package/dist/api/control-plane-fetch.d.ts +7 -0
- package/dist/api/control-plane-fetch.js +37 -0
- package/dist/api/control-plane.d.ts +0 -8
- package/dist/api/control-plane.js +1 -47
- package/dist/api/create-project.d.ts +18 -0
- package/dist/api/create-project.js +37 -0
- package/dist/api/list-project-workspaces.d.ts +8 -0
- package/dist/api/list-project-workspaces.js +28 -0
- package/dist/api/project-resource-type.d.ts +1 -0
- package/dist/api/project-resource-type.js +1 -0
- package/dist/auth/headless-oauth-flow.d.ts +23 -0
- package/dist/auth/headless-oauth-flow.js +69 -0
- package/dist/auth/oauth-flow.d.ts +2 -0
- package/dist/auth/oauth-flow.js +13 -8
- package/dist/auth/token-store.d.ts +4 -1
- package/dist/auth/token-store.js +14 -0
- package/dist/auth/types.d.ts +12 -0
- package/dist/cli.d.ts +10 -1
- package/dist/cli.js +39 -4
- package/dist/commands/bootstrap.js +2 -1
- package/dist/commands/deploy.d.ts +10 -0
- package/dist/commands/deploy.js +39 -11
- package/dist/commands/detect-project-resource-type.d.ts +3 -0
- package/dist/commands/detect-project-resource-type.js +28 -0
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.js +163 -78
- package/dist/commands/login.d.ts +11 -1
- package/dist/commands/login.js +66 -4
- package/dist/commands/prompt-to-create-project/format-project-subdomain.d.ts +1 -0
- package/dist/commands/prompt-to-create-project/format-project-subdomain.js +3 -0
- package/dist/commands/prompt-to-create-project/format-unavailable-subdomain-reason.d.ts +1 -0
- package/dist/commands/prompt-to-create-project/format-unavailable-subdomain-reason.js +7 -0
- package/dist/commands/prompt-to-create-project/get-default-project-name.d.ts +1 -0
- package/dist/commands/prompt-to-create-project/get-default-project-name.js +13 -0
- package/dist/commands/prompt-to-create-project/prompt-for-available-subdomain.d.ts +7 -0
- package/dist/commands/prompt-to-create-project/prompt-for-available-subdomain.js +32 -0
- package/dist/commands/prompt-to-create-project/resolve-project-region.d.ts +8 -0
- package/dist/commands/prompt-to-create-project/resolve-project-region.js +27 -0
- package/dist/commands/prompt-to-create-project/resolve-project-subdomain.d.ts +9 -0
- package/dist/commands/prompt-to-create-project/resolve-project-subdomain.js +54 -0
- package/dist/commands/prompt-to-create-project/resolve-text-input.d.ts +9 -0
- package/dist/commands/prompt-to-create-project/resolve-text-input.js +23 -0
- package/dist/commands/prompt-to-create-project/resolve-workspace-plan-key.d.ts +12 -0
- package/dist/commands/prompt-to-create-project/resolve-workspace-plan-key.js +36 -0
- package/dist/commands/prompt-to-create-project/validate-subdomain.d.ts +1 -0
- package/dist/commands/prompt-to-create-project/validate-subdomain.js +9 -0
- package/dist/commands/prompt-to-create-project.d.ts +24 -0
- package/dist/commands/prompt-to-create-project.js +69 -0
- package/dist/commands/setup-agent.d.ts +12 -0
- package/dist/commands/setup-agent.js +123 -0
- package/dist/commands/write-project-configuration.d.ts +12 -0
- package/dist/commands/write-project-configuration.js +16 -0
- package/dist/db-content-api/index.js +52 -33
- package/dist/db-content-api/utilities/data/injectGlobalType.d.ts +6 -0
- package/dist/db-content-api/utilities/data/injectGlobalType.js +11 -0
- package/dist/db-content-api/utilities/isRecord.d.ts +9 -0
- package/dist/db-content-api/utilities/isRecord.js +19 -0
- package/dist/db-content-api/utilities/joins.js +5 -1
- package/dist/db-content-api/utilities/meta/resolvesToRelationshipValue.d.ts +10 -0
- package/dist/db-content-api/utilities/meta/resolvesToRelationshipValue.js +95 -0
- package/dist/db-content-api/utilities/meta/stringifyIdsInWhere.d.ts +9 -0
- package/dist/db-content-api/utilities/meta/stringifyIdsInWhere.js +112 -0
- package/dist/db-content-api/utilities/where.d.ts +2 -6
- package/dist/db-content-api/utilities/where.js +20 -9
- package/dist/exports/views.d.ts +1 -0
- package/dist/exports/views.js +1 -0
- package/dist/imageSizeOptions.d.ts +23 -0
- package/dist/imageSizeOptions.js +26 -0
- package/dist/index.d.ts +1 -0
- package/dist/lib/write-agent-config.d.ts +12 -0
- package/dist/lib/write-agent-config.js +52 -0
- package/dist/oauth/defaults.d.ts +1 -0
- package/dist/oauth/defaults.js +1 -0
- package/dist/oauth/endpoints/getLoginEndpoint.js +7 -2
- package/dist/oauth/index.js +24 -9
- package/dist/oauth/utilities/getAdminCollectionSlug.d.ts +1 -1
- package/dist/oauth/utilities/getAuthorizeURL.d.ts +3 -0
- package/dist/oauth/utilities/getAuthorizeURL.js +8 -2
- package/dist/plugin/build-config.js +22 -9
- package/dist/plugin/cloud-limits/CloudLimitModal/index.d.ts +2 -3
- package/dist/plugin/cloud-limits/CloudLimitModal/index.js +4 -16
- package/dist/plugin/cloud-limits/CloudLimitModal/index.scss +5 -0
- package/dist/plugin/cloud-limits/CloudLimitProvider/index.d.ts +0 -3
- package/dist/plugin/cloud-limits/CloudLimitProvider/index.js +65 -124
- package/dist/plugin/cloud-limits/LimitReachedView/index.css +14 -0
- package/dist/plugin/cloud-limits/LimitReachedView/index.d.ts +4 -0
- package/dist/plugin/cloud-limits/LimitReachedView/index.js +52 -0
- package/dist/plugin/cloud-limits/SlugRegistryContext/index.d.ts +7 -2
- package/dist/plugin/cloud-limits/SlugTracker/index.d.ts +0 -8
- package/dist/plugin/cloud-limits/SlugTracker/index.js +14 -10
- package/dist/plugin/cloud-limits/routes.d.ts +2 -0
- package/dist/plugin/cloud-limits/routes.js +4 -0
- package/dist/plugin/cloud-limits/server/redirectInitialAutosaveCreate.d.ts +9 -0
- package/dist/plugin/cloud-limits/server/redirectInitialAutosaveCreate.js +28 -0
- package/dist/plugin/cloud-limits/shared.d.ts +1 -1
- package/dist/plugin/cloud-limits/shared.js +25 -0
- package/dist/plugin/cloud-limits/utilities/cloudLimitInterceptor.d.ts +2 -0
- package/dist/plugin/cloud-limits/utilities/cloudLimitInterceptor.js +134 -0
- package/dist/plugin/cloud-limits/utilities/toasts.d.ts +4 -0
- package/dist/plugin/cloud-limits/utilities/toasts.js +19 -0
- package/dist/skills/deploy-to-figma/SKILL.md +234 -0
- package/dist/skills/deploy-to-figma/references/cli-reference.md +146 -0
- package/dist/types.d.ts +9 -0
- package/dist/utils/lambda-config.js +4 -14
- package/dist/utils/messages.js +22 -3
- package/dist/utils/payload-generate.d.ts +10 -0
- package/dist/utils/payload-generate.js +59 -0
- package/dist/utils/pnpm-builds.d.ts +14 -0
- package/dist/utils/pnpm-builds.js +125 -0
- package/package.json +9 -1
- package/dist/lib/download-skill.d.ts +0 -12
- 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
|
+
}
|
package/dist/oauth/defaults.d.ts
CHANGED
|
@@ -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, }: {
|
package/dist/oauth/defaults.js
CHANGED
|
@@ -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 {
|
|
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:
|
|
155
|
+
path: getOAuthCallbackPath({
|
|
156
|
+
adminCollectionSlug: getAdminCollectionSlug(config),
|
|
157
|
+
collection,
|
|
158
|
+
endpointSlug
|
|
159
|
+
}),
|
|
155
160
|
serverURL: redirectServerURL
|
|
156
161
|
});
|
|
157
162
|
debugLogger.info({
|
package/dist/oauth/index.js
CHANGED
|
@@ -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
|
-
|
|
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'}
|
|
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
|
|
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
|
-
|
|
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:
|
|
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
|
|
421
|
+
// Inject Figma-managed identity fields only into the Payload Admin collection.
|
|
418
422
|
const collections = configWithFigmaDefaults.collections?.map((col)=>{
|
|
419
|
-
const
|
|
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 ===
|
|
447
|
+
} : col;
|
|
448
|
+
if (col.slug === adminCollectionSlug) {
|
|
436
449
|
return {
|
|
437
|
-
...
|
|
450
|
+
...withLimitView,
|
|
438
451
|
fields: [
|
|
439
452
|
...col.fields || [],
|
|
440
453
|
...figmaUserFields
|
|
441
454
|
]
|
|
442
455
|
};
|
|
443
456
|
}
|
|
444
|
-
return
|
|
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
|
-
|
|
4
|
+
collectionListURL?: string;
|
|
6
5
|
onRetry: () => void;
|
|
7
6
|
};
|
|
8
|
-
export declare function FigmaCloudLimitDocumentCountModal({
|
|
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({
|
|
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 &&
|
|
29
|
+
collectionLabel && collectionListURL ? /*#__PURE__*/ _jsxs("a", {
|
|
42
30
|
className: `${baseClass}__review-btn`,
|
|
43
|
-
|
|
44
|
-
|
|
31
|
+
href: collectionListURL,
|
|
32
|
+
onClick: ()=>closeModal(cloudLimitDocumentCountModalSlug),
|
|
45
33
|
children: [
|
|
46
34
|
/*#__PURE__*/ _jsx("span", {
|
|
47
35
|
className: `${baseClass}__review-btn-label`,
|