@payloadcms/figma 0.0.1-alpha.5 → 0.0.1-alpha.50
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/control-plane.d.ts +31 -1
- package/dist/api/control-plane.js +137 -67
- package/dist/api/figma-api.d.ts +20 -0
- package/dist/api/figma-api.js +77 -21
- package/dist/auth/callback-server.js +2 -1
- package/dist/auth/crypto-utils.js +5 -5
- package/dist/auth/jwt-validator.d.ts +2 -1
- package/dist/auth/jwt-validator.js +2 -2
- package/dist/auth/oauth-flow.d.ts +1 -1
- package/dist/auth/oauth-flow.js +15 -11
- package/dist/auth/project-token.js +11 -6
- package/dist/auth/refresh.d.ts +2 -1
- package/dist/auth/refresh.js +25 -12
- package/dist/auth/token-store.d.ts +40 -1
- package/dist/auth/token-store.js +65 -5
- package/dist/auth/types.d.ts +17 -4
- package/dist/cli.js +54 -6
- package/dist/commands/build-lambda-zip.d.ts +5 -0
- package/dist/commands/build-lambda-zip.js +19 -0
- package/dist/commands/debug.d.ts +8 -0
- package/dist/commands/debug.js +161 -0
- package/dist/commands/deploy.d.ts +6 -0
- package/dist/commands/deploy.js +94 -126
- package/dist/commands/env.d.ts +13 -0
- package/dist/commands/env.js +88 -0
- package/dist/commands/init.d.ts +3 -5
- package/dist/commands/init.js +118 -94
- package/dist/commands/list-tokens.d.ts +3 -3
- package/dist/commands/list-tokens.js +22 -7
- package/dist/commands/login.d.ts +8 -1
- package/dist/commands/login.js +30 -12
- package/dist/commands/logout.d.ts +5 -4
- package/dist/commands/logout.js +56 -13
- package/dist/config/oauth.d.ts +4 -14
- package/dist/config/oauth.js +18 -40
- package/dist/constants.d.ts +36 -19
- package/dist/constants.js +58 -20
- package/dist/db-content-api/README.md +98 -0
- package/dist/db-content-api/generated/content-api-types.d.ts +3746 -0
- package/dist/db-content-api/generated/content-api-types.js +7 -0
- package/dist/db-content-api/index.d.ts +20 -0
- package/dist/db-content-api/index.js +702 -0
- package/dist/db-content-api/temp-utilities/slug.d.ts +2 -0
- package/dist/db-content-api/temp-utilities/slug.js +3 -0
- package/dist/db-content-api/temp-utilities/sorting.d.ts +3 -0
- package/dist/db-content-api/temp-utilities/sorting.js +32 -0
- package/dist/db-content-api/temp-utilities/types.d.ts +22 -0
- package/dist/db-content-api/temp-utilities/types.js +15 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.d.ts +34 -0
- package/dist/db-content-api/temp-utilities/unwrapDocument.js +53 -0
- package/dist/db-content-api/utilities/auth.d.ts +30 -0
- package/dist/db-content-api/utilities/auth.js +81 -0
- package/dist/db-content-api/utilities/data/applyDefaults.d.ts +7 -0
- package/dist/db-content-api/utilities/data/applyDefaults.js +59 -0
- package/dist/db-content-api/utilities/data/castFieldValue.d.ts +11 -0
- package/dist/db-content-api/utilities/data/castFieldValue.js +69 -0
- package/dist/db-content-api/utilities/data/index.d.ts +42 -0
- package/dist/db-content-api/utilities/data/index.js +211 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.d.ts +12 -0
- package/dist/db-content-api/utilities/data/removeVirtualFields.js +54 -0
- package/dist/db-content-api/utilities/data/stripFields.d.ts +48 -0
- package/dist/db-content-api/utilities/data/stripFields.js +195 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.d.ts +23 -0
- package/dist/db-content-api/utilities/data/transformPublishedLocale.js +42 -0
- package/dist/db-content-api/utilities/joins.d.ts +55 -0
- package/dist/db-content-api/utilities/joins.js +136 -0
- package/dist/db-content-api/utilities/locale/index.d.ts +10 -0
- package/dist/db-content-api/utilities/locale/index.js +21 -0
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.d.ts +11 -0
- package/dist/db-content-api/utilities/meta/buildLocalizedPaths.js +66 -0
- package/dist/db-content-api/utilities/meta/buildMeta.d.ts +37 -0
- package/dist/db-content-api/utilities/meta/buildMeta.js +33 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.d.ts +13 -0
- package/dist/db-content-api/utilities/meta/buildPathTypes.js +181 -0
- package/dist/db-content-api/utilities/where.d.ts +20 -0
- package/dist/db-content-api/utilities/where.js +127 -0
- package/dist/endpoints/health.d.ts +3 -0
- package/dist/endpoints/health.js +11 -0
- package/dist/endpoints/schema.d.ts +3 -0
- package/dist/endpoints/schema.js +29 -0
- package/dist/exports/client.d.ts +3 -0
- package/dist/exports/client.js +3 -0
- package/dist/index.d.ts +2 -1
- package/dist/index.js +3 -1
- package/dist/oauth/components/FigmaAvatar/index.d.ts +4 -0
- package/dist/oauth/components/FigmaAvatar/index.js +27 -0
- package/dist/oauth/components/FigmaAvatar/index.scss +12 -0
- package/dist/oauth/components/FigmaAvatarCell/index.d.ts +5 -0
- package/dist/oauth/components/FigmaAvatarCell/index.js +25 -0
- package/dist/oauth/components/FigmaAvatarCell/index.scss +5 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.d.ts +9 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.js +37 -0
- package/dist/oauth/components/FigmaAvatarPlaceholder/index.scss +28 -0
- package/dist/oauth/components/LoginButton/index.js +50 -6
- package/dist/oauth/components/LoginButton/index.scss +50 -3
- package/dist/oauth/components/LogoutButton/index.js +5 -4
- package/dist/oauth/defaults.js +67 -10
- package/dist/oauth/endpoints/getLoginEndpoint.js +69 -24
- package/dist/oauth/endpoints/getLogoutEndpoint.js +7 -4
- package/dist/oauth/index.js +40 -5
- package/dist/oauth/strategy/index.d.ts +0 -2
- package/dist/oauth/strategy/index.js +40 -17
- package/dist/oauth/types.d.ts +6 -6
- package/dist/oauth/utilities/isDuplicateKeyError.d.ts +7 -0
- package/dist/oauth/utilities/isDuplicateKeyError.js +14 -0
- package/dist/oauth/utilities/refreshTokens.js +3 -3
- package/dist/plugin/build-config.d.ts +21 -14
- package/dist/plugin/build-config.js +208 -17
- package/dist/storage-content-api/api-types.d.ts +168 -0
- package/dist/storage-content-api/api-types.js +6 -0
- package/dist/storage-content-api/client-uploads/ClientUploadHandler.d.ts +9 -0
- package/dist/storage-content-api/client-uploads/ClientUploadHandler.js +42 -0
- package/dist/storage-content-api/client-uploads/generateSignedURL.d.ts +13 -0
- package/dist/storage-content-api/client-uploads/generateSignedURL.js +39 -0
- package/dist/storage-content-api/client.d.ts +6 -0
- package/dist/storage-content-api/client.js +36 -0
- package/dist/storage-content-api/generateURL.d.ts +7 -0
- package/dist/storage-content-api/generateURL.js +8 -0
- package/dist/storage-content-api/handleDelete.d.ts +8 -0
- package/dist/storage-content-api/handleDelete.js +17 -0
- package/dist/storage-content-api/handleUpload.d.ts +11 -0
- package/dist/storage-content-api/handleUpload.js +144 -0
- package/dist/storage-content-api/index.d.ts +5 -0
- package/dist/storage-content-api/index.js +31 -0
- package/dist/storage-content-api/staticHandler.d.ts +10 -0
- package/dist/storage-content-api/staticHandler.js +56 -0
- package/dist/storage-content-api/types.d.ts +10 -0
- package/dist/storage-content-api/types.js +3 -0
- package/dist/storage-content-api/utilities/getSafeFilename.d.ts +12 -0
- package/dist/storage-content-api/utilities/getSafeFilename.js +61 -0
- package/dist/storage-content-api/utilities/index.d.ts +2 -0
- package/dist/storage-content-api/utilities/index.js +3 -0
- package/dist/templates/.env.example +5 -0
- package/dist/templates/README.md +19 -0
- package/dist/types/config.d.ts +2 -1
- package/dist/types/config.js +0 -2
- package/dist/types.d.ts +3 -1
- package/dist/utils/asset-collection.d.ts +3 -6
- package/dist/utils/asset-collection.js +10 -34
- package/dist/utils/build-lambda-zip.d.ts +14 -0
- package/dist/utils/build-lambda-zip.js +81 -0
- package/dist/utils/cache-bootstrap.d.ts +8 -0
- package/dist/utils/cache-bootstrap.js +18 -0
- package/dist/utils/config.js +1 -1
- package/dist/utils/env-management.d.ts +16 -7
- package/dist/utils/env-management.js +85 -64
- package/dist/utils/format-env-suffix.d.ts +12 -0
- package/dist/utils/format-env-suffix.js +13 -0
- package/dist/utils/formatter.js +3 -5
- package/dist/utils/lambda-config.d.ts +3 -1
- package/dist/utils/lambda-config.js +38 -32
- package/dist/utils/messages.d.ts +1 -1
- package/dist/utils/messages.js +22 -8
- package/dist/utils/package-manager.d.ts +24 -0
- package/dist/utils/package-manager.js +53 -0
- package/dist/utils/payload-config-ast.d.ts +22 -3
- package/dist/utils/payload-config-ast.js +96 -31
- package/dist/utils/payload-config-finder.d.ts +2 -2
- package/dist/utils/payload-config-finder.js +48 -9
- package/dist/utils/payload-config-modifier.d.ts +1 -1
- package/dist/utils/payload-config-modifier.js +58 -9
- package/dist/utils/payload-package-check.d.ts +12 -1
- package/dist/utils/payload-package-check.js +63 -5
- package/dist/utils/project.d.ts +3 -2
- package/dist/utils/project.js +15 -7
- package/dist/utils/resolve-environment.d.ts +14 -0
- package/dist/utils/resolve-environment.js +28 -0
- package/dist/utils/s3-upload.d.ts +0 -1
- package/dist/utils/s3-upload.js +10 -3
- package/dist/utils/token-display.js +11 -5
- package/dist/utils/typescript-validator.js +4 -6
- package/dist/utils/version-check.d.ts +3 -0
- package/dist/utils/version-check.js +38 -0
- package/package.json +29 -10
- package/dist/api/control-plane.d.ts.map +0 -1
- package/dist/api/control-plane.js.map +0 -1
- package/dist/api/figma-api.d.ts.map +0 -1
- package/dist/api/figma-api.js.map +0 -1
- package/dist/auth/browser.d.ts.map +0 -1
- package/dist/auth/browser.js.map +0 -1
- package/dist/auth/callback-server.d.ts.map +0 -1
- package/dist/auth/callback-server.js.map +0 -1
- package/dist/auth/crypto-utils.d.ts.map +0 -1
- package/dist/auth/crypto-utils.js.map +0 -1
- package/dist/auth/jwt-validator.d.ts.map +0 -1
- package/dist/auth/jwt-validator.js.map +0 -1
- package/dist/auth/oauth-flow.d.ts.map +0 -1
- package/dist/auth/oauth-flow.js.map +0 -1
- package/dist/auth/pkce.d.ts.map +0 -1
- package/dist/auth/pkce.js.map +0 -1
- package/dist/auth/project-token.d.ts.map +0 -1
- package/dist/auth/project-token.js.map +0 -1
- package/dist/auth/refresh.d.ts.map +0 -1
- package/dist/auth/refresh.js.map +0 -1
- package/dist/auth/token-store.d.ts.map +0 -1
- package/dist/auth/token-store.js.map +0 -1
- package/dist/auth/types.d.ts.map +0 -1
- package/dist/auth/types.js.map +0 -1
- package/dist/cli.d.ts.map +0 -1
- package/dist/cli.js.map +0 -1
- package/dist/commands/deploy.d.ts.map +0 -1
- package/dist/commands/deploy.js.map +0 -1
- package/dist/commands/init.d.ts.map +0 -1
- package/dist/commands/init.js.map +0 -1
- package/dist/commands/list-tokens.d.ts.map +0 -1
- package/dist/commands/list-tokens.js.map +0 -1
- package/dist/commands/login.d.ts.map +0 -1
- package/dist/commands/login.js.map +0 -1
- package/dist/commands/logout.d.ts.map +0 -1
- package/dist/commands/logout.js.map +0 -1
- package/dist/config/oauth.d.ts.map +0 -1
- package/dist/config/oauth.js.map +0 -1
- package/dist/constants.d.ts.map +0 -1
- package/dist/constants.js.map +0 -1
- package/dist/exports/client.d.ts.map +0 -1
- package/dist/exports/client.js.map +0 -1
- package/dist/index.d.ts.map +0 -1
- package/dist/index.js.map +0 -1
- package/dist/oauth/components/LoginButton/index.d.ts.map +0 -1
- package/dist/oauth/components/LoginButton/index.js.map +0 -1
- package/dist/oauth/components/LogoutButton/index.d.ts.map +0 -1
- package/dist/oauth/components/LogoutButton/index.js.map +0 -1
- package/dist/oauth/defaults.d.ts.map +0 -1
- package/dist/oauth/defaults.js.map +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getLoginEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getLogoutEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getMetaEndpoint.js.map +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.d.ts.map +0 -1
- package/dist/oauth/endpoints/getRedirectToLoginEndpoint.js.map +0 -1
- package/dist/oauth/exports/client.d.ts.map +0 -1
- package/dist/oauth/exports/client.js.map +0 -1
- package/dist/oauth/hooks/afterLogout.d.ts.map +0 -1
- package/dist/oauth/hooks/afterLogout.js.map +0 -1
- package/dist/oauth/hooks/me.d.ts.map +0 -1
- package/dist/oauth/hooks/me.js.map +0 -1
- package/dist/oauth/hooks/refresh.d.ts.map +0 -1
- package/dist/oauth/hooks/refresh.js.map +0 -1
- package/dist/oauth/index.d.ts.map +0 -1
- package/dist/oauth/index.js.map +0 -1
- package/dist/oauth/strategy/index.d.ts.map +0 -1
- package/dist/oauth/strategy/index.js.map +0 -1
- package/dist/oauth/types.d.ts.map +0 -1
- package/dist/oauth/types.js.map +0 -1
- package/dist/oauth/utilities/clearCookie.d.ts.map +0 -1
- package/dist/oauth/utilities/clearCookie.js.map +0 -1
- package/dist/oauth/utilities/createCookieOptions.d.ts.map +0 -1
- package/dist/oauth/utilities/createCookieOptions.js.map +0 -1
- package/dist/oauth/utilities/createDebugLogger.d.ts.map +0 -1
- package/dist/oauth/utilities/createDebugLogger.js.map +0 -1
- package/dist/oauth/utilities/extractOrigin.d.ts.map +0 -1
- package/dist/oauth/utilities/extractOrigin.js.map +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.d.ts.map +0 -1
- package/dist/oauth/utilities/getAdminCollectionSlug.js.map +0 -1
- package/dist/oauth/utilities/getAdminPath.d.ts +0 -8
- package/dist/oauth/utilities/getAdminPath.d.ts.map +0 -1
- package/dist/oauth/utilities/getAdminPath.js +0 -9
- package/dist/oauth/utilities/getAdminPath.js.map +0 -1
- package/dist/oauth/utilities/getAuthorizeURL.d.ts.map +0 -1
- package/dist/oauth/utilities/getAuthorizeURL.js.map +0 -1
- package/dist/oauth/utilities/getCookieExpiration.d.ts.map +0 -1
- package/dist/oauth/utilities/getCookieExpiration.js.map +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.d.ts.map +0 -1
- package/dist/oauth/utilities/getSecondsFromTokenExp.js.map +0 -1
- package/dist/oauth/utilities/getTokenExp.d.ts.map +0 -1
- package/dist/oauth/utilities/getTokenExp.js.map +0 -1
- package/dist/oauth/utilities/getUsernameField.d.ts.map +0 -1
- package/dist/oauth/utilities/getUsernameField.js.map +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.d.ts.map +0 -1
- package/dist/oauth/utilities/hasUserTokenPropsChanged.js.map +0 -1
- package/dist/oauth/utilities/mergeHeaders.d.ts.map +0 -1
- package/dist/oauth/utilities/mergeHeaders.js.map +0 -1
- package/dist/oauth/utilities/refreshTokens.d.ts.map +0 -1
- package/dist/oauth/utilities/refreshTokens.js.map +0 -1
- package/dist/plugin/adapter.d.ts.map +0 -1
- package/dist/plugin/adapter.js.map +0 -1
- package/dist/plugin/build-config.d.ts.map +0 -1
- package/dist/plugin/build-config.js.map +0 -1
- package/dist/types/config.d.ts.map +0 -1
- package/dist/types/config.js.map +0 -1
- package/dist/types.d.ts.map +0 -1
- package/dist/types.js.map +0 -1
- package/dist/utils/asset-collection.d.ts.map +0 -1
- package/dist/utils/asset-collection.js.map +0 -1
- package/dist/utils/build-detection.d.ts.map +0 -1
- package/dist/utils/build-detection.js.map +0 -1
- package/dist/utils/config.d.ts.map +0 -1
- package/dist/utils/config.js.map +0 -1
- package/dist/utils/download-template.d.ts.map +0 -1
- package/dist/utils/download-template.js.map +0 -1
- package/dist/utils/env-management.d.ts.map +0 -1
- package/dist/utils/env-management.js.map +0 -1
- package/dist/utils/format.d.ts.map +0 -1
- package/dist/utils/format.js.map +0 -1
- package/dist/utils/formatter.d.ts.map +0 -1
- package/dist/utils/formatter.js.map +0 -1
- package/dist/utils/git.d.ts.map +0 -1
- package/dist/utils/git.js.map +0 -1
- package/dist/utils/is-debug.d.ts.map +0 -1
- package/dist/utils/is-debug.js.map +0 -1
- package/dist/utils/lambda-config.d.ts.map +0 -1
- package/dist/utils/lambda-config.js.map +0 -1
- package/dist/utils/log.d.ts.map +0 -1
- package/dist/utils/log.js.map +0 -1
- package/dist/utils/messages.d.ts.map +0 -1
- package/dist/utils/messages.js.map +0 -1
- package/dist/utils/package-manager.d.ts.map +0 -1
- package/dist/utils/package-manager.js.map +0 -1
- package/dist/utils/payload-config-ast.d.ts.map +0 -1
- package/dist/utils/payload-config-ast.js.map +0 -1
- package/dist/utils/payload-config-finder.d.ts.map +0 -1
- package/dist/utils/payload-config-finder.js.map +0 -1
- package/dist/utils/payload-config-modifier.d.ts.map +0 -1
- package/dist/utils/payload-config-modifier.js.map +0 -1
- package/dist/utils/payload-package-check.d.ts.map +0 -1
- package/dist/utils/payload-package-check.js.map +0 -1
- package/dist/utils/project.d.ts.map +0 -1
- package/dist/utils/project.js.map +0 -1
- package/dist/utils/s3-upload.d.ts.map +0 -1
- package/dist/utils/s3-upload.js.map +0 -1
- package/dist/utils/token-display.d.ts.map +0 -1
- package/dist/utils/token-display.js.map +0 -1
- package/dist/utils/typescript-validator.d.ts.map +0 -1
- package/dist/utils/typescript-validator.js.map +0 -1
|
@@ -0,0 +1,211 @@
|
|
|
1
|
+
import { flattenAllFields, traverseFields } from 'payload';
|
|
2
|
+
import { applyDefaults } from './applyDefaults.js';
|
|
3
|
+
import { castFieldValue } from './castFieldValue.js';
|
|
4
|
+
import { removeVirtualFields } from './removeVirtualFields.js';
|
|
5
|
+
import { stripFields } from './stripFields.js';
|
|
6
|
+
import { transformToLocalizeStatus } from './transformPublishedLocale.js';
|
|
7
|
+
/**
|
|
8
|
+
* Transform data before sending to Content API (WRITE operations)
|
|
9
|
+
*
|
|
10
|
+
* Conversions applied:
|
|
11
|
+
* - Default values: Apply static defaults for undefined fields (when applyDefaults=true)
|
|
12
|
+
* - Type casting: Convert values to match field types (e.g., number -> string for text fields)
|
|
13
|
+
* - RichText fields: Objects -> JSON strings
|
|
14
|
+
* - Virtual fields: Remove fields with `virtual: true` (pure virtual fields should never be saved)
|
|
15
|
+
* - Timestamps: Add updatedAt (always), and createdAt (when createdAt=true)
|
|
16
|
+
* - publishedLocale: Transform to localizeStatus format (when publishedLocale is provided)
|
|
17
|
+
*
|
|
18
|
+
* Note: Date fields are automatically converted to ISO strings by JSON.stringify()
|
|
19
|
+
*/ export function dataToContentAPI(payload, collectionSlug, data, options) {
|
|
20
|
+
if (!data || typeof data !== 'object') {
|
|
21
|
+
return data;
|
|
22
|
+
}
|
|
23
|
+
// Transform publishedLocale to localizeStatus format before other transformations
|
|
24
|
+
const dataWithLocalizedStatus = transformToLocalizeStatus(data, options?.publishedLocale);
|
|
25
|
+
// Deep clone to avoid mutating original data
|
|
26
|
+
const transformed = JSON.parse(JSON.stringify(dataWithLocalizedStatus));
|
|
27
|
+
// Get collection config
|
|
28
|
+
const isGlobal = collectionSlug.startsWith('_global-');
|
|
29
|
+
const actualSlug = isGlobal ? collectionSlug.substring(8) : collectionSlug;
|
|
30
|
+
const collectionConfig = isGlobal ? payload.config.globals?.find((g)=>g.slug === actualSlug) : payload.config.collections.find((c)=>c.slug === actualSlug);
|
|
31
|
+
if (!collectionConfig?.fields) {
|
|
32
|
+
return transformed;
|
|
33
|
+
}
|
|
34
|
+
// Apply static defaults recursively to handle nested structures (arrays, groups)
|
|
35
|
+
// This must happen before traverseFields to ensure defaults are in place
|
|
36
|
+
if (options?.applyDefaults) {
|
|
37
|
+
applyDefaults(transformed, collectionConfig.fields);
|
|
38
|
+
}
|
|
39
|
+
// Use Payload's traverseFields to iterate over all fields for transformations
|
|
40
|
+
const callback = ({ field, ref })=>{
|
|
41
|
+
if (!('name' in field) || !field.name) {
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
if (!ref || typeof ref !== 'object') {
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const current = ref;
|
|
48
|
+
let value = current[field.name];
|
|
49
|
+
// Transform existing values
|
|
50
|
+
if (value !== null && value !== undefined) {
|
|
51
|
+
// Step 1: Apply type casting (e.g., number -> string for text fields)
|
|
52
|
+
value = castFieldValue(field, value);
|
|
53
|
+
current[field.name] = value;
|
|
54
|
+
// Step 2: Apply Content API specific transformations
|
|
55
|
+
// RichText: object -> JSON string
|
|
56
|
+
if (field.type === 'richText' && typeof value !== 'string') {
|
|
57
|
+
current[field.name] = JSON.stringify(value);
|
|
58
|
+
}
|
|
59
|
+
// Date fields are already handled by JSON.stringify() which converts Date -> ISO string
|
|
60
|
+
}
|
|
61
|
+
};
|
|
62
|
+
traverseFields({
|
|
63
|
+
callback,
|
|
64
|
+
fields: collectionConfig.fields,
|
|
65
|
+
fillEmpty: false,
|
|
66
|
+
ref: transformed
|
|
67
|
+
});
|
|
68
|
+
stripFields({
|
|
69
|
+
config: payload.config,
|
|
70
|
+
data: transformed,
|
|
71
|
+
fields: flattenAllFields({
|
|
72
|
+
cache: true,
|
|
73
|
+
fields: collectionConfig.fields
|
|
74
|
+
}),
|
|
75
|
+
reservedKeys: [
|
|
76
|
+
'id',
|
|
77
|
+
'globalType'
|
|
78
|
+
]
|
|
79
|
+
});
|
|
80
|
+
removeVirtualFields(transformed, collectionConfig.fields);
|
|
81
|
+
// Convert numeric ID to string for Content API
|
|
82
|
+
const customIDType = payload.collections?.[collectionSlug]?.customIDType;
|
|
83
|
+
if (customIDType === 'number') {
|
|
84
|
+
transformed.id = String(transformed.id);
|
|
85
|
+
}
|
|
86
|
+
// Add timestamps (Content API no longer auto-sets these in DB)
|
|
87
|
+
// updatedAt is always set, createdAt only on create operations
|
|
88
|
+
const now = new Date().toISOString();
|
|
89
|
+
transformed.updatedAt = now;
|
|
90
|
+
if (options?.createdAt) {
|
|
91
|
+
transformed.createdAt = now;
|
|
92
|
+
}
|
|
93
|
+
return transformed;
|
|
94
|
+
}
|
|
95
|
+
/**
|
|
96
|
+
* Transform data received from Content API (READ operations)
|
|
97
|
+
*
|
|
98
|
+
* Conversions applied:
|
|
99
|
+
* - RichText fields: JSON strings -> Objects
|
|
100
|
+
* - Virtual fields: Remove fields with `virtual: true` (should not be in DB but Content API backend may add them)
|
|
101
|
+
*
|
|
102
|
+
* Note: Date fields come as ISO strings from Content API and stay as strings
|
|
103
|
+
* (matching MongoDB and other adapters' behavior)
|
|
104
|
+
*/ export function dataFromContentAPI(payload, collectionSlug, data) {
|
|
105
|
+
if (!data || typeof data !== 'object') {
|
|
106
|
+
return data;
|
|
107
|
+
}
|
|
108
|
+
// Deep clone to avoid mutating original data
|
|
109
|
+
const transformed = JSON.parse(JSON.stringify(data));
|
|
110
|
+
// Get collection config
|
|
111
|
+
const isGlobal = collectionSlug.startsWith('_global-');
|
|
112
|
+
const actualSlug = isGlobal ? collectionSlug.substring(8) : collectionSlug;
|
|
113
|
+
const collectionConfig = isGlobal ? payload.config.globals?.find((g)=>g.slug === actualSlug) : payload.config.collections.find((c)=>c.slug === actualSlug);
|
|
114
|
+
if (!collectionConfig?.fields) {
|
|
115
|
+
return transformed;
|
|
116
|
+
}
|
|
117
|
+
// Use Payload's traverseFields to iterate over all fields
|
|
118
|
+
const callback = ({ field, parentPath, ref })=>{
|
|
119
|
+
if (!('name' in field) || !field.name) {
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
if (!ref || typeof ref !== 'object') {
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
const current = ref;
|
|
126
|
+
const value = current[field.name];
|
|
127
|
+
// Normalize undefined → null for optional fields
|
|
128
|
+
// Content API may omit fields (undefined) but Payload expects null for optional fields
|
|
129
|
+
if (value === undefined) {
|
|
130
|
+
const isRequired = 'required' in field && field.required;
|
|
131
|
+
if (!isRequired) {
|
|
132
|
+
current[field.name] = null;
|
|
133
|
+
}
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
if (value !== null) {
|
|
137
|
+
// Localized fields: JSON string -> parsed object
|
|
138
|
+
// Content API may store localized fields as JSON strings like "{\"en\":\"value\"}"
|
|
139
|
+
// so we need to parse them back to objects.
|
|
140
|
+
// Note: We return the full locale object - Payload Core handles flattening to requested locale.
|
|
141
|
+
// When requesting a specific locale (not 'all'), values are simple strings that won't parse.
|
|
142
|
+
// In that case, we silently keep the original value.
|
|
143
|
+
if ('localized' in field && field.localized && typeof value === 'string') {
|
|
144
|
+
try {
|
|
145
|
+
const parsed = JSON.parse(value);
|
|
146
|
+
// Only use parsed value if it's actually an object (locale -> value mapping)
|
|
147
|
+
// Simple strings like "EN Title" would parse to themselves, which we don't want
|
|
148
|
+
if (typeof parsed === 'object' && parsed !== null) {
|
|
149
|
+
current[field.name] = parsed;
|
|
150
|
+
}
|
|
151
|
+
} catch {
|
|
152
|
+
// Not valid JSON - keep original value (this is expected for single-locale requests)
|
|
153
|
+
}
|
|
154
|
+
} else if (field.type === 'richText' && typeof value === 'string') {
|
|
155
|
+
try {
|
|
156
|
+
current[field.name] = JSON.parse(value);
|
|
157
|
+
} catch (error) {
|
|
158
|
+
const fieldPath = parentPath ? `${parentPath}.${field.name}` : field.name;
|
|
159
|
+
payload.logger.warn({
|
|
160
|
+
err: error instanceof Error ? error : new Error(String(error)),
|
|
161
|
+
msg: `Failed to parse richtext field '${fieldPath}' in collection '${collectionSlug}'`
|
|
162
|
+
});
|
|
163
|
+
}
|
|
164
|
+
}
|
|
165
|
+
// Date fields: Already ISO strings from Content API, no conversion needed
|
|
166
|
+
}
|
|
167
|
+
};
|
|
168
|
+
traverseFields({
|
|
169
|
+
callback,
|
|
170
|
+
fields: collectionConfig.fields,
|
|
171
|
+
fillEmpty: false,
|
|
172
|
+
ref: transformed
|
|
173
|
+
});
|
|
174
|
+
// Convert string ID to number if collection uses numeric custom ID
|
|
175
|
+
const customIDType = payload.collections?.[collectionSlug]?.customIDType;
|
|
176
|
+
if (customIDType === 'number') {
|
|
177
|
+
transformed.id = Number(transformed.id);
|
|
178
|
+
}
|
|
179
|
+
stripFields({
|
|
180
|
+
config: payload.config,
|
|
181
|
+
data: transformed,
|
|
182
|
+
fields: flattenAllFields({
|
|
183
|
+
cache: true,
|
|
184
|
+
fields: collectionConfig.fields
|
|
185
|
+
}),
|
|
186
|
+
reservedKeys: [
|
|
187
|
+
'id',
|
|
188
|
+
'globalType'
|
|
189
|
+
]
|
|
190
|
+
});
|
|
191
|
+
// Remove virtual fields - must happen AFTER stripFields
|
|
192
|
+
removeVirtualFields(transformed, collectionConfig.fields);
|
|
193
|
+
// Handle auth-specific fields that aren't in the field schema
|
|
194
|
+
// When these fields are null in DB, Content API omits them from response (undefined)
|
|
195
|
+
// But Payload expects them to be null, not undefined
|
|
196
|
+
// Only add them if the collection has auth enabled
|
|
197
|
+
if ('auth' in collectionConfig && collectionConfig.auth) {
|
|
198
|
+
const authFields = [
|
|
199
|
+
'resetPasswordExpiration',
|
|
200
|
+
'lockUntil'
|
|
201
|
+
];
|
|
202
|
+
for (const fieldName of authFields){
|
|
203
|
+
if (!(fieldName in transformed)) {
|
|
204
|
+
transformed[fieldName] = null;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return transformed;
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { CollectionConfig } from 'payload';
|
|
2
|
+
/**
|
|
3
|
+
* Removes virtual fields (fields with virtual: true) from data recursively.
|
|
4
|
+
* Virtual fields should never be persisted in the database.
|
|
5
|
+
*
|
|
6
|
+
* @todo It might be a good idea to combine `stripFields` with `stripFields`
|
|
7
|
+
* in a new utility that receives a callback with conditions. I didn't do
|
|
8
|
+
* it now because `stripFields` was copied from db-mongo and I'd like to
|
|
9
|
+
* find a way to unify everything.
|
|
10
|
+
*/
|
|
11
|
+
export declare function removeVirtualFields(data: Record<string, unknown>, fieldConfigs: CollectionConfig['fields']): void;
|
|
12
|
+
//# sourceMappingURL=removeVirtualFields.d.ts.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Removes virtual fields (fields with virtual: true) from data recursively.
|
|
3
|
+
* Virtual fields should never be persisted in the database.
|
|
4
|
+
*
|
|
5
|
+
* @todo It might be a good idea to combine `stripFields` with `stripFields`
|
|
6
|
+
* in a new utility that receives a callback with conditions. I didn't do
|
|
7
|
+
* it now because `stripFields` was copied from db-mongo and I'd like to
|
|
8
|
+
* find a way to unify everything.
|
|
9
|
+
*/ export function removeVirtualFields(data, fieldConfigs) {
|
|
10
|
+
for (const field of fieldConfigs){
|
|
11
|
+
// Handle UI fields (row, collapsible, tabs) - they don't have names
|
|
12
|
+
// but contain other fields that might be virtual
|
|
13
|
+
if (field.type === 'row' || field.type === 'collapsible') {
|
|
14
|
+
if ('fields' in field) {
|
|
15
|
+
removeVirtualFields(data, field.fields);
|
|
16
|
+
}
|
|
17
|
+
continue;
|
|
18
|
+
}
|
|
19
|
+
if (field.type === 'tabs' && 'tabs' in field) {
|
|
20
|
+
for (const tab of field.tabs){
|
|
21
|
+
if ('fields' in tab) {
|
|
22
|
+
removeVirtualFields(data, tab.fields);
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
// Skip fields without names
|
|
28
|
+
if (!('name' in field) || !field.name) {
|
|
29
|
+
continue;
|
|
30
|
+
}
|
|
31
|
+
// Remove field if it has virtual: true
|
|
32
|
+
if ('virtual' in field && field.virtual === true) {
|
|
33
|
+
delete data[field.name];
|
|
34
|
+
continue;
|
|
35
|
+
}
|
|
36
|
+
// Recursively handle nested structures (groups, arrays with items, etc.)
|
|
37
|
+
if ('fields' in field && field.name in data) {
|
|
38
|
+
const value = data[field.name];
|
|
39
|
+
if (field.type === 'array' && Array.isArray(value)) {
|
|
40
|
+
// Process each array item
|
|
41
|
+
for (const item of value){
|
|
42
|
+
if (item && typeof item === 'object') {
|
|
43
|
+
removeVirtualFields(item, field.fields);
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
} else if (field.type === 'group' && value && typeof value === 'object') {
|
|
47
|
+
// Process group
|
|
48
|
+
removeVirtualFields(value, field.fields);
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
//# sourceMappingURL=removeVirtualFields.js.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
import type { FlattenedField, SanitizedConfig } from 'payload';
|
|
2
|
+
/**
|
|
3
|
+
* Strips fields from data that are not defined in the schema or are invalid.
|
|
4
|
+
*
|
|
5
|
+
* This function was copied from the MongoDB adapter's implementation:
|
|
6
|
+
* @see packages/db-mongodb/src/utilities/transform.ts (stripFields function)
|
|
7
|
+
*
|
|
8
|
+
* @description
|
|
9
|
+
* This utility performs deep sanitization of document data by:
|
|
10
|
+
* 1. **Removing undefined fields**: Strips any field not present in the collection's schema
|
|
11
|
+
* (e.g., sensitive fields like `password`, `apiKey`, or any extra fields not in config)
|
|
12
|
+
* 2. **Removing invalid locales**: Deletes locale keys that don't exist in `config.localization.localeCodes`
|
|
13
|
+
* (e.g., if data contains `{ "es-MX": "..." }` but only `"en"` is configured)
|
|
14
|
+
* 3. **Removing invalid blocks**: Filters out blocks with unknown `blockType` values
|
|
15
|
+
* (prevents data corruption from blocks that don't exist in the schema)
|
|
16
|
+
* 4. **Recursive sanitization**: Processes nested structures (arrays, groups, blocks, localized fields)
|
|
17
|
+
* to ensure deep data integrity
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Unlike MongoDB's adapter which uses Mongoose schemas with `strict: true` (rejecting extra fields
|
|
21
|
+
* on write), Content API uses flexible JSONB storage that accepts any fields. Therefore, this
|
|
22
|
+
* function is called on **both read and write operations** to ensure data consistency.
|
|
23
|
+
*
|
|
24
|
+
* The MongoDB adapter also supports an `allowAdditionalKeys` option that allows reading/writing
|
|
25
|
+
* fields not in the schema. For now, Content API does not support this feature - we always
|
|
26
|
+
* sanitize data. If users request this functionality in the future, we can consider adding it.
|
|
27
|
+
*
|
|
28
|
+
* @todo
|
|
29
|
+
* 1. Consider moving this utility to `payload/shared` so both MongoDB and Content API adapters
|
|
30
|
+
* can use the same implementation, reducing code duplication and maintenance burden.
|
|
31
|
+
*
|
|
32
|
+
* 2. Performance optimization: This function iterates through all fields recursively.
|
|
33
|
+
* The `dataToContentAPI` and `dataFromContentAPI` functions in
|
|
34
|
+
* `packages/figma/src/db-content-api/utilities/data.ts` also iterate through fields
|
|
35
|
+
* to transform richText (object ↔ JSON string), custom IDs (number ↔ string), and dates.
|
|
36
|
+
* Consider combining both traversals into a single abstraction to avoid iterating twice.
|
|
37
|
+
*
|
|
38
|
+
* 3. Feature parity: MongoDB adapter has `allowAdditionalKeys` option. We currently always
|
|
39
|
+
* strip additional keys, but could add this as a configurable option if users need it.
|
|
40
|
+
*/
|
|
41
|
+
export declare const stripFields: ({ config, data, fields, parentIsLocalized, reservedKeys, }: {
|
|
42
|
+
config: SanitizedConfig;
|
|
43
|
+
data: any;
|
|
44
|
+
fields: FlattenedField[];
|
|
45
|
+
parentIsLocalized?: boolean;
|
|
46
|
+
reservedKeys?: string[];
|
|
47
|
+
}) => void;
|
|
48
|
+
//# sourceMappingURL=stripFields.d.ts.map
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
import { fieldShouldBeLocalized } from 'payload/shared';
|
|
2
|
+
/**
|
|
3
|
+
* Strips fields from data that are not defined in the schema or are invalid.
|
|
4
|
+
*
|
|
5
|
+
* This function was copied from the MongoDB adapter's implementation:
|
|
6
|
+
* @see packages/db-mongodb/src/utilities/transform.ts (stripFields function)
|
|
7
|
+
*
|
|
8
|
+
* @description
|
|
9
|
+
* This utility performs deep sanitization of document data by:
|
|
10
|
+
* 1. **Removing undefined fields**: Strips any field not present in the collection's schema
|
|
11
|
+
* (e.g., sensitive fields like `password`, `apiKey`, or any extra fields not in config)
|
|
12
|
+
* 2. **Removing invalid locales**: Deletes locale keys that don't exist in `config.localization.localeCodes`
|
|
13
|
+
* (e.g., if data contains `{ "es-MX": "..." }` but only `"en"` is configured)
|
|
14
|
+
* 3. **Removing invalid blocks**: Filters out blocks with unknown `blockType` values
|
|
15
|
+
* (prevents data corruption from blocks that don't exist in the schema)
|
|
16
|
+
* 4. **Recursive sanitization**: Processes nested structures (arrays, groups, blocks, localized fields)
|
|
17
|
+
* to ensure deep data integrity
|
|
18
|
+
*
|
|
19
|
+
* @remarks
|
|
20
|
+
* Unlike MongoDB's adapter which uses Mongoose schemas with `strict: true` (rejecting extra fields
|
|
21
|
+
* on write), Content API uses flexible JSONB storage that accepts any fields. Therefore, this
|
|
22
|
+
* function is called on **both read and write operations** to ensure data consistency.
|
|
23
|
+
*
|
|
24
|
+
* The MongoDB adapter also supports an `allowAdditionalKeys` option that allows reading/writing
|
|
25
|
+
* fields not in the schema. For now, Content API does not support this feature - we always
|
|
26
|
+
* sanitize data. If users request this functionality in the future, we can consider adding it.
|
|
27
|
+
*
|
|
28
|
+
* @todo
|
|
29
|
+
* 1. Consider moving this utility to `payload/shared` so both MongoDB and Content API adapters
|
|
30
|
+
* can use the same implementation, reducing code duplication and maintenance burden.
|
|
31
|
+
*
|
|
32
|
+
* 2. Performance optimization: This function iterates through all fields recursively.
|
|
33
|
+
* The `dataToContentAPI` and `dataFromContentAPI` functions in
|
|
34
|
+
* `packages/figma/src/db-content-api/utilities/data.ts` also iterate through fields
|
|
35
|
+
* to transform richText (object ↔ JSON string), custom IDs (number ↔ string), and dates.
|
|
36
|
+
* Consider combining both traversals into a single abstraction to avoid iterating twice.
|
|
37
|
+
*
|
|
38
|
+
* 3. Feature parity: MongoDB adapter has `allowAdditionalKeys` option. We currently always
|
|
39
|
+
* strip additional keys, but could add this as a configurable option if users need it.
|
|
40
|
+
*/ export const stripFields = ({ config, data, fields, parentIsLocalized = false, reservedKeys = [] })=>{
|
|
41
|
+
for(const k in data){
|
|
42
|
+
if (!fields.some((field)=>field.name === k) && !reservedKeys.includes(k)) {
|
|
43
|
+
delete data[k];
|
|
44
|
+
}
|
|
45
|
+
}
|
|
46
|
+
for (const field of fields){
|
|
47
|
+
reservedKeys = [];
|
|
48
|
+
const fieldData = data[field.name];
|
|
49
|
+
if (!fieldData || typeof fieldData !== 'object') {
|
|
50
|
+
continue;
|
|
51
|
+
}
|
|
52
|
+
const shouldLocalizeField = fieldShouldBeLocalized({
|
|
53
|
+
field,
|
|
54
|
+
parentIsLocalized
|
|
55
|
+
});
|
|
56
|
+
if (field.type === 'blocks') {
|
|
57
|
+
reservedKeys.push('blockType');
|
|
58
|
+
}
|
|
59
|
+
if ('flattenedFields' in field || 'blocks' in field) {
|
|
60
|
+
if (shouldLocalizeField && config.localization) {
|
|
61
|
+
for(const localeKey in fieldData){
|
|
62
|
+
if (!config.localization.localeCodes.some((code)=>code === localeKey)) {
|
|
63
|
+
delete fieldData[localeKey];
|
|
64
|
+
continue;
|
|
65
|
+
}
|
|
66
|
+
const localeData = fieldData[localeKey];
|
|
67
|
+
if (!localeData || typeof localeData !== 'object') {
|
|
68
|
+
continue;
|
|
69
|
+
}
|
|
70
|
+
if (field.type === 'array' || field.type === 'blocks') {
|
|
71
|
+
if (!Array.isArray(localeData)) {
|
|
72
|
+
continue;
|
|
73
|
+
}
|
|
74
|
+
let hasNull = false;
|
|
75
|
+
for(let i = 0; i < localeData.length; i++){
|
|
76
|
+
const data = localeData[i];
|
|
77
|
+
let fields = null;
|
|
78
|
+
if (field.type === 'array') {
|
|
79
|
+
fields = field.flattenedFields;
|
|
80
|
+
} else {
|
|
81
|
+
let maybeBlock = undefined;
|
|
82
|
+
if (field.blockReferences) {
|
|
83
|
+
const maybeBlockReference = field.blockReferences.find((each)=>{
|
|
84
|
+
const slug = typeof each === 'string' ? each : each.slug;
|
|
85
|
+
return slug === data.blockType;
|
|
86
|
+
});
|
|
87
|
+
if (maybeBlockReference) {
|
|
88
|
+
if (typeof maybeBlockReference === 'object') {
|
|
89
|
+
maybeBlock = maybeBlockReference;
|
|
90
|
+
} else {
|
|
91
|
+
maybeBlock = config.blocks?.find((each)=>each.slug === maybeBlockReference);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
if (!maybeBlock) {
|
|
96
|
+
maybeBlock = field.blocks.find((each)=>each.slug === data.blockType);
|
|
97
|
+
}
|
|
98
|
+
if (maybeBlock) {
|
|
99
|
+
fields = maybeBlock.flattenedFields;
|
|
100
|
+
} else {
|
|
101
|
+
localeData[i] = null;
|
|
102
|
+
hasNull = true;
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
if (!fields) {
|
|
106
|
+
continue;
|
|
107
|
+
}
|
|
108
|
+
stripFields({
|
|
109
|
+
config,
|
|
110
|
+
data,
|
|
111
|
+
fields,
|
|
112
|
+
parentIsLocalized: parentIsLocalized || field.localized,
|
|
113
|
+
reservedKeys
|
|
114
|
+
});
|
|
115
|
+
}
|
|
116
|
+
if (hasNull) {
|
|
117
|
+
fieldData[localeKey] = localeData.filter(Boolean);
|
|
118
|
+
}
|
|
119
|
+
continue;
|
|
120
|
+
} else {
|
|
121
|
+
stripFields({
|
|
122
|
+
config,
|
|
123
|
+
data: localeData,
|
|
124
|
+
fields: field.flattenedFields,
|
|
125
|
+
parentIsLocalized: parentIsLocalized || field.localized,
|
|
126
|
+
reservedKeys
|
|
127
|
+
});
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
continue;
|
|
131
|
+
}
|
|
132
|
+
if (field.type === 'array' || field.type === 'blocks') {
|
|
133
|
+
if (!Array.isArray(fieldData)) {
|
|
134
|
+
continue;
|
|
135
|
+
}
|
|
136
|
+
let hasNull = false;
|
|
137
|
+
for(let i = 0; i < fieldData.length; i++){
|
|
138
|
+
const data = fieldData[i];
|
|
139
|
+
let fields = null;
|
|
140
|
+
if (field.type === 'array') {
|
|
141
|
+
fields = field.flattenedFields;
|
|
142
|
+
} else {
|
|
143
|
+
let maybeBlock = undefined;
|
|
144
|
+
if (field.blockReferences) {
|
|
145
|
+
const maybeBlockReference = field.blockReferences.find((each)=>{
|
|
146
|
+
const slug = typeof each === 'string' ? each : each.slug;
|
|
147
|
+
return slug === data.blockType;
|
|
148
|
+
});
|
|
149
|
+
if (maybeBlockReference) {
|
|
150
|
+
if (typeof maybeBlockReference === 'object') {
|
|
151
|
+
maybeBlock = maybeBlockReference;
|
|
152
|
+
} else {
|
|
153
|
+
maybeBlock = config.blocks?.find((each)=>each.slug === maybeBlockReference);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
if (!maybeBlock) {
|
|
158
|
+
maybeBlock = field.blocks.find((each)=>each.slug === data.blockType);
|
|
159
|
+
}
|
|
160
|
+
if (maybeBlock) {
|
|
161
|
+
fields = maybeBlock.flattenedFields;
|
|
162
|
+
} else {
|
|
163
|
+
fieldData[i] = null;
|
|
164
|
+
hasNull = true;
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (!fields) {
|
|
168
|
+
continue;
|
|
169
|
+
}
|
|
170
|
+
stripFields({
|
|
171
|
+
config,
|
|
172
|
+
data,
|
|
173
|
+
fields,
|
|
174
|
+
parentIsLocalized: parentIsLocalized || field.localized,
|
|
175
|
+
reservedKeys
|
|
176
|
+
});
|
|
177
|
+
}
|
|
178
|
+
if (hasNull) {
|
|
179
|
+
data[field.name] = fieldData.filter(Boolean);
|
|
180
|
+
}
|
|
181
|
+
continue;
|
|
182
|
+
} else {
|
|
183
|
+
stripFields({
|
|
184
|
+
config,
|
|
185
|
+
data: fieldData,
|
|
186
|
+
fields: field.flattenedFields,
|
|
187
|
+
parentIsLocalized: parentIsLocalized || field.localized,
|
|
188
|
+
reservedKeys
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
};
|
|
194
|
+
|
|
195
|
+
//# sourceMappingURL=stripFields.js.map
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform publishedLocale to localizeStatus format
|
|
3
|
+
*
|
|
4
|
+
* publishedLocale is a legacy API that is going to be removed in Payload v4 in favor of localizeStatus.
|
|
5
|
+
* The db-adapter transforms publishedLocale here so Content API doesn't need to know about it.
|
|
6
|
+
*/
|
|
7
|
+
type VersionData = Record<string, unknown>;
|
|
8
|
+
/**
|
|
9
|
+
* Transforms version data to use localizeStatus format
|
|
10
|
+
*
|
|
11
|
+
* If `publishedLocale` is provided and `_status` is a string, transforms to object format.
|
|
12
|
+
* If `_status` is already an object, leaves it unchanged.
|
|
13
|
+
*
|
|
14
|
+
* @example
|
|
15
|
+
* // Input (old format):
|
|
16
|
+
* { _status: 'published', text: 'Hello' }, publishedLocale: 'en'
|
|
17
|
+
*
|
|
18
|
+
* // Output (new format):
|
|
19
|
+
* { _status: { en: 'published' }, text: 'Hello' }
|
|
20
|
+
*/
|
|
21
|
+
export declare function transformToLocalizeStatus(versionData: VersionData, publishedLocale?: string): VersionData;
|
|
22
|
+
export {};
|
|
23
|
+
//# sourceMappingURL=transformPublishedLocale.d.ts.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Transform publishedLocale to localizeStatus format
|
|
3
|
+
*
|
|
4
|
+
* publishedLocale is a legacy API that is going to be removed in Payload v4 in favor of localizeStatus.
|
|
5
|
+
* The db-adapter transforms publishedLocale here so Content API doesn't need to know about it.
|
|
6
|
+
*/ /**
|
|
7
|
+
* Transforms version data to use localizeStatus format
|
|
8
|
+
*
|
|
9
|
+
* If `publishedLocale` is provided and `_status` is a string, transforms to object format.
|
|
10
|
+
* If `_status` is already an object, leaves it unchanged.
|
|
11
|
+
*
|
|
12
|
+
* @example
|
|
13
|
+
* // Input (old format):
|
|
14
|
+
* { _status: 'published', text: 'Hello' }, publishedLocale: 'en'
|
|
15
|
+
*
|
|
16
|
+
* // Output (new format):
|
|
17
|
+
* { _status: { en: 'published' }, text: 'Hello' }
|
|
18
|
+
*/ export function transformToLocalizeStatus(versionData, publishedLocale) {
|
|
19
|
+
// No publishedLocale provided - no transformation needed
|
|
20
|
+
if (!publishedLocale) {
|
|
21
|
+
return versionData;
|
|
22
|
+
}
|
|
23
|
+
const status = versionData._status;
|
|
24
|
+
// If _status is already an object (localizeStatus format), return as-is
|
|
25
|
+
if (typeof status === 'object' && status !== null) {
|
|
26
|
+
return versionData;
|
|
27
|
+
}
|
|
28
|
+
// Transform: publishedLocale + string status → object status
|
|
29
|
+
if (typeof status === 'string') {
|
|
30
|
+
// Only the specified locale gets the status, others remain undefined
|
|
31
|
+
// (Content API / Payload will handle merging with existing locale statuses)
|
|
32
|
+
return {
|
|
33
|
+
...versionData,
|
|
34
|
+
_status: {
|
|
35
|
+
[publishedLocale]: status
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
return versionData;
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
//# sourceMappingURL=transformPublishedLocale.js.map
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import type { JoinQuery, Payload } from 'payload';
|
|
2
|
+
import type { components } from '../generated/content-api-types.js';
|
|
3
|
+
type ContentAPIJoin = components['schemas']['JoinClause'][number];
|
|
4
|
+
/**
|
|
5
|
+
* Convert Payload's JoinQuery to Content API's join format.
|
|
6
|
+
*
|
|
7
|
+
* ## Content API Join Limitations
|
|
8
|
+
*
|
|
9
|
+
* The following Payload join features are NOT YET supported by Content API:
|
|
10
|
+
*
|
|
11
|
+
* 1. **hasMany relationships** - Content API's join uses `data#>'{path}'#>>'{}'` to extract
|
|
12
|
+
* a single ID. HasMany relationships store arrays `["id1", "id2"]` which can't match.
|
|
13
|
+
*
|
|
14
|
+
* 2. **Array field relationships** - `on: 'array.category'` expects iteration over array
|
|
15
|
+
* elements, but Content API treats the path as a single JSONB extraction.
|
|
16
|
+
*
|
|
17
|
+
* 3. **Polymorphic relationships** - Stored as `{ relationTo, value }` objects, but
|
|
18
|
+
* Content API expects a simple ID string.
|
|
19
|
+
*
|
|
20
|
+
* 4. **Localized relationship fields** - Locale-aware joins not implemented.
|
|
21
|
+
*
|
|
22
|
+
* Note: "Where querying through joins" (e.g., `where: { 'relatedPosts.title': { equals: 'x' } }`)
|
|
23
|
+
* is a separate Payload feature that filters documents based on joined data. This is NOT
|
|
24
|
+
* a join feature but a where clause feature, and would need separate Content API support.
|
|
25
|
+
*
|
|
26
|
+
* Payload's JoinQuery format (at runtime):
|
|
27
|
+
* {
|
|
28
|
+
* 'group.relatedPosts': { // joinPath - where results go in the document
|
|
29
|
+
* sort: '-title',
|
|
30
|
+
* limit: 10,
|
|
31
|
+
* page: 2, // page-based pagination
|
|
32
|
+
* where: { ... }, // Payload where format
|
|
33
|
+
* count: true
|
|
34
|
+
* }
|
|
35
|
+
* }
|
|
36
|
+
*
|
|
37
|
+
* Content API's join format:
|
|
38
|
+
* [{
|
|
39
|
+
* collectionId: 'posts', // collection to join FROM
|
|
40
|
+
* on: 'group.category', // field in joined collection pointing to this doc
|
|
41
|
+
* path: 'group.relatedPosts', // where to put results
|
|
42
|
+
* count: false,
|
|
43
|
+
* where: { ... }, // Content API where format
|
|
44
|
+
* sort: '-title',
|
|
45
|
+
* limit: 10,
|
|
46
|
+
* offset: 10 // offset-based pagination
|
|
47
|
+
* }]
|
|
48
|
+
*
|
|
49
|
+
* The mapping requires the collection config to resolve:
|
|
50
|
+
* - Which collection each join field refers to
|
|
51
|
+
* - What the 'on' field is for each join
|
|
52
|
+
*/
|
|
53
|
+
export declare function convertPayloadJoinsToContentAPI(payload: Payload, collectionSlug: string, joins: false | JoinQuery | undefined): ContentAPIJoin[] | undefined;
|
|
54
|
+
export {};
|
|
55
|
+
//# sourceMappingURL=joins.d.ts.map
|