@payloadcms/figma 0.1.0-alpha.1 → 0.1.0-alpha.3
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 +1 -1
- package/dist/api/control-plane.js +1 -1
- package/dist/cli.d.ts +30 -0
- package/dist/cli.js +33 -33
- package/dist/commands/deploy.d.ts +2 -0
- package/dist/commands/deploy.js +22 -12
- package/dist/db-content-api/index.d.ts +1 -1
- package/dist/db-content-api/index.js +70 -40
- package/dist/db-content-api/utilities/schema/getDocumentSchema.d.ts +3 -0
- package/dist/db-content-api/utilities/schema/getDocumentSchema.js +24 -0
- package/dist/exports/client.d.ts +2 -0
- package/dist/exports/client.js +2 -0
- package/dist/plugin/build-config.js +39 -4
- package/dist/plugin/cloud-limits/CloudLimitModal/index.d.ts +9 -0
- package/dist/plugin/cloud-limits/CloudLimitModal/index.js +78 -0
- package/dist/plugin/cloud-limits/CloudLimitModal/index.scss +51 -0
- package/dist/plugin/cloud-limits/CloudLimitProvider/index.d.ts +7 -0
- package/dist/plugin/cloud-limits/CloudLimitProvider/index.js +169 -0
- package/dist/plugin/cloud-limits/SlugRegistryContext/index.d.ts +2 -0
- package/dist/plugin/cloud-limits/SlugRegistryContext/index.js +3 -0
- package/dist/plugin/cloud-limits/SlugTracker/index.d.ts +9 -0
- package/dist/plugin/cloud-limits/SlugTracker/index.js +23 -0
- package/dist/plugin/cloud-limits/icons/ExternalLinkIcon.d.ts +2 -0
- package/dist/plugin/cloud-limits/icons/ExternalLinkIcon.js +30 -0
- package/dist/plugin/cloud-limits/shared.d.ts +10 -0
- package/dist/plugin/cloud-limits/shared.js +27 -0
- package/dist/plugin/sandbox-upload-fetch.d.ts +32 -0
- package/dist/plugin/sandbox-upload-fetch.js +53 -0
- package/dist/translations/ar.d.ts +12 -0
- package/dist/translations/ar.js +12 -0
- package/dist/translations/az.d.ts +12 -0
- package/dist/translations/az.js +12 -0
- package/dist/translations/bg.d.ts +12 -0
- package/dist/translations/bg.js +12 -0
- package/dist/translations/bnBd.d.ts +12 -0
- package/dist/translations/bnBd.js +12 -0
- package/dist/translations/bnIn.d.ts +12 -0
- package/dist/translations/bnIn.js +12 -0
- package/dist/translations/ca.d.ts +12 -0
- package/dist/translations/ca.js +12 -0
- package/dist/translations/cs.d.ts +12 -0
- package/dist/translations/cs.js +12 -0
- package/dist/translations/da.d.ts +12 -0
- package/dist/translations/da.js +12 -0
- package/dist/translations/de.d.ts +12 -0
- package/dist/translations/de.js +12 -0
- package/dist/translations/en.d.ts +12 -0
- package/dist/translations/en.js +12 -0
- package/dist/translations/es.d.ts +12 -0
- package/dist/translations/es.js +12 -0
- package/dist/translations/et.d.ts +12 -0
- package/dist/translations/et.js +12 -0
- package/dist/translations/fa.d.ts +12 -0
- package/dist/translations/fa.js +12 -0
- package/dist/translations/fr.d.ts +12 -0
- package/dist/translations/fr.js +12 -0
- package/dist/translations/he.d.ts +12 -0
- package/dist/translations/he.js +12 -0
- package/dist/translations/hr.d.ts +12 -0
- package/dist/translations/hr.js +12 -0
- package/dist/translations/hu.d.ts +12 -0
- package/dist/translations/hu.js +12 -0
- package/dist/translations/hy.d.ts +12 -0
- package/dist/translations/hy.js +12 -0
- package/dist/translations/id.d.ts +12 -0
- package/dist/translations/id.js +12 -0
- package/dist/translations/index.d.ts +533 -0
- package/dist/translations/index.js +90 -0
- package/dist/translations/is.d.ts +12 -0
- package/dist/translations/is.js +12 -0
- package/dist/translations/it.d.ts +12 -0
- package/dist/translations/it.js +12 -0
- package/dist/translations/ja.d.ts +12 -0
- package/dist/translations/ja.js +12 -0
- package/dist/translations/ko.d.ts +12 -0
- package/dist/translations/ko.js +12 -0
- package/dist/translations/lt.d.ts +12 -0
- package/dist/translations/lt.js +12 -0
- package/dist/translations/lv.d.ts +12 -0
- package/dist/translations/lv.js +12 -0
- package/dist/translations/my.d.ts +12 -0
- package/dist/translations/my.js +12 -0
- package/dist/translations/nb.d.ts +12 -0
- package/dist/translations/nb.js +12 -0
- package/dist/translations/nl.d.ts +12 -0
- package/dist/translations/nl.js +12 -0
- package/dist/translations/pl.d.ts +12 -0
- package/dist/translations/pl.js +12 -0
- package/dist/translations/pt.d.ts +12 -0
- package/dist/translations/pt.js +12 -0
- package/dist/translations/ro.d.ts +12 -0
- package/dist/translations/ro.js +12 -0
- package/dist/translations/rs.d.ts +12 -0
- package/dist/translations/rs.js +12 -0
- package/dist/translations/rsLatin.d.ts +12 -0
- package/dist/translations/rsLatin.js +12 -0
- package/dist/translations/ru.d.ts +12 -0
- package/dist/translations/ru.js +12 -0
- package/dist/translations/sk.d.ts +12 -0
- package/dist/translations/sk.js +12 -0
- package/dist/translations/sl.d.ts +12 -0
- package/dist/translations/sl.js +12 -0
- package/dist/translations/sv.d.ts +12 -0
- package/dist/translations/sv.js +12 -0
- package/dist/translations/ta.d.ts +12 -0
- package/dist/translations/ta.js +12 -0
- package/dist/translations/th.d.ts +12 -0
- package/dist/translations/th.js +12 -0
- package/dist/translations/tr.d.ts +12 -0
- package/dist/translations/tr.js +12 -0
- package/dist/translations/uk.d.ts +12 -0
- package/dist/translations/uk.js +12 -0
- package/dist/translations/vi.d.ts +12 -0
- package/dist/translations/vi.js +12 -0
- package/dist/translations/zh.d.ts +12 -0
- package/dist/translations/zh.js +12 -0
- package/dist/translations/zhTw.d.ts +12 -0
- package/dist/translations/zhTw.js +12 -0
- package/dist/types.d.ts +2 -0
- package/dist/utils/adapters/nextjs.d.ts +3 -3
- package/dist/utils/adapters/nextjs.js +9 -7
- package/dist/utils/adapters/nitro.d.ts +3 -3
- package/dist/utils/adapters/nitro.js +73 -77
- package/dist/utils/adapters/vite.d.ts +1 -1
- package/dist/utils/adapters/vite.js +8 -7
- package/dist/utils/assert-never.d.ts +1 -0
- package/dist/utils/assert-never.js +3 -0
- package/dist/utils/asset-collection.d.ts +2 -2
- package/dist/utils/asset-collection.js +10 -15
- package/dist/utils/build-detection.d.ts +6 -1
- package/dist/utils/build-detection.js +68 -89
- package/dist/utils/build-lambda-zip.d.ts +5 -6
- package/dist/utils/build-lambda-zip.js +31 -48
- package/dist/utils/deploy-adapter.d.ts +4 -4
- package/dist/utils/deploy-adapter.js +12 -8
- package/dist/utils/deploy-output/inspectNextjsOutput/getNextRelativeAppDir.d.ts +1 -0
- package/dist/utils/deploy-output/inspectNextjsOutput/getNextRelativeAppDir.js +15 -0
- package/dist/utils/deploy-output/inspectNextjsOutput.d.ts +12 -0
- package/dist/utils/deploy-output/inspectNextjsOutput.js +28 -0
- package/dist/utils/deploy-output/inspectNitroOutput.d.ts +9 -0
- package/dist/utils/deploy-output/inspectNitroOutput.js +13 -0
- package/dist/utils/deploy-output/isFile.d.ts +1 -0
- package/dist/utils/deploy-output/isFile.js +4 -0
- package/dist/utils/deploy-output/readJson.d.ts +1 -0
- package/dist/utils/deploy-output/readJson.js +9 -0
- package/dist/utils/deploy-output/resolveNitroOutputLayout.d.ts +8 -0
- package/dist/utils/deploy-output/resolveNitroOutputLayout.js +16 -0
- package/dist/utils/deploy-output/resolveOutputPath.d.ts +2 -0
- package/dist/utils/deploy-output/resolveOutputPath.js +9 -0
- package/dist/utils/deploy-output/resolveWithin.d.ts +1 -0
- package/dist/utils/deploy-output/resolveWithin.js +12 -0
- package/dist/utils/messages.js +2 -0
- package/package.json +6 -5
|
@@ -77,7 +77,7 @@ export interface PerformDeploymentResponse {
|
|
|
77
77
|
deploymentId: string;
|
|
78
78
|
/** Status message */
|
|
79
79
|
message: string;
|
|
80
|
-
/**
|
|
80
|
+
/** SiteDomain hostnames returned through the compatibility tenant_domains key */
|
|
81
81
|
tenantDomains: string[];
|
|
82
82
|
}
|
|
83
83
|
export interface PerformDeploymentApiResponse {
|
package/dist/cli.d.ts
CHANGED
|
@@ -1,3 +1,33 @@
|
|
|
1
|
+
export declare const cliArgSpec: {
|
|
2
|
+
readonly '--adapter': StringConstructor;
|
|
3
|
+
readonly '--all': BooleanConstructor;
|
|
4
|
+
readonly '--debug': BooleanConstructor;
|
|
5
|
+
readonly '--dry-run': BooleanConstructor;
|
|
6
|
+
readonly '--env': StringConstructor;
|
|
7
|
+
readonly '--force': BooleanConstructor;
|
|
8
|
+
readonly '--help': BooleanConstructor;
|
|
9
|
+
readonly '--id': StringConstructor;
|
|
10
|
+
readonly '--infra-env': StringConstructor;
|
|
11
|
+
readonly '--json': BooleanConstructor;
|
|
12
|
+
readonly '--name': StringConstructor;
|
|
13
|
+
readonly '--no-skill': BooleanConstructor;
|
|
14
|
+
readonly '--output': StringConstructor;
|
|
15
|
+
readonly '--payload-version': StringConstructor;
|
|
16
|
+
readonly '--skip-auth': BooleanConstructor;
|
|
17
|
+
readonly '--skip-build': BooleanConstructor;
|
|
18
|
+
readonly '--skip-size-check': BooleanConstructor;
|
|
19
|
+
readonly '--template': StringConstructor;
|
|
20
|
+
readonly '--version': BooleanConstructor;
|
|
21
|
+
readonly '--yes': BooleanConstructor;
|
|
22
|
+
readonly '--environment': "--env";
|
|
23
|
+
readonly '-e': "--env";
|
|
24
|
+
readonly '-f': "--force";
|
|
25
|
+
readonly '-h': "--help";
|
|
26
|
+
readonly '-n': "--name";
|
|
27
|
+
readonly '-t': "--template";
|
|
28
|
+
readonly '-v': "--version";
|
|
29
|
+
readonly '-y': "--yes";
|
|
30
|
+
};
|
|
1
31
|
/**
|
|
2
32
|
* Entrypoint for bin/cli.js
|
|
3
33
|
*/
|
package/dist/cli.js
CHANGED
|
@@ -15,6 +15,37 @@ import { upgradeCommand } from './commands/upgrade.js';
|
|
|
15
15
|
import { uploadSchemaCommand } from './commands/upload-schema.js';
|
|
16
16
|
import { setInfraEnvironment } from './constants.js';
|
|
17
17
|
import { helpMessage } from './utils/messages.js';
|
|
18
|
+
export const cliArgSpec = {
|
|
19
|
+
'--adapter': String,
|
|
20
|
+
'--all': Boolean,
|
|
21
|
+
'--debug': Boolean,
|
|
22
|
+
'--dry-run': Boolean,
|
|
23
|
+
'--env': String,
|
|
24
|
+
'--force': Boolean,
|
|
25
|
+
'--help': Boolean,
|
|
26
|
+
'--id': String,
|
|
27
|
+
'--infra-env': String,
|
|
28
|
+
'--json': Boolean,
|
|
29
|
+
'--name': String,
|
|
30
|
+
'--no-skill': Boolean,
|
|
31
|
+
'--output': String,
|
|
32
|
+
'--payload-version': String,
|
|
33
|
+
'--skip-auth': Boolean,
|
|
34
|
+
'--skip-build': Boolean,
|
|
35
|
+
'--skip-size-check': Boolean,
|
|
36
|
+
'--template': String,
|
|
37
|
+
'--version': Boolean,
|
|
38
|
+
'--yes': Boolean,
|
|
39
|
+
// Aliases
|
|
40
|
+
'--environment': '--env',
|
|
41
|
+
'-e': '--env',
|
|
42
|
+
'-f': '--force',
|
|
43
|
+
'-h': '--help',
|
|
44
|
+
'-n': '--name',
|
|
45
|
+
'-t': '--template',
|
|
46
|
+
'-v': '--version',
|
|
47
|
+
'-y': '--yes'
|
|
48
|
+
};
|
|
18
49
|
/**
|
|
19
50
|
* Entrypoint for bin/cli.js
|
|
20
51
|
*/ export async function main() {
|
|
@@ -31,39 +62,7 @@ class Main {
|
|
|
31
62
|
args;
|
|
32
63
|
constructor(){
|
|
33
64
|
// @ts-expect-error bad typings
|
|
34
|
-
this.args = arg({
|
|
35
|
-
// Hidden flag — intentionally not displayed in help output yet.
|
|
36
|
-
// Auto-detection covers most cases; this is an escape hatch for testing.
|
|
37
|
-
// May expose in help text once multi-framework support is public.
|
|
38
|
-
'--adapter': String,
|
|
39
|
-
'--all': Boolean,
|
|
40
|
-
'--debug': Boolean,
|
|
41
|
-
'--dry-run': Boolean,
|
|
42
|
-
'--env': String,
|
|
43
|
-
'--force': Boolean,
|
|
44
|
-
'--help': Boolean,
|
|
45
|
-
'--id': String,
|
|
46
|
-
'--infra-env': String,
|
|
47
|
-
'--json': Boolean,
|
|
48
|
-
'--name': String,
|
|
49
|
-
'--no-skill': Boolean,
|
|
50
|
-
'--payload-version': String,
|
|
51
|
-
'--skip-auth': Boolean,
|
|
52
|
-
'--skip-build': Boolean,
|
|
53
|
-
'--skip-size-check': Boolean,
|
|
54
|
-
'--template': String,
|
|
55
|
-
'--version': Boolean,
|
|
56
|
-
'--yes': Boolean,
|
|
57
|
-
// Aliases
|
|
58
|
-
'--environment': '--env',
|
|
59
|
-
'-e': '--env',
|
|
60
|
-
'-f': '--force',
|
|
61
|
-
'-h': '--help',
|
|
62
|
-
'-n': '--name',
|
|
63
|
-
'-t': '--template',
|
|
64
|
-
'-v': '--version',
|
|
65
|
-
'-y': '--yes'
|
|
66
|
-
}, {
|
|
65
|
+
this.args = arg(cliArgSpec, {
|
|
67
66
|
permissive: true
|
|
68
67
|
});
|
|
69
68
|
// Set debug flag globally
|
|
@@ -136,6 +135,7 @@ class Main {
|
|
|
136
135
|
adapter: this.args['--adapter'],
|
|
137
136
|
debug: this.args['--debug'],
|
|
138
137
|
env: this.args['--env'],
|
|
138
|
+
output: this.args['--output'],
|
|
139
139
|
skipBuild: this.args['--skip-build'],
|
|
140
140
|
skipSizeCheck: this.args['--skip-size-check'],
|
|
141
141
|
yes: this.args['--yes']
|
|
@@ -11,6 +11,8 @@ export interface DeployCommandOptions {
|
|
|
11
11
|
env?: string;
|
|
12
12
|
/** CMS Resource ID (overrides FIGMA_PROJECT_ID) */
|
|
13
13
|
id?: string;
|
|
14
|
+
/** Exact framework build output root */
|
|
15
|
+
output?: string;
|
|
14
16
|
/** Skip the build step (use existing build) */
|
|
15
17
|
skipBuild?: boolean;
|
|
16
18
|
/** Skip the client-side unzipped bundle size pre-flight check */
|
package/dist/commands/deploy.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as p from '@clack/prompts';
|
|
2
2
|
import spawn from 'cross-spawn';
|
|
3
|
+
import path from 'path';
|
|
3
4
|
import pc from 'picocolors';
|
|
4
5
|
import { ControlPlaneError, createDeployment, getBootstrapInfo, performDeployment } from '../api/control-plane.js';
|
|
5
6
|
import { tryGetCredential } from '../auth/oauth-flow.js';
|
|
@@ -64,10 +65,10 @@ import { loginCommand } from './login.js';
|
|
|
64
65
|
const environmentName = options.env ?? await getEnvVar(projectPath, 'FIGMA_ENVIRONMENT_NAME') ?? undefined;
|
|
65
66
|
try {
|
|
66
67
|
// ===== PRE-FLIGHT CHECKS =====
|
|
67
|
-
//
|
|
68
|
-
if (!await isInProjectDirectory(projectPath)) {
|
|
69
|
-
p.log.error(pc.red(
|
|
70
|
-
p.note('
|
|
68
|
+
// Building requires package.json, but --skip-build can deploy a prebuilt artifact directly.
|
|
69
|
+
if (!options.skipBuild && !await isInProjectDirectory(projectPath)) {
|
|
70
|
+
p.log.error(pc.red('✗ Cannot build because package.json was not found in this directory.'));
|
|
71
|
+
p.note('Run from a package directory, or deploy prebuilt output with --skip-build --output <path>.', 'Tip');
|
|
71
72
|
process.exit(1);
|
|
72
73
|
}
|
|
73
74
|
// Check authentication
|
|
@@ -110,13 +111,18 @@ import { loginCommand } from './login.js';
|
|
|
110
111
|
process.env.FIGMA_EXTRACT_SCHEDULES = 'true';
|
|
111
112
|
// ===== BUILD =====
|
|
112
113
|
let buildInfo;
|
|
114
|
+
const buildOptions = {
|
|
115
|
+
adapter: options.adapter,
|
|
116
|
+
output: options.output
|
|
117
|
+
};
|
|
113
118
|
if (options.skipBuild) {
|
|
114
119
|
// User asserts build exists - verify it
|
|
115
120
|
spinner.start('Checking for build...');
|
|
116
|
-
buildInfo = await detectBuild(projectPath);
|
|
121
|
+
buildInfo = await detectBuild(projectPath, buildOptions);
|
|
117
122
|
if (!buildInfo) {
|
|
118
123
|
spinner.stop(pc.red('✗ No build found'));
|
|
119
|
-
p.log.error(
|
|
124
|
+
p.log.error(getMissingBuildMessage(projectPath, options));
|
|
125
|
+
p.note('Use deploy without --skip-build to build first.', 'Tip');
|
|
120
126
|
process.exit(1);
|
|
121
127
|
}
|
|
122
128
|
spinner.stop(pc.green('✓ Build found'));
|
|
@@ -182,9 +188,9 @@ import { loginCommand } from './login.js';
|
|
|
182
188
|
process.exit(1);
|
|
183
189
|
}
|
|
184
190
|
// Verify build output
|
|
185
|
-
buildInfo = await detectBuild(projectPath);
|
|
191
|
+
buildInfo = await detectBuild(projectPath, buildOptions);
|
|
186
192
|
if (!buildInfo) {
|
|
187
|
-
p.log.error(pc.red(
|
|
193
|
+
p.log.error(pc.red(`✗ ${getMissingBuildMessage(projectPath, options)}`));
|
|
188
194
|
p.note('Ensure your build produces a valid output directory.', 'Check Build Configuration');
|
|
189
195
|
process.exit(1);
|
|
190
196
|
}
|
|
@@ -192,12 +198,12 @@ import { loginCommand } from './login.js';
|
|
|
192
198
|
// ===== DEPLOYMENT PREPARATION =====
|
|
193
199
|
// Detect framework adapter
|
|
194
200
|
spinner.start('Detecting framework...');
|
|
195
|
-
const adapter = await detectAdapter(projectPath, options.adapter);
|
|
201
|
+
const adapter = await detectAdapter(projectPath, options.adapter, options.output);
|
|
196
202
|
spinner.stop(pc.green(`✓ Detected ${adapter.name} adapter`));
|
|
197
203
|
// Collect pages and assets
|
|
198
204
|
spinner.start('Collecting assets...');
|
|
199
|
-
const pages = await adapter.collectPages(projectPath);
|
|
200
|
-
const assets = await adapter.collectAssets(projectPath);
|
|
205
|
+
const pages = await adapter.collectPages(projectPath, options.output);
|
|
206
|
+
const assets = await adapter.collectAssets(projectPath, options.output);
|
|
201
207
|
spinner.stop(pc.green(`✓ ${pages.routes.length} pages, ${assets.routes.length} assets detected`));
|
|
202
208
|
// Create deployment package (if server adapter)
|
|
203
209
|
let zipPath = null;
|
|
@@ -205,7 +211,7 @@ import { loginCommand } from './login.js';
|
|
|
205
211
|
let unzippedBytes = 0;
|
|
206
212
|
spinner.start('Creating deployment package...');
|
|
207
213
|
try {
|
|
208
|
-
const bundle = await adapter.prepareLambdaBundle(projectPath);
|
|
214
|
+
const bundle = await adapter.prepareLambdaBundle(projectPath, options.output);
|
|
209
215
|
if (bundle) {
|
|
210
216
|
zipPath = bundle.zipPath;
|
|
211
217
|
unzippedBytes = bundle.unzippedBytes;
|
|
@@ -342,3 +348,7 @@ import { loginCommand } from './login.js';
|
|
|
342
348
|
process.exit(1);
|
|
343
349
|
}
|
|
344
350
|
}
|
|
351
|
+
function getMissingBuildMessage(projectPath, options) {
|
|
352
|
+
const location = options.output ? ` at ${path.resolve(projectPath, options.output)}` : '';
|
|
353
|
+
return options.adapter ? `No ${options.adapter} build found${location}.` : `No supported build found${location}.`;
|
|
354
|
+
}
|
|
@@ -29,7 +29,7 @@ export type ContentAPIAdapter = {
|
|
|
29
29
|
client: ReturnType<typeof createClient<paths>>;
|
|
30
30
|
clientVersionHeaders: Record<string, string>;
|
|
31
31
|
contentSystemId: string;
|
|
32
|
-
documentSchema: DocumentSchemaWire;
|
|
32
|
+
documentSchema: () => DocumentSchemaWire;
|
|
33
33
|
environmentName?: string;
|
|
34
34
|
idType: 'uuid';
|
|
35
35
|
notifyLocalJobQueue: boolean;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import createClient from 'openapi-fetch';
|
|
2
|
-
import { APIError, createDatabaseAdapter } from 'payload';
|
|
2
|
+
import { APIError, createDatabaseAdapter, ValidationError } from 'payload';
|
|
3
3
|
import { v4 as uuid } from 'uuid';
|
|
4
4
|
import { FigmaApiError } from '../api/figma-api.js';
|
|
5
5
|
import { CONTENT_SYSTEM_NOT_FOUND_MESSAGE } from '../constants.js';
|
|
@@ -13,7 +13,7 @@ import { validateRelationshipIds } from './utilities/data/validateRelationships.
|
|
|
13
13
|
import { convertPayloadJoinsToContentAPI } from './utilities/joins.js';
|
|
14
14
|
import { addFallbackLocale } from './utilities/locale/index.js';
|
|
15
15
|
import { normalizeLocaleInWhere } from './utilities/meta/normalizeLocaleInWhere.js';
|
|
16
|
-
import {
|
|
16
|
+
import { getDocumentSchema } from './utilities/schema/getDocumentSchema.js';
|
|
17
17
|
import { convertPayloadWhereToContentAPI } from './utilities/where.js';
|
|
18
18
|
/**
|
|
19
19
|
* Heads-up logged locally whenever a job is queued. Queued jobs are executed by Figma's deployed runner, so
|
|
@@ -109,7 +109,7 @@ async function createCollection(collectionId) {
|
|
|
109
109
|
}
|
|
110
110
|
});
|
|
111
111
|
if (error) {
|
|
112
|
-
throw
|
|
112
|
+
throw createDocumentContentAPIError(this, 'createCollection', error, httpResponse.status, collectionId);
|
|
113
113
|
}
|
|
114
114
|
this.payload.logger.info(`Created collection: ${collectionId}`);
|
|
115
115
|
} catch (error) {
|
|
@@ -131,13 +131,13 @@ async function findMany({ collection, joins, limit, locale: localeArg, page, pag
|
|
|
131
131
|
limit,
|
|
132
132
|
locale,
|
|
133
133
|
page: page ?? 1,
|
|
134
|
-
schema: this.documentSchema,
|
|
134
|
+
schema: this.documentSchema(),
|
|
135
135
|
sort: addFallbackSort(sort, this.payload, collection),
|
|
136
136
|
where: convertPayloadWhereToContentAPI(normalizedWhere ?? {})
|
|
137
137
|
}
|
|
138
138
|
});
|
|
139
139
|
if (error) {
|
|
140
|
-
throw
|
|
140
|
+
throw createDocumentContentAPIError(this, 'findMany', error, httpResponse.status, collection);
|
|
141
141
|
}
|
|
142
142
|
if (!response) {
|
|
143
143
|
throw new Error('No response from findMany');
|
|
@@ -176,13 +176,13 @@ async function findVersions(args) {
|
|
|
176
176
|
limit: args.limit,
|
|
177
177
|
locale,
|
|
178
178
|
page: args.page ?? 1,
|
|
179
|
-
schema: this.documentSchema,
|
|
179
|
+
schema: this.documentSchema(),
|
|
180
180
|
sort: sortWithFallback,
|
|
181
181
|
where: whereClause
|
|
182
182
|
}
|
|
183
183
|
});
|
|
184
184
|
if (error) {
|
|
185
|
-
throw
|
|
185
|
+
throw createDocumentContentAPIError(this, 'findVersions', error, httpResponse.status, args.collection);
|
|
186
186
|
}
|
|
187
187
|
if (!response) {
|
|
188
188
|
throw new Error('No response from findVersions');
|
|
@@ -230,7 +230,7 @@ async function createVersion(args) {
|
|
|
230
230
|
body: {
|
|
231
231
|
collection: args.collectionSlug,
|
|
232
232
|
contentSystemId: this.contentSystemId,
|
|
233
|
-
schema: this.documentSchema,
|
|
233
|
+
schema: this.documentSchema(),
|
|
234
234
|
versionDoc: {
|
|
235
235
|
createdAt: args.createdAt,
|
|
236
236
|
latest: true,
|
|
@@ -241,7 +241,7 @@ async function createVersion(args) {
|
|
|
241
241
|
}
|
|
242
242
|
});
|
|
243
243
|
if (error) {
|
|
244
|
-
throw
|
|
244
|
+
throw createDocumentContentAPIError(this, 'createVersion', error, httpResponse.status, args.collectionSlug);
|
|
245
245
|
}
|
|
246
246
|
if (!response) {
|
|
247
247
|
throw new Error('No response from createVersion');
|
|
@@ -272,7 +272,7 @@ async function updateVersion(args) {
|
|
|
272
272
|
contentSystemId: this.contentSystemId,
|
|
273
273
|
createOnMissing: false,
|
|
274
274
|
locale,
|
|
275
|
-
schema: this.documentSchema,
|
|
275
|
+
schema: this.documentSchema(),
|
|
276
276
|
versionDoc: {
|
|
277
277
|
createdAt: versionMeta.createdAt,
|
|
278
278
|
latest: versionMeta.latest,
|
|
@@ -284,7 +284,7 @@ async function updateVersion(args) {
|
|
|
284
284
|
}
|
|
285
285
|
});
|
|
286
286
|
if (error) {
|
|
287
|
-
throw
|
|
287
|
+
throw createDocumentContentAPIError(this, 'updateVersion', error, httpResponse.status, args.collection);
|
|
288
288
|
}
|
|
289
289
|
if (!response?.result || !('data' in response.result)) {
|
|
290
290
|
throw new Error('No document data in updateVersion response');
|
|
@@ -301,21 +301,22 @@ async function updateVersion(args) {
|
|
|
301
301
|
});
|
|
302
302
|
}
|
|
303
303
|
async function deleteVersions(args) {
|
|
304
|
-
|
|
304
|
+
const collection = args.collection;
|
|
305
|
+
if (collection == null) {
|
|
305
306
|
throw new Error('deleteVersions requires a collection');
|
|
306
307
|
}
|
|
307
308
|
const locale = addFallbackLocale(args.locale, this.payload);
|
|
308
309
|
const { error, response: httpResponse } = await this.client.POST('/api/v1/document_versions:delete', {
|
|
309
310
|
body: {
|
|
310
|
-
collection
|
|
311
|
+
collection,
|
|
311
312
|
contentSystemId: this.contentSystemId,
|
|
312
313
|
locale,
|
|
313
|
-
schema: this.documentSchema,
|
|
314
|
+
schema: this.documentSchema(),
|
|
314
315
|
where: convertPayloadWhereToContentAPI(args.where)
|
|
315
316
|
}
|
|
316
317
|
});
|
|
317
318
|
if (error) {
|
|
318
|
-
throw
|
|
319
|
+
throw createDocumentContentAPIError(this, 'deleteVersions', error, httpResponse.status, collection);
|
|
319
320
|
}
|
|
320
321
|
}
|
|
321
322
|
async function findOne(args) {
|
|
@@ -339,13 +340,13 @@ async function findDistinct(args) {
|
|
|
339
340
|
limit: args.limit,
|
|
340
341
|
locale,
|
|
341
342
|
page: args.page ?? 1,
|
|
342
|
-
schema: this.documentSchema,
|
|
343
|
+
schema: this.documentSchema(),
|
|
343
344
|
sort: addFallbackSort(args.sort, this.payload, args.collection),
|
|
344
345
|
where: convertPayloadWhereToContentAPI(args.where ?? {})
|
|
345
346
|
}
|
|
346
347
|
});
|
|
347
348
|
if (error) {
|
|
348
|
-
throw
|
|
349
|
+
throw createDocumentContentAPIError(this, 'findDistinct', error, httpResponse.status, args.collection);
|
|
349
350
|
}
|
|
350
351
|
const { data, ...pagination } = response.result;
|
|
351
352
|
return {
|
|
@@ -372,13 +373,13 @@ async function updateMany(args) {
|
|
|
372
373
|
environmentName: this.environmentName,
|
|
373
374
|
limit: args.limit,
|
|
374
375
|
locale,
|
|
375
|
-
schema: this.documentSchema,
|
|
376
|
+
schema: this.documentSchema(),
|
|
376
377
|
sort: addFallbackSort(args.sort || '-updatedAt', this.payload, args.collection),
|
|
377
378
|
where: convertPayloadWhereToContentAPI(args.where)
|
|
378
379
|
}
|
|
379
380
|
});
|
|
380
381
|
if (error) {
|
|
381
|
-
throw
|
|
382
|
+
throw createDocumentContentAPIError(this, 'updateMany', error, httpResponse.status, args.collection);
|
|
382
383
|
}
|
|
383
384
|
if (!contentAPIResponse) {
|
|
384
385
|
throw new Error('No response from updateMany');
|
|
@@ -413,12 +414,12 @@ async function updateOne(args) {
|
|
|
413
414
|
doc: dataToContentAPI(this.payload, args.collection, args.data),
|
|
414
415
|
environmentName: this.environmentName,
|
|
415
416
|
locale,
|
|
416
|
-
schema: this.documentSchema,
|
|
417
|
+
schema: this.documentSchema(),
|
|
417
418
|
where: convertPayloadWhereToContentAPI(where)
|
|
418
419
|
}
|
|
419
420
|
});
|
|
420
421
|
if (error) {
|
|
421
|
-
throw
|
|
422
|
+
throw createDocumentContentAPIError(this, 'updateOne', error, httpResponse.status, args.collection);
|
|
422
423
|
}
|
|
423
424
|
if (!contentAPIResponse) {
|
|
424
425
|
throw new Error('No response from updateOne');
|
|
@@ -445,12 +446,12 @@ async function deleteMany(args) {
|
|
|
445
446
|
contentSystemId: this.contentSystemId,
|
|
446
447
|
environmentName: this.environmentName,
|
|
447
448
|
locale,
|
|
448
|
-
schema: this.documentSchema,
|
|
449
|
+
schema: this.documentSchema(),
|
|
449
450
|
where: convertPayloadWhereToContentAPI(args.where)
|
|
450
451
|
}
|
|
451
452
|
});
|
|
452
453
|
if (error) {
|
|
453
|
-
throw
|
|
454
|
+
throw createDocumentContentAPIError(this, 'deleteMany', error, httpResponse.status, args.collection);
|
|
454
455
|
}
|
|
455
456
|
}
|
|
456
457
|
async function deleteOne(args) {
|
|
@@ -461,12 +462,12 @@ async function deleteOne(args) {
|
|
|
461
462
|
contentSystemId: this.contentSystemId,
|
|
462
463
|
environmentName: this.environmentName,
|
|
463
464
|
locale,
|
|
464
|
-
schema: this.documentSchema,
|
|
465
|
+
schema: this.documentSchema(),
|
|
465
466
|
where: convertPayloadWhereToContentAPI(args.where)
|
|
466
467
|
}
|
|
467
468
|
});
|
|
468
469
|
if (error) {
|
|
469
|
-
throw
|
|
470
|
+
throw createDocumentContentAPIError(this, 'deleteOne', error, httpResponse.status, args.collection);
|
|
470
471
|
}
|
|
471
472
|
if (!response?.result || !('data' in response.result)) {
|
|
472
473
|
throw new Error('No document data in deleteOne response');
|
|
@@ -516,11 +517,11 @@ async function create(args) {
|
|
|
516
517
|
},
|
|
517
518
|
environmentName: this.environmentName,
|
|
518
519
|
locale,
|
|
519
|
-
schema: this.documentSchema
|
|
520
|
+
schema: this.documentSchema()
|
|
520
521
|
}
|
|
521
522
|
});
|
|
522
523
|
if (error) {
|
|
523
|
-
throw
|
|
524
|
+
throw createDocumentContentAPIError(this, 'create', error, httpResponse.status, args.collection);
|
|
524
525
|
}
|
|
525
526
|
if (!contentAPIResponse) {
|
|
526
527
|
throw new Error('No response from create');
|
|
@@ -568,12 +569,12 @@ async function count(args) {
|
|
|
568
569
|
collection: args.collection,
|
|
569
570
|
contentSystemId: this.contentSystemId,
|
|
570
571
|
locale,
|
|
571
|
-
schema: this.documentSchema,
|
|
572
|
+
schema: this.documentSchema(),
|
|
572
573
|
where: convertPayloadWhereToContentAPI(args.where)
|
|
573
574
|
}
|
|
574
575
|
});
|
|
575
576
|
if (error) {
|
|
576
|
-
throw
|
|
577
|
+
throw createDocumentContentAPIError(this, 'count', error, httpResponse.status, args.collection);
|
|
577
578
|
}
|
|
578
579
|
if (!response) {
|
|
579
580
|
throw new Error('No response from count');
|
|
@@ -589,12 +590,12 @@ async function countVersions(args) {
|
|
|
589
590
|
collection: args.collection,
|
|
590
591
|
contentSystemId: this.contentSystemId,
|
|
591
592
|
locale,
|
|
592
|
-
schema: this.documentSchema,
|
|
593
|
+
schema: this.documentSchema(),
|
|
593
594
|
where: convertPayloadWhereToContentAPI(args.where)
|
|
594
595
|
}
|
|
595
596
|
});
|
|
596
597
|
if (error) {
|
|
597
|
-
throw
|
|
598
|
+
throw createDocumentContentAPIError(this, 'countVersions', error, httpResponse.status, args.collection);
|
|
598
599
|
}
|
|
599
600
|
if (!response) {
|
|
600
601
|
throw new Error('No response from countVersions');
|
|
@@ -633,12 +634,12 @@ async function upsert(args) {
|
|
|
633
634
|
}),
|
|
634
635
|
environmentName: this.environmentName,
|
|
635
636
|
locale,
|
|
636
|
-
schema: this.documentSchema,
|
|
637
|
+
schema: this.documentSchema(),
|
|
637
638
|
where: convertPayloadWhereToContentAPI(args.where)
|
|
638
639
|
}
|
|
639
640
|
});
|
|
640
641
|
if (error) {
|
|
641
|
-
throw
|
|
642
|
+
throw createDocumentContentAPIError(this, 'upsert', error, httpResponse.status, args.collection);
|
|
642
643
|
}
|
|
643
644
|
if (!contentAPIResponse) {
|
|
644
645
|
throw new Error('No response from upsert');
|
|
@@ -658,6 +659,7 @@ async function upsert(args) {
|
|
|
658
659
|
});
|
|
659
660
|
}
|
|
660
661
|
async function updateJobs(args) {
|
|
662
|
+
const collection = 'payload-jobs';
|
|
661
663
|
const { id, limit, returning, sort, where } = args;
|
|
662
664
|
if (id == null && where == null) {
|
|
663
665
|
throw new Error('updateJobs requires either id or a where clause');
|
|
@@ -678,12 +680,12 @@ async function updateJobs(args) {
|
|
|
678
680
|
equals: String(id)
|
|
679
681
|
}
|
|
680
682
|
} : where;
|
|
681
|
-
const docData = dataToContentAPI(this.payload,
|
|
682
|
-
const sortClause = addFallbackSort(sort || '-updatedAt', this.payload,
|
|
683
|
+
const docData = dataToContentAPI(this.payload, collection, data);
|
|
684
|
+
const sortClause = addFallbackSort(sort || '-updatedAt', this.payload, collection);
|
|
683
685
|
const whereQuery = convertPayloadWhereToContentAPI(whereClause);
|
|
684
686
|
const { data: response, error, response: httpResponse } = await this.client.POST('/api/v1/documents:update', {
|
|
685
687
|
body: {
|
|
686
|
-
collection
|
|
688
|
+
collection,
|
|
687
689
|
contentSystemId: this.contentSystemId,
|
|
688
690
|
createOnMissing: false,
|
|
689
691
|
doc: docData,
|
|
@@ -691,13 +693,13 @@ async function updateJobs(args) {
|
|
|
691
693
|
...limit != null && {
|
|
692
694
|
limit
|
|
693
695
|
},
|
|
694
|
-
schema: this.documentSchema,
|
|
696
|
+
schema: this.documentSchema(),
|
|
695
697
|
sort: sortClause,
|
|
696
698
|
where: whereQuery
|
|
697
699
|
}
|
|
698
700
|
});
|
|
699
701
|
if (error) {
|
|
700
|
-
throw
|
|
702
|
+
throw createDocumentContentAPIError(this, 'updateJobs', error, httpResponse.status, collection);
|
|
701
703
|
}
|
|
702
704
|
if (!response) {
|
|
703
705
|
throw new Error('No response from updateJobs');
|
|
@@ -709,7 +711,7 @@ async function updateJobs(args) {
|
|
|
709
711
|
return [];
|
|
710
712
|
}
|
|
711
713
|
return response.result.data.map((doc)=>unwrapDocument({
|
|
712
|
-
collectionSlug:
|
|
714
|
+
collectionSlug: collection,
|
|
713
715
|
doc,
|
|
714
716
|
payload: this.payload
|
|
715
717
|
}));
|
|
@@ -809,6 +811,13 @@ function countGlobalVersions(args) {
|
|
|
809
811
|
where: args.where
|
|
810
812
|
});
|
|
811
813
|
}
|
|
814
|
+
function createDocumentContentAPIError(adapter, operation, error, status, collectionSlug) {
|
|
815
|
+
const validationError = maybeCreateUniqueValidationError(error, collectionSlug, adapter);
|
|
816
|
+
if (validationError != null) {
|
|
817
|
+
return validationError;
|
|
818
|
+
}
|
|
819
|
+
return createContentAPIError(operation, error, status);
|
|
820
|
+
}
|
|
812
821
|
function createContentAPIError(operation, error, status) {
|
|
813
822
|
return new APIError(`Content API ${operation} error: ${error.message}`, status, {
|
|
814
823
|
code: error.code,
|
|
@@ -816,6 +825,27 @@ function createContentAPIError(operation, error, status) {
|
|
|
816
825
|
field: error.field
|
|
817
826
|
});
|
|
818
827
|
}
|
|
828
|
+
// A unique-constraint violation from the Content API is Payload's `ValidationError` contract:
|
|
829
|
+
// reconstruct it with the offending field path(s) so callers can map the error back to a field
|
|
830
|
+
// (matching what Payload's other database adapters throw). Falls back to a generic APIError when
|
|
831
|
+
// the collection or offending field is unknown.
|
|
832
|
+
function maybeCreateUniqueValidationError(error, collectionSlug, adapter) {
|
|
833
|
+
if (error.constraint !== 'unique_constraint') {
|
|
834
|
+
return null;
|
|
835
|
+
}
|
|
836
|
+
const paths = (error.field ?? '').split(',').map((path)=>path.trim()).filter((path)=>path.length > 0);
|
|
837
|
+
if (paths.length === 0) {
|
|
838
|
+
adapter.payload.logger.error(`Unique constraint violation but no offending field.`);
|
|
839
|
+
return null;
|
|
840
|
+
}
|
|
841
|
+
return new ValidationError({
|
|
842
|
+
collection: collectionSlug,
|
|
843
|
+
errors: paths.map((path)=>({
|
|
844
|
+
message: error.message,
|
|
845
|
+
path
|
|
846
|
+
}))
|
|
847
|
+
});
|
|
848
|
+
}
|
|
819
849
|
export const contentAPIAdapter = (opts)=>({
|
|
820
850
|
name: 'content-api',
|
|
821
851
|
defaultIDType: 'text',
|
|
@@ -855,7 +885,7 @@ export const contentAPIAdapter = (opts)=>({
|
|
|
855
885
|
deleteMany: deleteMany,
|
|
856
886
|
deleteOne: deleteOne,
|
|
857
887
|
deleteVersions: deleteVersions,
|
|
858
|
-
documentSchema:
|
|
888
|
+
documentSchema: ()=>getDocumentSchema(payload.config),
|
|
859
889
|
environmentName: opts.environmentName,
|
|
860
890
|
find: find,
|
|
861
891
|
findDistinct: findDistinct,
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import { buildDocumentSchema } from './buildDocumentSchema.js';
|
|
2
|
+
// The schema built by `getDocumentSchema`, keyed by the config it was built from.
|
|
3
|
+
// Weakly held so a config discarded by HMR takes its schema with it.
|
|
4
|
+
let schemaByConfig = new WeakMap();
|
|
5
|
+
// Retrieves a document schema for the given config, building it if necessary.
|
|
6
|
+
// The last output is memoized, so if this config matches the last config we just return
|
|
7
|
+
// the previous output instead of rebuilding it.
|
|
8
|
+
export function getDocumentSchema(config) {
|
|
9
|
+
const existing = schemaByConfig.get(config);
|
|
10
|
+
if (existing != null) {
|
|
11
|
+
return existing;
|
|
12
|
+
}
|
|
13
|
+
const schema = buildDocumentSchema(config);
|
|
14
|
+
// Clear the cache of any previous config, so only the most recent one is held.
|
|
15
|
+
// This ensures that we never accidentally leak memory by holding on to more
|
|
16
|
+
// and more schemas if the configs are never garbage collected.
|
|
17
|
+
schemaByConfig = new WeakMap([
|
|
18
|
+
[
|
|
19
|
+
config,
|
|
20
|
+
schema
|
|
21
|
+
]
|
|
22
|
+
]);
|
|
23
|
+
return schema;
|
|
24
|
+
}
|
package/dist/exports/client.d.ts
CHANGED
|
@@ -2,3 +2,5 @@ export { FigmaAvatar } from '../oauth/components/FigmaAvatar/index.js';
|
|
|
2
2
|
export { FigmaAvatarCell } from '../oauth/components/FigmaAvatarCell/index.js';
|
|
3
3
|
export { DefaultLoginButton } from '../oauth/components/LoginButton/index.js';
|
|
4
4
|
export { LogoutButton } from '../oauth/components/LogoutButton/index.js';
|
|
5
|
+
export { FigmaCloudLimitProvider } from '../plugin/cloud-limits/CloudLimitProvider/index.js';
|
|
6
|
+
export { FigmaCloudLimitSlugTracker } from '../plugin/cloud-limits/SlugTracker/index.js';
|
package/dist/exports/client.js
CHANGED
|
@@ -2,3 +2,5 @@ export { FigmaAvatar } from '../oauth/components/FigmaAvatar/index.js';
|
|
|
2
2
|
export { FigmaAvatarCell } from '../oauth/components/FigmaAvatarCell/index.js';
|
|
3
3
|
export { DefaultLoginButton } from '../oauth/components/LoginButton/index.js';
|
|
4
4
|
export { LogoutButton } from '../oauth/components/LogoutButton/index.js';
|
|
5
|
+
export { FigmaCloudLimitProvider } from '../plugin/cloud-limits/CloudLimitProvider/index.js';
|
|
6
|
+
export { FigmaCloudLimitSlugTracker } from '../plugin/cloud-limits/SlugTracker/index.js';
|