@payloadcms/figma 0.0.1-alpha.3 → 0.0.1-alpha.30
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/control-plane.d.ts +22 -1
- package/dist/api/control-plane.d.ts.map +1 -1
- package/dist/api/control-plane.js +54 -15
- package/dist/api/control-plane.js.map +1 -1
- package/dist/api/figma-api.d.ts.map +1 -1
- package/dist/api/figma-api.js +42 -12
- package/dist/api/figma-api.js.map +1 -1
- package/dist/auth/callback-server.d.ts.map +1 -1
- package/dist/auth/callback-server.js +2 -1
- package/dist/auth/callback-server.js.map +1 -1
- package/dist/auth/crypto-utils.d.ts.map +1 -1
- package/dist/auth/crypto-utils.js +5 -5
- package/dist/auth/crypto-utils.js.map +1 -1
- package/dist/auth/oauth-flow.d.ts +1 -1
- package/dist/auth/oauth-flow.d.ts.map +1 -1
- package/dist/auth/oauth-flow.js +5 -5
- package/dist/auth/oauth-flow.js.map +1 -1
- package/dist/auth/project-token.d.ts.map +1 -1
- package/dist/auth/project-token.js +9 -4
- package/dist/auth/project-token.js.map +1 -1
- package/dist/auth/token-store.d.ts +10 -0
- package/dist/auth/token-store.d.ts.map +1 -1
- package/dist/auth/token-store.js +20 -0
- package/dist/auth/token-store.js.map +1 -1
- package/dist/cli.js +3 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/deploy.d.ts +4 -0
- package/dist/commands/deploy.d.ts.map +1 -1
- package/dist/commands/deploy.js +68 -126
- package/dist/commands/deploy.js.map +1 -1
- package/dist/commands/init.d.ts +1 -5
- package/dist/commands/init.d.ts.map +1 -1
- package/dist/commands/init.js +90 -85
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/list-tokens.js +2 -2
- package/dist/commands/list-tokens.js.map +1 -1
- package/dist/commands/login.d.ts +8 -1
- package/dist/commands/login.d.ts.map +1 -1
- package/dist/commands/login.js +12 -6
- package/dist/commands/login.js.map +1 -1
- package/dist/commands/logout.js +2 -2
- package/dist/commands/logout.js.map +1 -1
- package/dist/config/oauth.d.ts +5 -0
- package/dist/config/oauth.d.ts.map +1 -1
- package/dist/config/oauth.js +9 -4
- package/dist/config/oauth.js.map +1 -1
- package/dist/db-content-api/README.md +108 -0
- package/dist/db-content-api/generated/content-api-types.d.ts +3702 -0
- package/dist/db-content-api/generated/content-api-types.d.ts.map +1 -0
- package/dist/db-content-api/generated/content-api-types.js +7 -0
- package/dist/db-content-api/generated/content-api-types.js.map +1 -0
- package/dist/db-content-api/index.d.ts +18 -0
- package/dist/db-content-api/index.d.ts.map +1 -0
- package/dist/db-content-api/index.js +551 -0
- package/dist/db-content-api/index.js.map +1 -0
- package/dist/db-content-api/temp-utilities/pagination.d.ts +13 -0
- package/dist/db-content-api/temp-utilities/pagination.d.ts.map +1 -0
- package/dist/db-content-api/temp-utilities/pagination.js +45 -0
- package/dist/db-content-api/temp-utilities/pagination.js.map +1 -0
- package/dist/db-content-api/temp-utilities/slug.d.ts +2 -0
- package/dist/db-content-api/temp-utilities/slug.d.ts.map +1 -0
- package/dist/db-content-api/temp-utilities/slug.js +3 -0
- package/dist/db-content-api/temp-utilities/slug.js.map +1 -0
- package/dist/db-content-api/temp-utilities/sorting.d.ts +7 -0
- package/dist/db-content-api/temp-utilities/sorting.d.ts.map +1 -0
- package/dist/db-content-api/temp-utilities/sorting.js +71 -0
- package/dist/db-content-api/temp-utilities/sorting.js.map +1 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +4 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts.map +1 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.js +45 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.js.map +1 -0
- package/dist/db-content-api/utilities/auth.d.ts +30 -0
- package/dist/db-content-api/utilities/auth.d.ts.map +1 -0
- package/dist/db-content-api/utilities/auth.js +81 -0
- package/dist/db-content-api/utilities/auth.js.map +1 -0
- package/dist/db-content-api/utilities/data.d.ts +24 -0
- package/dist/db-content-api/utilities/data.d.ts.map +1 -0
- package/dist/db-content-api/utilities/data.js +118 -0
- package/dist/db-content-api/utilities/data.js.map +1 -0
- package/dist/db-content-api/utilities/joins.d.ts +55 -0
- package/dist/db-content-api/utilities/joins.d.ts.map +1 -0
- package/dist/db-content-api/utilities/joins.js +130 -0
- package/dist/db-content-api/utilities/joins.js.map +1 -0
- package/dist/db-content-api/utilities/where.d.ts +12 -0
- package/dist/db-content-api/utilities/where.d.ts.map +1 -0
- package/dist/db-content-api/utilities/where.js +63 -0
- package/dist/db-content-api/utilities/where.js.map +1 -0
- package/dist/endpoints/health.d.ts +3 -0
- package/dist/endpoints/health.d.ts.map +1 -0
- package/dist/endpoints/health.js +11 -0
- package/dist/endpoints/health.js.map +1 -0
- package/dist/exports/client.d.ts +3 -0
- package/dist/exports/client.d.ts.map +1 -0
- package/dist/exports/client.js +4 -0
- package/dist/exports/client.js.map +1 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -1
- package/dist/index.js.map +1 -1
- package/dist/oauth/components/LoginButton/index.d.ts.map +1 -1
- package/dist/oauth/components/LoginButton/index.js +50 -6
- package/dist/oauth/components/LoginButton/index.js.map +1 -1
- package/dist/oauth/components/LoginButton/index.scss +50 -3
- package/dist/oauth/components/LogoutButton/index.d.ts.map +1 -1
- package/dist/oauth/components/LogoutButton/index.js +0 -1
- package/dist/oauth/components/LogoutButton/index.js.map +1 -1
- package/dist/oauth/defaults.d.ts.map +1 -1
- package/dist/oauth/defaults.js +29 -5
- package/dist/oauth/defaults.js.map +1 -1
- package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +1 -1
- package/dist/oauth/endpoints/getLoginEndpoint.js +1 -1
- package/dist/oauth/endpoints/getLoginEndpoint.js.map +1 -1
- package/dist/oauth/index.d.ts.map +1 -1
- package/dist/oauth/index.js +42 -6
- package/dist/oauth/index.js.map +1 -1
- package/dist/oauth/strategy/index.d.ts.map +1 -1
- package/dist/oauth/strategy/index.js +6 -2
- package/dist/oauth/strategy/index.js.map +1 -1
- package/dist/oauth/types.d.ts +6 -6
- package/dist/oauth/types.d.ts.map +1 -1
- package/dist/oauth/types.js.map +1 -1
- package/dist/oauth/utilities/createCookieOptions.d.ts.map +1 -1
- package/dist/oauth/utilities/createCookieOptions.js.map +1 -1
- package/dist/oauth/utilities/isDuplicateKeyError.d.ts +7 -0
- package/dist/oauth/utilities/isDuplicateKeyError.d.ts.map +1 -0
- package/dist/oauth/utilities/isDuplicateKeyError.js +14 -0
- package/dist/oauth/utilities/isDuplicateKeyError.js.map +1 -0
- package/dist/oauth/utilities/refreshTokens.d.ts.map +1 -1
- package/dist/oauth/utilities/refreshTokens.js +1 -1
- package/dist/oauth/utilities/refreshTokens.js.map +1 -1
- package/dist/plugin/build-config.d.ts +21 -4
- package/dist/plugin/build-config.d.ts.map +1 -1
- package/dist/plugin/build-config.js +89 -9
- package/dist/plugin/build-config.js.map +1 -1
- package/dist/storage-content-api/api-types.d.ts +161 -0
- package/dist/storage-content-api/api-types.d.ts.map +1 -0
- package/dist/storage-content-api/api-types.js +6 -0
- package/dist/storage-content-api/api-types.js.map +1 -0
- package/dist/storage-content-api/client.d.ts +6 -0
- package/dist/storage-content-api/client.d.ts.map +1 -0
- package/dist/storage-content-api/client.js +36 -0
- package/dist/storage-content-api/client.js.map +1 -0
- package/dist/storage-content-api/generateURL.d.ts +7 -0
- package/dist/storage-content-api/generateURL.d.ts.map +1 -0
- package/dist/storage-content-api/generateURL.js +7 -0
- package/dist/storage-content-api/generateURL.js.map +1 -0
- package/dist/storage-content-api/handleDelete.d.ts +8 -0
- package/dist/storage-content-api/handleDelete.d.ts.map +1 -0
- package/dist/storage-content-api/handleDelete.js +15 -0
- package/dist/storage-content-api/handleDelete.js.map +1 -0
- package/dist/storage-content-api/handleUpload.d.ts +11 -0
- package/dist/storage-content-api/handleUpload.d.ts.map +1 -0
- package/dist/storage-content-api/handleUpload.js +126 -0
- package/dist/storage-content-api/handleUpload.js.map +1 -0
- package/dist/storage-content-api/index.d.ts +5 -0
- package/dist/storage-content-api/index.d.ts.map +1 -0
- package/dist/storage-content-api/index.js +31 -0
- package/dist/storage-content-api/index.js.map +1 -0
- package/dist/storage-content-api/staticHandler.d.ts +10 -0
- package/dist/storage-content-api/staticHandler.d.ts.map +1 -0
- package/dist/storage-content-api/staticHandler.js +35 -0
- package/dist/storage-content-api/staticHandler.js.map +1 -0
- package/dist/storage-content-api/types.d.ts +10 -0
- package/dist/storage-content-api/types.d.ts.map +1 -0
- package/dist/storage-content-api/types.js +3 -0
- package/dist/storage-content-api/types.js.map +1 -0
- package/dist/templates/README.md +19 -0
- package/dist/utils/env-management.d.ts +9 -8
- package/dist/utils/env-management.d.ts.map +1 -1
- package/dist/utils/env-management.js +73 -74
- package/dist/utils/env-management.js.map +1 -1
- package/dist/utils/formatter.d.ts.map +1 -1
- package/dist/utils/formatter.js +1 -7
- package/dist/utils/formatter.js.map +1 -1
- package/dist/utils/lambda-config.d.ts.map +1 -1
- package/dist/utils/lambda-config.js +1 -0
- package/dist/utils/lambda-config.js.map +1 -1
- package/dist/utils/messages.d.ts.map +1 -1
- package/dist/utils/messages.js +5 -7
- package/dist/utils/messages.js.map +1 -1
- package/dist/utils/payload-config-ast.d.ts +22 -3
- package/dist/utils/payload-config-ast.d.ts.map +1 -1
- package/dist/utils/payload-config-ast.js +89 -31
- package/dist/utils/payload-config-ast.js.map +1 -1
- package/dist/utils/payload-config-finder.d.ts +2 -2
- package/dist/utils/payload-config-finder.d.ts.map +1 -1
- package/dist/utils/payload-config-finder.js +48 -9
- package/dist/utils/payload-config-finder.js.map +1 -1
- package/dist/utils/payload-config-modifier.d.ts.map +1 -1
- package/dist/utils/payload-config-modifier.js +33 -4
- package/dist/utils/payload-config-modifier.js.map +1 -1
- package/dist/utils/payload-package-check.d.ts +5 -0
- package/dist/utils/payload-package-check.d.ts.map +1 -1
- package/dist/utils/payload-package-check.js +48 -4
- package/dist/utils/payload-package-check.js.map +1 -1
- package/dist/utils/project.d.ts.map +1 -1
- package/dist/utils/project.js +8 -6
- package/dist/utils/project.js.map +1 -1
- package/dist/utils/s3-upload.d.ts +0 -1
- package/dist/utils/s3-upload.d.ts.map +1 -1
- package/dist/utils/s3-upload.js +10 -3
- package/dist/utils/s3-upload.js.map +1 -1
- package/dist/utils/token-display.d.ts.map +1 -1
- package/dist/utils/token-display.js +11 -5
- package/dist/utils/token-display.js.map +1 -1
- package/dist/utils/typescript-validator.d.ts.map +1 -1
- package/dist/utils/typescript-validator.js +1 -6
- package/dist/utils/typescript-validator.js.map +1 -1
- package/package.json +24 -7
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../src/oauth/utilities/refreshTokens.ts"],"sourcesContent":["import type jwt from 'jsonwebtoken'\nimport type { Payload } from 'payload'\n\nimport { generateCookie } from 'payload'\n\nimport type { Strategy } from '../strategy/index.js'\n\nimport { getProjectToken } from '../../api/figma-api.js'\nimport { validateProjectToken } from '../../auth/jwt-validator.js'\nimport { getEnvironment } from '../../constants.js'\nimport { createCookieOptions } from './createCookieOptions.js'\nimport { createDebugLogger } from './createDebugLogger.js'\nimport { getCookieExpiration } from './getCookieExpiration.js'\
|
|
1
|
+
{"version":3,"sources":["../../../src/oauth/utilities/refreshTokens.ts"],"sourcesContent":["import type jwt from 'jsonwebtoken'\nimport type { Payload } from 'payload'\n\nimport { generateCookie } from 'payload'\n\nimport type { Strategy } from '../strategy/index.js'\n\nimport { getProjectToken } from '../../api/figma-api.js'\nimport { validateProjectToken } from '../../auth/jwt-validator.js'\nimport { getEnvironment } from '../../constants.js'\nimport { createCookieOptions } from './createCookieOptions.js'\nimport { createDebugLogger } from './createDebugLogger.js'\nimport { getCookieExpiration } from './getCookieExpiration.js'\n\ninterface Args {\n payload: Payload\n refreshToken: string\n strategy: Strategy\n}\n\ntype Result =\n | {\n decodedOauthToken: jwt.JwtPayload\n headers: Headers\n token: string\n }\n | false\n\nexport const refreshTokens = async ({ payload, refreshToken, strategy }: Args): Promise<Result> => {\n const debugLogger = createDebugLogger(payload, strategy.debug)\n\n debugLogger.info({\n msg: 'Refreshing tokens',\n })\n\n const headers = new Headers()\n\n // At this point, access token is expired\n // but refresh token is still valid\n // so we will refresh both tokens\n\n try {\n // Get another project token\n const { expiresAt, token } = await getProjectToken(\n refreshToken,\n payload.config.custom.figma.contentSystemId,\n )\n\n debugLogger.info({\n expiresAt,\n msg: 'Received new tokens from Figma API',\n token,\n })\n\n // On error, no user\n if (!token) {\n debugLogger.error({\n msg: 'Error refreshing tokens',\n })\n return false\n }\n\n if (token) {\n debugLogger.info({\n msg: 'Successfully refreshed project token',\n token,\n })\n\n const expires_in = new Date(expiresAt)\n\n const cookieOptions = createCookieOptions({\n collection: strategy.collection,\n headers,\n pluginOptions: strategy.pluginOptions,\n })\n\n const tokenCookie = generateCookie({\n ...cookieOptions,\n name: strategy.cookieName,\n expires: getCookieExpiration(expires_in),\n returnCookieAsObject: false,\n value: token,\n }) as string\n\n headers.append('Set-Cookie', tokenCookie)\n\n const decodedOauthToken = await validateProjectToken(token, getEnvironment())\n\n return { decodedOauthToken, headers, token }\n }\n } catch (error) {\n debugLogger.error({\n err: error,\n msg: 'Error refreshing tokens',\n })\n }\n\n return false\n}\n"],"names":["generateCookie","getProjectToken","validateProjectToken","getEnvironment","createCookieOptions","createDebugLogger","getCookieExpiration","refreshTokens","payload","refreshToken","strategy","debugLogger","debug","info","msg","headers","Headers","expiresAt","token","config","custom","figma","contentSystemId","error","expires_in","Date","cookieOptions","collection","pluginOptions","tokenCookie","name","cookieName","expires","returnCookieAsObject","value","append","decodedOauthToken","err"],"mappings":"AAGA,SAASA,cAAc,QAAQ,UAAS;AAIxC,SAASC,eAAe,QAAQ,yBAAwB;AACxD,SAASC,oBAAoB,QAAQ,8BAA6B;AAClE,SAASC,cAAc,QAAQ,qBAAoB;AACnD,SAASC,mBAAmB,QAAQ,2BAA0B;AAC9D,SAASC,iBAAiB,QAAQ,yBAAwB;AAC1D,SAASC,mBAAmB,QAAQ,2BAA0B;AAgB9D,OAAO,MAAMC,gBAAgB,OAAO,EAAEC,OAAO,EAAEC,YAAY,EAAEC,QAAQ,EAAQ;IAC3E,MAAMC,cAAcN,kBAAkBG,SAASE,SAASE,KAAK;IAE7DD,YAAYE,IAAI,CAAC;QACfC,KAAK;IACP;IAEA,MAAMC,UAAU,IAAIC;IAEpB,yCAAyC;IACzC,mCAAmC;IACnC,iCAAiC;IAEjC,IAAI;QACF,4BAA4B;QAC5B,MAAM,EAAEC,SAAS,EAAEC,KAAK,EAAE,GAAG,MAAMjB,gBACjCQ,cACAD,QAAQW,MAAM,CAACC,MAAM,CAACC,KAAK,CAACC,eAAe;QAG7CX,YAAYE,IAAI,CAAC;YACfI;YACAH,KAAK;YACLI;QACF;QAEA,oBAAoB;QACpB,IAAI,CAACA,OAAO;YACVP,YAAYY,KAAK,CAAC;gBAChBT,KAAK;YACP;YACA,OAAO;QACT;QAEA,IAAII,OAAO;YACTP,YAAYE,IAAI,CAAC;gBACfC,KAAK;gBACLI;YACF;YAEA,MAAMM,aAAa,IAAIC,KAAKR;YAE5B,MAAMS,gBAAgBtB,oBAAoB;gBACxCuB,YAAYjB,SAASiB,UAAU;gBAC/BZ;gBACAa,eAAelB,SAASkB,aAAa;YACvC;YAEA,MAAMC,cAAc7B,eAAe;gBACjC,GAAG0B,aAAa;gBAChBI,MAAMpB,SAASqB,UAAU;gBACzBC,SAAS1B,oBAAoBkB;gBAC7BS,sBAAsB;gBACtBC,OAAOhB;YACT;YAEAH,QAAQoB,MAAM,CAAC,cAAcN;YAE7B,MAAMO,oBAAoB,MAAMlC,qBAAqBgB,OAAOf;YAE5D,OAAO;gBAAEiC;gBAAmBrB;gBAASG;YAAM;QAC7C;IACF,EAAE,OAAOK,OAAO;QACdZ,YAAYY,KAAK,CAAC;YAChBc,KAAKd;YACLT,KAAK;QACP;IACF;IAEA,OAAO;AACT,EAAC"}
|
|
@@ -10,25 +10,42 @@ import type { Config, SanitizedConfig } from 'payload';
|
|
|
10
10
|
* @example
|
|
11
11
|
* // Minimal config
|
|
12
12
|
* const config: FigmaConfig = {
|
|
13
|
+
* figma: {
|
|
14
|
+
* contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!
|
|
15
|
+
* },
|
|
13
16
|
* collections: [...]
|
|
14
17
|
* }
|
|
15
18
|
*
|
|
16
19
|
* @example
|
|
17
20
|
* // With custom editor
|
|
18
21
|
* const config: FigmaConfig = {
|
|
22
|
+
* figma: {
|
|
23
|
+
* contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!
|
|
24
|
+
* },
|
|
19
25
|
* collections: [...],
|
|
20
26
|
* editor: lexicalEditor({ features: [...] })
|
|
21
27
|
* }
|
|
28
|
+
*
|
|
29
|
+
* @example
|
|
30
|
+
* // Disable Content System (use custom db)
|
|
31
|
+
* const config: FigmaConfig = {
|
|
32
|
+
* figma: {
|
|
33
|
+
* contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!,
|
|
34
|
+
* useContentSystem: false
|
|
35
|
+
* },
|
|
36
|
+
* db: mongooseAdapter({ url: process.env.DATABASE_URI }),
|
|
37
|
+
* collections: [...]
|
|
38
|
+
* }
|
|
22
39
|
*/
|
|
23
40
|
export type FigmaConfig = {
|
|
24
41
|
editor?: Config['editor'];
|
|
25
42
|
} & {
|
|
26
43
|
figma: {
|
|
27
|
-
|
|
28
|
-
|
|
44
|
+
contentSystemId: string;
|
|
45
|
+
storage?: boolean;
|
|
29
46
|
useContentSystem?: boolean;
|
|
30
47
|
};
|
|
31
|
-
} & Omit<Config, 'editor' | 'secret'> & Partial<Pick<Config, 'db'>>;
|
|
48
|
+
} & Omit<Config, 'db' | 'editor' | 'secret'> & Partial<Pick<Config, 'db'>>;
|
|
32
49
|
/**
|
|
33
50
|
* Figma platform wrapper for Payload's buildConfig.
|
|
34
51
|
* Automatically injects:
|
|
@@ -39,5 +56,5 @@ export type FigmaConfig = {
|
|
|
39
56
|
* @param config - Payload configuration (db and secret omitted, editor optional)
|
|
40
57
|
* @returns Promise<SanitizedConfig> - Built Payload configuration
|
|
41
58
|
*/
|
|
42
|
-
export declare function
|
|
59
|
+
export declare function buildFigmaConfig(config: FigmaConfig): Promise<SanitizedConfig>;
|
|
43
60
|
//# sourceMappingURL=build-config.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"build-config.d.ts","sourceRoot":"","sources":["../../src/plugin/build-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;
|
|
1
|
+
{"version":3,"file":"build-config.d.ts","sourceRoot":"","sources":["../../src/plugin/build-config.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,MAAM,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AActD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAqCG;AACH,MAAM,MAAM,WAAW,GAAG;IACxB,MAAM,CAAC,EAAE,MAAM,CAAC,QAAQ,CAAC,CAAA;CAC1B,GAAG;IACF,KAAK,EAAE;QACL,eAAe,EAAE,MAAM,CAAA;QACvB,OAAO,CAAC,EAAE,OAAO,CAAA;QACjB,gBAAgB,CAAC,EAAE,OAAO,CAAA;KAC3B,CAAA;CACF,GAAG,IAAI,CAAC,MAAM,EAAE,IAAI,GAAG,QAAQ,GAAG,QAAQ,CAAC,GAC1C,OAAO,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC,CAAA;AAE7B;;;;;;;;;GASG;AACH,wBAAsB,gBAAgB,CAAC,MAAM,EAAE,WAAW,GAAG,OAAO,CAAC,eAAe,CAAC,CA+GpF"}
|
|
@@ -1,7 +1,11 @@
|
|
|
1
|
+
import { cloudStoragePlugin } from '@payloadcms/plugin-cloud-storage';
|
|
1
2
|
import { lexicalEditor } from '@payloadcms/richtext-lexical';
|
|
2
3
|
import { buildConfig as payloadBuildConfig } from 'payload';
|
|
4
|
+
import { getTokenStore } from '../auth/token-store.js';
|
|
5
|
+
import { contentAPIAdapter } from '../db-content-api/index.js';
|
|
6
|
+
import { health } from '../endpoints/health.js';
|
|
3
7
|
import { oAuth2Plugin } from '../oauth/index.js';
|
|
4
|
-
import {
|
|
8
|
+
import { contentApiStorageAdapter } from '../storage-content-api/index.js';
|
|
5
9
|
/**
|
|
6
10
|
* Figma platform wrapper for Payload's buildConfig.
|
|
7
11
|
* Automatically injects:
|
|
@@ -11,20 +15,97 @@ import { figmaContentSystem } from './adapter.js';
|
|
|
11
15
|
*
|
|
12
16
|
* @param config - Payload configuration (db and secret omitted, editor optional)
|
|
13
17
|
* @returns Promise<SanitizedConfig> - Built Payload configuration
|
|
14
|
-
*/ export async function
|
|
18
|
+
*/ export async function buildFigmaConfig(config) {
|
|
19
|
+
// Validate required environment variable
|
|
20
|
+
if (!config.figma.contentSystemId) {
|
|
21
|
+
throw new Error('FIGMA_CONTENT_SYSTEM_ID is required. ' + 'Ensure your .env file contains: FIGMA_CONTENT_SYSTEM_ID=your-content-system-id');
|
|
22
|
+
}
|
|
23
|
+
const DEFAULT_CONTENT_API_URL = 'https://us-east-1.cms-tenants-001-staging.figmacontentstaging.com';
|
|
24
|
+
const url = process.env.FIGMA_CONTENT_API_URL || DEFAULT_CONTENT_API_URL;
|
|
25
|
+
const { contentSystemId } = config.figma;
|
|
26
|
+
// Determine database adapter based on environment
|
|
27
|
+
let db;
|
|
28
|
+
if (config.figma.useContentSystem === false) {
|
|
29
|
+
db = config.db;
|
|
30
|
+
} else if (process.env.FIGMA_CONTENT_API_ACCESS_KEY) {
|
|
31
|
+
db = contentAPIAdapter({
|
|
32
|
+
auth: {
|
|
33
|
+
apiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY,
|
|
34
|
+
mode: 'apiKey'
|
|
35
|
+
},
|
|
36
|
+
contentSystemId,
|
|
37
|
+
url
|
|
38
|
+
});
|
|
39
|
+
} else if (process.env.FIGMA_DEV_JWT === 'true') {
|
|
40
|
+
db = contentAPIAdapter({
|
|
41
|
+
auth: {
|
|
42
|
+
mode: 'devJwt'
|
|
43
|
+
},
|
|
44
|
+
contentSystemId,
|
|
45
|
+
url
|
|
46
|
+
});
|
|
47
|
+
} else {
|
|
48
|
+
db = contentAPIAdapter({
|
|
49
|
+
auth: {
|
|
50
|
+
mode: 'tokenStore',
|
|
51
|
+
tokenStore: getTokenStore()
|
|
52
|
+
},
|
|
53
|
+
contentSystemId,
|
|
54
|
+
url
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
// Build storage plugin if there are upload collections and storage is not disabled
|
|
58
|
+
const uploadCollections = (config.collections || []).filter((c)=>c.upload);
|
|
59
|
+
let storagePlugin;
|
|
60
|
+
if (uploadCollections.length > 0 && config.figma.storage !== false) {
|
|
61
|
+
const storageConfig = process.env.FIGMA_CONTENT_API_ACCESS_KEY ? {
|
|
62
|
+
baseUrl: url,
|
|
63
|
+
contentApiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY
|
|
64
|
+
} : process.env.FIGMA_DEV_JWT === 'true' ? {
|
|
65
|
+
auth: {
|
|
66
|
+
mode: 'devJwt'
|
|
67
|
+
},
|
|
68
|
+
baseUrl: url,
|
|
69
|
+
contentSystemId
|
|
70
|
+
} : {
|
|
71
|
+
auth: {
|
|
72
|
+
mode: 'tokenStore',
|
|
73
|
+
tokenStore: getTokenStore()
|
|
74
|
+
},
|
|
75
|
+
baseUrl: url,
|
|
76
|
+
contentSystemId
|
|
77
|
+
};
|
|
78
|
+
const adapter = contentApiStorageAdapter(storageConfig);
|
|
79
|
+
const collectionsMap = uploadCollections.reduce((acc, c)=>{
|
|
80
|
+
acc[c.slug] = {
|
|
81
|
+
adapter,
|
|
82
|
+
disableLocalStorage: true
|
|
83
|
+
};
|
|
84
|
+
return acc;
|
|
85
|
+
}, {});
|
|
86
|
+
storagePlugin = cloudStoragePlugin({
|
|
87
|
+
collections: collectionsMap
|
|
88
|
+
});
|
|
89
|
+
}
|
|
15
90
|
// Build complete config with Figma platform defaults
|
|
16
91
|
const configWithFigmaDefaults = {
|
|
17
92
|
...config,
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
} : {
|
|
21
|
-
db: config.db
|
|
93
|
+
custom: {
|
|
94
|
+
figma: config.figma || {}
|
|
22
95
|
},
|
|
96
|
+
db,
|
|
23
97
|
editor: config.editor ?? lexicalEditor(),
|
|
98
|
+
endpoints: [
|
|
99
|
+
...config.endpoints ?? [],
|
|
100
|
+
health
|
|
101
|
+
],
|
|
24
102
|
secret: 'MY_SECRET',
|
|
25
103
|
// Add oauth to plugins if not already present
|
|
26
104
|
plugins: [
|
|
27
105
|
...config.plugins ?? [],
|
|
106
|
+
...storagePlugin ? [
|
|
107
|
+
storagePlugin
|
|
108
|
+
] : [],
|
|
28
109
|
oAuth2Plugin({
|
|
29
110
|
collections: [
|
|
30
111
|
{
|
|
@@ -44,9 +125,8 @@ import { figmaContentSystem } from './adapter.js';
|
|
|
44
125
|
usernameField: 'email'
|
|
45
126
|
}
|
|
46
127
|
],
|
|
47
|
-
debug:
|
|
48
|
-
disabled: false
|
|
49
|
-
redirectServerURL: 'http://localhost:3000'
|
|
128
|
+
debug: !!process.env.DEBUG,
|
|
129
|
+
disabled: false
|
|
50
130
|
})
|
|
51
131
|
]
|
|
52
132
|
};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/plugin/build-config.ts"],"sourcesContent":["import type { Config, SanitizedConfig } from 'payload'\n\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\nimport { buildConfig as payloadBuildConfig } from 'payload'\n\nimport { oAuth2Plugin } from '../oauth/index.js'\nimport {
|
|
1
|
+
{"version":3,"sources":["../../src/plugin/build-config.ts"],"sourcesContent":["import type { Config, SanitizedConfig } from 'payload'\n\nimport { cloudStoragePlugin } from '@payloadcms/plugin-cloud-storage'\nimport { lexicalEditor } from '@payloadcms/richtext-lexical'\nimport { buildConfig as payloadBuildConfig } from 'payload'\n\nimport type { StorageClientConfig } from '../storage-content-api/index.js'\n\nimport { getTokenStore } from '../auth/token-store.js'\nimport { contentAPIAdapter } from '../db-content-api/index.js'\nimport { health } from '../endpoints/health.js'\nimport { oAuth2Plugin } from '../oauth/index.js'\nimport { contentApiStorageAdapter } from '../storage-content-api/index.js'\n\n/**\n * Configuration type for Payload projects on the Figma platform.\n *\n * Differences from standard Payload Config:\n * - `db`: Omitted (auto-injected by Figma platform)\n * - `secret`: Omitted (auto-injected by Figma platform)\n * - `editor`: Optional (defaults to lexicalEditor() if not provided)\n *\n * @example\n * // Minimal config\n * const config: FigmaConfig = {\n * figma: {\n * contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!\n * },\n * collections: [...]\n * }\n *\n * @example\n * // With custom editor\n * const config: FigmaConfig = {\n * figma: {\n * contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!\n * },\n * collections: [...],\n * editor: lexicalEditor({ features: [...] })\n * }\n *\n * @example\n * // Disable Content System (use custom db)\n * const config: FigmaConfig = {\n * figma: {\n * contentSystemId: process.env.FIGMA_CONTENT_SYSTEM_ID!,\n * useContentSystem: false\n * },\n * db: mongooseAdapter({ url: process.env.DATABASE_URI }),\n * collections: [...]\n * }\n */\nexport type FigmaConfig = {\n editor?: Config['editor']\n} & {\n figma: {\n contentSystemId: string\n storage?: boolean\n useContentSystem?: boolean\n }\n} & Omit<Config, 'db' | 'editor' | 'secret'> &\n Partial<Pick<Config, 'db'>>\n\n/**\n * Figma platform wrapper for Payload's buildConfig.\n * Automatically injects:\n * - Figma database adapter\n * - Secret (platform-provided)\n * - Default lexicalEditor (if no custom editor specified)\n *\n * @param config - Payload configuration (db and secret omitted, editor optional)\n * @returns Promise<SanitizedConfig> - Built Payload configuration\n */\nexport async function buildFigmaConfig(config: FigmaConfig): Promise<SanitizedConfig> {\n // Validate required environment variable\n if (!config.figma.contentSystemId) {\n throw new Error(\n 'FIGMA_CONTENT_SYSTEM_ID is required. ' +\n 'Ensure your .env file contains: FIGMA_CONTENT_SYSTEM_ID=your-content-system-id',\n )\n }\n\n const DEFAULT_CONTENT_API_URL =\n 'https://us-east-1.cms-tenants-001-staging.figmacontentstaging.com'\n\n const url = process.env.FIGMA_CONTENT_API_URL || DEFAULT_CONTENT_API_URL\n const { contentSystemId } = config.figma\n\n // Determine database adapter based on environment\n let db: Config['db']\n\n if (config.figma.useContentSystem === false) {\n db = config.db!\n } else if (process.env.FIGMA_CONTENT_API_ACCESS_KEY) {\n db = contentAPIAdapter({\n auth: { apiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY, mode: 'apiKey' },\n contentSystemId,\n url,\n })\n } else if (process.env.FIGMA_DEV_JWT === 'true') {\n db = contentAPIAdapter({\n auth: { mode: 'devJwt' },\n contentSystemId,\n url,\n })\n } else {\n db = contentAPIAdapter({\n auth: { mode: 'tokenStore', tokenStore: getTokenStore() },\n contentSystemId,\n url,\n })\n }\n\n // Build storage plugin if there are upload collections and storage is not disabled\n const uploadCollections = (config.collections || []).filter((c) => c.upload)\n let storagePlugin: ReturnType<typeof cloudStoragePlugin> | undefined\n\n if (uploadCollections.length > 0 && config.figma.storage !== false) {\n const storageConfig: StorageClientConfig = process.env.FIGMA_CONTENT_API_ACCESS_KEY\n ? { baseUrl: url, contentApiKey: process.env.FIGMA_CONTENT_API_ACCESS_KEY }\n : process.env.FIGMA_DEV_JWT === 'true'\n ? {\n auth: { mode: 'devJwt' },\n baseUrl: url,\n contentSystemId,\n }\n : {\n auth: { mode: 'tokenStore', tokenStore: getTokenStore() },\n baseUrl: url,\n contentSystemId,\n }\n\n const adapter = contentApiStorageAdapter(storageConfig)\n\n const collectionsMap = uploadCollections.reduce(\n (acc, c) => {\n acc[c.slug] = { adapter, disableLocalStorage: true }\n return acc\n },\n {} as Record<string, { adapter: typeof adapter; disableLocalStorage: boolean }>,\n )\n\n storagePlugin = cloudStoragePlugin({ collections: collectionsMap })\n }\n\n // Build complete config with Figma platform defaults\n const configWithFigmaDefaults: Config = {\n ...config,\n custom: {\n figma: config.figma || {},\n },\n db,\n editor: config.editor ?? lexicalEditor(),\n endpoints: [...(config.endpoints ?? []), health],\n secret: 'MY_SECRET',\n // Add oauth to plugins if not already present\n plugins: [\n ...(config.plugins ?? []),\n ...(storagePlugin ? [storagePlugin] : []),\n oAuth2Plugin({\n collections: [\n {\n slug: 'users',\n // Use adapter because Figma app doesn't support OIDC scopes\n authorizationURLParams: {\n response_mode: 'query',\n response_type: 'code',\n },\n clientID: process.env.FIGMA_OAUTH_CLIENT_ID!,\n clientSecret: process.env.FIGMA_OAUTH_CLIENT_SECRET,\n identityMetadata: 'https://staging.figma.com/.well-known/openid-configuration',\n scope: ['current_user:read'],\n token: 'id_token', // Adapter creates JWT id_token from Figma user info\n usernameField: 'email',\n },\n ],\n debug: !!process.env.DEBUG,\n disabled: false,\n }),\n ],\n }\n\n // Delegate to Payload's buildConfig\n return await payloadBuildConfig(configWithFigmaDefaults)\n}\n"],"names":["cloudStoragePlugin","lexicalEditor","buildConfig","payloadBuildConfig","getTokenStore","contentAPIAdapter","health","oAuth2Plugin","contentApiStorageAdapter","buildFigmaConfig","config","figma","contentSystemId","Error","DEFAULT_CONTENT_API_URL","url","process","env","FIGMA_CONTENT_API_URL","db","useContentSystem","FIGMA_CONTENT_API_ACCESS_KEY","auth","apiKey","mode","FIGMA_DEV_JWT","tokenStore","uploadCollections","collections","filter","c","upload","storagePlugin","length","storage","storageConfig","baseUrl","contentApiKey","adapter","collectionsMap","reduce","acc","slug","disableLocalStorage","configWithFigmaDefaults","custom","editor","endpoints","secret","plugins","authorizationURLParams","response_mode","response_type","clientID","FIGMA_OAUTH_CLIENT_ID","clientSecret","FIGMA_OAUTH_CLIENT_SECRET","identityMetadata","scope","token","usernameField","debug","DEBUG","disabled"],"mappings":"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"}
|
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Upload API types extracted from Content API OpenAPI spec.
|
|
3
|
+
* These are kept separate to avoid breaking changes when the main spec is regenerated.
|
|
4
|
+
*/
|
|
5
|
+
export type UploadPaths = {
|
|
6
|
+
'/api/v0/uploads/{filename}': {
|
|
7
|
+
delete: {
|
|
8
|
+
parameters: {
|
|
9
|
+
path: {
|
|
10
|
+
filename: string;
|
|
11
|
+
};
|
|
12
|
+
};
|
|
13
|
+
responses: {
|
|
14
|
+
200: {
|
|
15
|
+
content: {
|
|
16
|
+
'application/json': {
|
|
17
|
+
success: true;
|
|
18
|
+
};
|
|
19
|
+
};
|
|
20
|
+
};
|
|
21
|
+
};
|
|
22
|
+
};
|
|
23
|
+
};
|
|
24
|
+
'/api/v0/uploads/download/sign': {
|
|
25
|
+
post: {
|
|
26
|
+
requestBody: {
|
|
27
|
+
content: {
|
|
28
|
+
'application/json': {
|
|
29
|
+
expiresIn: number;
|
|
30
|
+
filename: string;
|
|
31
|
+
};
|
|
32
|
+
};
|
|
33
|
+
};
|
|
34
|
+
responses: {
|
|
35
|
+
200: {
|
|
36
|
+
content: {
|
|
37
|
+
'application/json': {
|
|
38
|
+
url: string;
|
|
39
|
+
};
|
|
40
|
+
};
|
|
41
|
+
};
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
};
|
|
45
|
+
'/api/v0/uploads/multipart/abort': {
|
|
46
|
+
post: {
|
|
47
|
+
requestBody: {
|
|
48
|
+
content: {
|
|
49
|
+
'application/json': {
|
|
50
|
+
filename: string;
|
|
51
|
+
uploadId: string;
|
|
52
|
+
};
|
|
53
|
+
};
|
|
54
|
+
};
|
|
55
|
+
responses: {
|
|
56
|
+
200: {
|
|
57
|
+
content: {
|
|
58
|
+
'application/json': {
|
|
59
|
+
success: true;
|
|
60
|
+
};
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
};
|
|
64
|
+
};
|
|
65
|
+
};
|
|
66
|
+
'/api/v0/uploads/multipart/complete': {
|
|
67
|
+
post: {
|
|
68
|
+
requestBody: {
|
|
69
|
+
content: {
|
|
70
|
+
'application/json': {
|
|
71
|
+
filename: string;
|
|
72
|
+
parts: Array<{
|
|
73
|
+
ETag: string;
|
|
74
|
+
PartNumber: number;
|
|
75
|
+
}>;
|
|
76
|
+
uploadId: string;
|
|
77
|
+
};
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
responses: {
|
|
81
|
+
200: {
|
|
82
|
+
content: {
|
|
83
|
+
'application/json': {
|
|
84
|
+
success: true;
|
|
85
|
+
};
|
|
86
|
+
};
|
|
87
|
+
};
|
|
88
|
+
};
|
|
89
|
+
};
|
|
90
|
+
};
|
|
91
|
+
'/api/v0/uploads/multipart/initiate': {
|
|
92
|
+
post: {
|
|
93
|
+
requestBody: {
|
|
94
|
+
content: {
|
|
95
|
+
'application/json': {
|
|
96
|
+
contentType: string;
|
|
97
|
+
filename: string;
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
responses: {
|
|
102
|
+
200: {
|
|
103
|
+
content: {
|
|
104
|
+
'application/json': {
|
|
105
|
+
uploadId: string;
|
|
106
|
+
};
|
|
107
|
+
};
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
};
|
|
112
|
+
'/api/v0/uploads/multipart/parts': {
|
|
113
|
+
post: {
|
|
114
|
+
requestBody: {
|
|
115
|
+
content: {
|
|
116
|
+
'application/json': {
|
|
117
|
+
expiresIn: number;
|
|
118
|
+
filename: string;
|
|
119
|
+
partNumbers: number[];
|
|
120
|
+
uploadId: string;
|
|
121
|
+
};
|
|
122
|
+
};
|
|
123
|
+
};
|
|
124
|
+
responses: {
|
|
125
|
+
200: {
|
|
126
|
+
content: {
|
|
127
|
+
'application/json': {
|
|
128
|
+
parts: Array<{
|
|
129
|
+
partNumber: number;
|
|
130
|
+
url: string;
|
|
131
|
+
}>;
|
|
132
|
+
};
|
|
133
|
+
};
|
|
134
|
+
};
|
|
135
|
+
};
|
|
136
|
+
};
|
|
137
|
+
};
|
|
138
|
+
'/api/v0/uploads/sign': {
|
|
139
|
+
post: {
|
|
140
|
+
requestBody: {
|
|
141
|
+
content: {
|
|
142
|
+
'application/json': {
|
|
143
|
+
contentType?: string;
|
|
144
|
+
expiresIn: number;
|
|
145
|
+
filename: string;
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
};
|
|
149
|
+
responses: {
|
|
150
|
+
200: {
|
|
151
|
+
content: {
|
|
152
|
+
'application/json': {
|
|
153
|
+
url: string;
|
|
154
|
+
};
|
|
155
|
+
};
|
|
156
|
+
};
|
|
157
|
+
};
|
|
158
|
+
};
|
|
159
|
+
};
|
|
160
|
+
};
|
|
161
|
+
//# sourceMappingURL=api-types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"api-types.d.ts","sourceRoot":"","sources":["../../src/storage-content-api/api-types.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/storage-content-api/api-types.ts"],"sourcesContent":["/**\n * Upload API types extracted from Content API OpenAPI spec.\n * These are kept separate to avoid breaking changes when the main spec is regenerated.\n */\n\nexport type UploadPaths = {\n '/api/v0/uploads/{filename}': {\n delete: {\n parameters: {\n path: {\n filename: string\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { success: true }\n }\n }\n }\n }\n }\n '/api/v0/uploads/download/sign': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n expiresIn: number\n filename: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { url: string }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/abort': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n filename: string\n uploadId: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { success: true }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/complete': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n filename: string\n parts: Array<{ ETag: string; PartNumber: number }>\n uploadId: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { success: true }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/initiate': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n contentType: string\n filename: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { uploadId: string }\n }\n }\n }\n }\n }\n '/api/v0/uploads/multipart/parts': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n expiresIn: number\n filename: string\n partNumbers: number[]\n uploadId: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': {\n parts: Array<{ partNumber: number; url: string }>\n }\n }\n }\n }\n }\n }\n '/api/v0/uploads/sign': {\n post: {\n requestBody: {\n content: {\n 'application/json': {\n contentType?: string\n expiresIn: number\n filename: string\n }\n }\n }\n responses: {\n 200: {\n content: {\n 'application/json': { url: string }\n }\n }\n }\n }\n }\n}\n"],"names":[],"mappings":"AAAA;;;CAGC,GAED,WAyIC"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import createClient from 'openapi-fetch';
|
|
2
|
+
import type { UploadPaths } from './api-types.js';
|
|
3
|
+
import type { StorageClientConfig } from './types.js';
|
|
4
|
+
export type StorageClient = ReturnType<typeof createClient<UploadPaths>>;
|
|
5
|
+
export declare function createStorageClient(config: StorageClientConfig): StorageClient;
|
|
6
|
+
//# sourceMappingURL=client.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../../src/storage-content-api/client.ts"],"names":[],"mappings":"AAEA,OAAO,YAAY,MAAM,eAAe,CAAA;AAExC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAA;AACjD,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAA;AAKrD,MAAM,MAAM,aAAa,GAAG,UAAU,CAAC,OAAO,YAAY,CAAC,WAAW,CAAC,CAAC,CAAA;AAExE,wBAAgB,mBAAmB,CAAC,MAAM,EAAE,mBAAmB,GAAG,aAAa,CAM9E"}
|
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
import createClient from 'openapi-fetch';
|
|
2
|
+
import { getValidProjectToken } from '../auth/project-token.js';
|
|
3
|
+
import { fetchDevJwt } from '../db-content-api/utilities/auth.js';
|
|
4
|
+
export function createStorageClient(config) {
|
|
5
|
+
const client = createClient({
|
|
6
|
+
baseUrl: config.baseUrl
|
|
7
|
+
});
|
|
8
|
+
client.use(createStorageAuthMiddleware(config));
|
|
9
|
+
return client;
|
|
10
|
+
}
|
|
11
|
+
function createStorageAuthMiddleware(config) {
|
|
12
|
+
return {
|
|
13
|
+
async onRequest ({ request }) {
|
|
14
|
+
if ('contentApiKey' in config) {
|
|
15
|
+
request.headers.set('X-Api-Key', config.contentApiKey);
|
|
16
|
+
} else {
|
|
17
|
+
const { auth, contentSystemId } = config;
|
|
18
|
+
if (auth.mode === 'apiKey') {
|
|
19
|
+
request.headers.set('X-Api-Key', auth.apiKey);
|
|
20
|
+
} else if (auth.mode === 'tokenStore') {
|
|
21
|
+
const token = await getValidProjectToken(auth.tokenStore, contentSystemId);
|
|
22
|
+
if (!token) {
|
|
23
|
+
throw new Error('Authentication required. Run `npx @payloadcms/figma login` to authenticate.');
|
|
24
|
+
}
|
|
25
|
+
request.headers.set('Authorization', `Bearer ${token}`);
|
|
26
|
+
} else {
|
|
27
|
+
const token = await fetchDevJwt(config.baseUrl, contentSystemId);
|
|
28
|
+
request.headers.set('Authorization', `Bearer ${token}`);
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return request;
|
|
32
|
+
}
|
|
33
|
+
};
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
//# sourceMappingURL=client.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/storage-content-api/client.ts"],"sourcesContent":["import type { Middleware } from 'openapi-fetch'\n\nimport createClient from 'openapi-fetch'\n\nimport type { UploadPaths } from './api-types.js'\nimport type { StorageClientConfig } from './types.js'\n\nimport { getValidProjectToken } from '../auth/project-token.js'\nimport { fetchDevJwt } from '../db-content-api/utilities/auth.js'\n\nexport type StorageClient = ReturnType<typeof createClient<UploadPaths>>\n\nexport function createStorageClient(config: StorageClientConfig): StorageClient {\n const client = createClient<UploadPaths>({ baseUrl: config.baseUrl })\n\n client.use(createStorageAuthMiddleware(config))\n\n return client\n}\n\nfunction createStorageAuthMiddleware(config: StorageClientConfig): Middleware {\n return {\n async onRequest({ request }) {\n if ('contentApiKey' in config) {\n request.headers.set('X-Api-Key', config.contentApiKey)\n } else {\n const { auth, contentSystemId } = config\n\n if (auth.mode === 'apiKey') {\n request.headers.set('X-Api-Key', auth.apiKey)\n } else if (auth.mode === 'tokenStore') {\n const token = await getValidProjectToken(auth.tokenStore, contentSystemId)\n if (!token) {\n throw new Error(\n 'Authentication required. Run `npx @payloadcms/figma login` to authenticate.',\n )\n }\n request.headers.set('Authorization', `Bearer ${token}`)\n } else {\n const token = await fetchDevJwt(config.baseUrl, contentSystemId)\n request.headers.set('Authorization', `Bearer ${token}`)\n }\n }\n return request\n },\n }\n}\n"],"names":["createClient","getValidProjectToken","fetchDevJwt","createStorageClient","config","client","baseUrl","use","createStorageAuthMiddleware","onRequest","request","headers","set","contentApiKey","auth","contentSystemId","mode","apiKey","token","tokenStore","Error"],"mappings":"AAEA,OAAOA,kBAAkB,gBAAe;AAKxC,SAASC,oBAAoB,QAAQ,2BAA0B;AAC/D,SAASC,WAAW,QAAQ,sCAAqC;AAIjE,OAAO,SAASC,oBAAoBC,MAA2B;IAC7D,MAAMC,SAASL,aAA0B;QAAEM,SAASF,OAAOE,OAAO;IAAC;IAEnED,OAAOE,GAAG,CAACC,4BAA4BJ;IAEvC,OAAOC;AACT;AAEA,SAASG,4BAA4BJ,MAA2B;IAC9D,OAAO;QACL,MAAMK,WAAU,EAAEC,OAAO,EAAE;YACzB,IAAI,mBAAmBN,QAAQ;gBAC7BM,QAAQC,OAAO,CAACC,GAAG,CAAC,aAAaR,OAAOS,aAAa;YACvD,OAAO;gBACL,MAAM,EAAEC,IAAI,EAAEC,eAAe,EAAE,GAAGX;gBAElC,IAAIU,KAAKE,IAAI,KAAK,UAAU;oBAC1BN,QAAQC,OAAO,CAACC,GAAG,CAAC,aAAaE,KAAKG,MAAM;gBAC9C,OAAO,IAAIH,KAAKE,IAAI,KAAK,cAAc;oBACrC,MAAME,QAAQ,MAAMjB,qBAAqBa,KAAKK,UAAU,EAAEJ;oBAC1D,IAAI,CAACG,OAAO;wBACV,MAAM,IAAIE,MACR;oBAEJ;oBACAV,QAAQC,OAAO,CAACC,GAAG,CAAC,iBAAiB,CAAC,OAAO,EAAEM,OAAO;gBACxD,OAAO;oBACL,MAAMA,QAAQ,MAAMhB,YAAYE,OAAOE,OAAO,EAAES;oBAChDL,QAAQC,OAAO,CAACC,GAAG,CAAC,iBAAiB,CAAC,OAAO,EAAEM,OAAO;gBACxD;YACF;YACA,OAAOR;QACT;IACF;AACF"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generateURL.d.ts","sourceRoot":"","sources":["../../src/storage-content-api/generateURL.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,wCAAwC,CAAA;AAIzE,KAAK,IAAI,GAAG;IACV,OAAO,EAAE,MAAM,CAAA;CAChB,CAAA;AAED,eAAO,MAAM,cAAc,gBACX,IAAI,KAAG,WAIpB,CAAA"}
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
export const getGenerateURL = ({ baseUrl })=>({ filename, prefix = '' })=>{
|
|
3
|
+
const fileKey = path.posix.join(prefix, filename);
|
|
4
|
+
return `${baseUrl}/api/v0/uploads/download/${encodeURIComponent(fileKey)}`;
|
|
5
|
+
};
|
|
6
|
+
|
|
7
|
+
//# sourceMappingURL=generateURL.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/storage-content-api/generateURL.ts"],"sourcesContent":["import type { GenerateURL } from '@payloadcms/plugin-cloud-storage/types'\n\nimport path from 'path'\n\ntype Args = {\n baseUrl: string\n}\n\nexport const getGenerateURL =\n ({ baseUrl }: Args): GenerateURL =>\n ({ filename, prefix = '' }) => {\n const fileKey = path.posix.join(prefix, filename)\n return `${baseUrl}/api/v0/uploads/download/${encodeURIComponent(fileKey)}`\n }\n"],"names":["path","getGenerateURL","baseUrl","filename","prefix","fileKey","posix","join","encodeURIComponent"],"mappings":"AAEA,OAAOA,UAAU,OAAM;AAMvB,OAAO,MAAMC,iBACX,CAAC,EAAEC,OAAO,EAAQ,GAClB,CAAC,EAAEC,QAAQ,EAAEC,SAAS,EAAE,EAAE;QACxB,MAAMC,UAAUL,KAAKM,KAAK,CAACC,IAAI,CAACH,QAAQD;QACxC,OAAO,GAAGD,QAAQ,yBAAyB,EAAEM,mBAAmBH,UAAU;IAC5E,EAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import type { HandleDelete } from '@payloadcms/plugin-cloud-storage/types';
|
|
2
|
+
import type { StorageClient } from './client.js';
|
|
3
|
+
type Args = {
|
|
4
|
+
client: StorageClient;
|
|
5
|
+
};
|
|
6
|
+
export declare const getHandleDelete: ({ client }: Args) => HandleDelete;
|
|
7
|
+
export {};
|
|
8
|
+
//# sourceMappingURL=handleDelete.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handleDelete.d.ts","sourceRoot":"","sources":["../../src/storage-content-api/handleDelete.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AAI1E,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,aAAa,CAAA;CACtB,CAAA;AAED,eAAO,MAAM,eAAe,eAAgB,IAAI,KAAG,YAOlD,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
export const getHandleDelete = ({ client })=>{
|
|
3
|
+
return async ({ doc: { prefix = '' }, filename })=>{
|
|
4
|
+
const fileKey = path.posix.join(prefix, filename);
|
|
5
|
+
await client.DELETE('/api/v0/uploads/{filename}', {
|
|
6
|
+
params: {
|
|
7
|
+
path: {
|
|
8
|
+
filename: fileKey
|
|
9
|
+
}
|
|
10
|
+
}
|
|
11
|
+
});
|
|
12
|
+
};
|
|
13
|
+
};
|
|
14
|
+
|
|
15
|
+
//# sourceMappingURL=handleDelete.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/storage-content-api/handleDelete.ts"],"sourcesContent":["import type { HandleDelete } from '@payloadcms/plugin-cloud-storage/types'\n\nimport path from 'path'\n\nimport type { StorageClient } from './client.js'\n\ntype Args = {\n client: StorageClient\n}\n\nexport const getHandleDelete = ({ client }: Args): HandleDelete => {\n return async ({ doc: { prefix = '' }, filename }) => {\n const fileKey = path.posix.join(prefix, filename)\n await client.DELETE('/api/v0/uploads/{filename}', {\n params: { path: { filename: fileKey } },\n })\n }\n}\n"],"names":["path","getHandleDelete","client","doc","prefix","filename","fileKey","posix","join","DELETE","params"],"mappings":"AAEA,OAAOA,UAAU,OAAM;AAQvB,OAAO,MAAMC,kBAAkB,CAAC,EAAEC,MAAM,EAAQ;IAC9C,OAAO,OAAO,EAAEC,KAAK,EAAEC,SAAS,EAAE,EAAE,EAAEC,QAAQ,EAAE;QAC9C,MAAMC,UAAUN,KAAKO,KAAK,CAACC,IAAI,CAACJ,QAAQC;QACxC,MAAMH,OAAOO,MAAM,CAAC,8BAA8B;YAChDC,QAAQ;gBAAEV,MAAM;oBAAEK,UAAUC;gBAAQ;YAAE;QACxC;IACF;AACF,EAAC"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { HandleUpload } from '@payloadcms/plugin-cloud-storage/types';
|
|
2
|
+
import type { CollectionConfig } from 'payload';
|
|
3
|
+
import type { StorageClient } from './client.js';
|
|
4
|
+
type Args = {
|
|
5
|
+
client: StorageClient;
|
|
6
|
+
collection: CollectionConfig;
|
|
7
|
+
prefix?: string;
|
|
8
|
+
};
|
|
9
|
+
export declare const getHandleUpload: ({ client, prefix }: Args) => HandleUpload;
|
|
10
|
+
export {};
|
|
11
|
+
//# sourceMappingURL=handleUpload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"handleUpload.d.ts","sourceRoot":"","sources":["../../src/storage-content-api/handleUpload.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,wCAAwC,CAAA;AAC1E,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,SAAS,CAAA;AAK/C,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AAEhD,KAAK,IAAI,GAAG;IACV,MAAM,EAAE,aAAa,CAAA;IACrB,UAAU,EAAE,gBAAgB,CAAA;IAC5B,MAAM,CAAC,EAAE,MAAM,CAAA;CAChB,CAAA;AAID,eAAO,MAAM,eAAe,uBAA6B,IAAI,KAAG,YAc/D,CAAA"}
|