@payloadcms/figma 0.0.1-alpha.52 → 0.0.1-alpha.53
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/cli.js +7 -10
- package/dist/commands/upgrade.d.ts +5 -0
- package/dist/commands/upgrade.js +331 -0
- package/dist/db-content-api/generated/content-api-types.d.ts +246 -25
- package/dist/plugin/build-config.js +0 -12
- package/dist/types.d.ts +1 -0
- package/dist/utils/handle-upgrade.d.ts +4 -7
- package/dist/utils/handle-upgrade.js +2 -203
- package/dist/utils/messages.js +6 -0
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -9,8 +9,8 @@ import { initCommand } from './commands/init.js';
|
|
|
9
9
|
import { listTokensCommand } from './commands/list-tokens.js';
|
|
10
10
|
import { loginCommand } from './commands/login.js';
|
|
11
11
|
import { logoutCommand } from './commands/logout.js';
|
|
12
|
+
import { upgradeCommand } from './commands/upgrade.js';
|
|
12
13
|
import { setInfraEnvironment } from './constants.js';
|
|
13
|
-
import { handleUpgrade } from './utils/handle-upgrade.js';
|
|
14
14
|
import { helpMessage } from './utils/messages.js';
|
|
15
15
|
/**
|
|
16
16
|
* Entrypoint for bin/cli.js
|
|
@@ -31,6 +31,7 @@ class Main {
|
|
|
31
31
|
this.args = arg({
|
|
32
32
|
'--all': Boolean,
|
|
33
33
|
'--debug': Boolean,
|
|
34
|
+
'--dry-run': Boolean,
|
|
34
35
|
'--env': String,
|
|
35
36
|
'--force': Boolean,
|
|
36
37
|
'--help': Boolean,
|
|
@@ -86,15 +87,6 @@ class Main {
|
|
|
86
87
|
helpMessage();
|
|
87
88
|
process.exit(0);
|
|
88
89
|
}
|
|
89
|
-
// Check for upgrade migrations
|
|
90
|
-
try {
|
|
91
|
-
const upgradeChanges = await handleUpgrade(process.cwd());
|
|
92
|
-
if (upgradeChanges.length > 0) {
|
|
93
|
-
p.log.info(`Migrated project: ${upgradeChanges.join(', ')}`);
|
|
94
|
-
}
|
|
95
|
-
} catch {
|
|
96
|
-
// Never block CLI execution due to upgrade check
|
|
97
|
-
}
|
|
98
90
|
// Debug command outputs plain text for copy-paste — skip styled intro
|
|
99
91
|
if (subcommand === 'debug') {
|
|
100
92
|
await debugCommand();
|
|
@@ -147,6 +139,11 @@ class Main {
|
|
|
147
139
|
debug: this.args['--debug']
|
|
148
140
|
});
|
|
149
141
|
break;
|
|
142
|
+
case 'upgrade':
|
|
143
|
+
await upgradeCommand({
|
|
144
|
+
isDryRun: this.args['--dry-run']
|
|
145
|
+
});
|
|
146
|
+
break;
|
|
150
147
|
default:
|
|
151
148
|
p.log.error(pc.red(`Unknown command: ${subcommand}`));
|
|
152
149
|
p.note('Use --help to see available commands', 'Tip');
|
|
@@ -0,0 +1,331 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
import pc from 'picocolors';
|
|
5
|
+
import { Project } from 'ts-morph';
|
|
6
|
+
import { fileURLToPath } from 'url';
|
|
7
|
+
import { getBootstrapInfo, getCmsResourceId } from '../api/control-plane.js';
|
|
8
|
+
import { getValidAccessToken } from '../auth/oauth-flow.js';
|
|
9
|
+
import { getTokenStore } from '../auth/token-store.js';
|
|
10
|
+
import { cacheAllEnvironments } from '../utils/cache-bootstrap.js';
|
|
11
|
+
import { addOrUpdateEnvVar, getEnvVar, removeEnvVar } from '../utils/env-management.js';
|
|
12
|
+
import { formatFile } from '../utils/formatter.js';
|
|
13
|
+
import { getPackageManager } from '../utils/package-manager.js';
|
|
14
|
+
import { removeFigmaContentSystemId } from '../utils/payload-config-ast.js';
|
|
15
|
+
import { findPayloadConfig } from '../utils/payload-config-finder.js';
|
|
16
|
+
import { checkPackageInstalled, installPackage } from '../utils/payload-package-check.js';
|
|
17
|
+
import { getOwnVersion } from '../utils/version-check.js';
|
|
18
|
+
export async function upgradeCommand(options = {}) {
|
|
19
|
+
const cwd = process.cwd();
|
|
20
|
+
const { isDryRun = false } = options;
|
|
21
|
+
const changes = [];
|
|
22
|
+
const warnings = [];
|
|
23
|
+
const spinner = p.spinner();
|
|
24
|
+
spinner.start('Checking for needed migrations...');
|
|
25
|
+
spinner.stop('Checking for needed migrations...');
|
|
26
|
+
await migrateEnvRename({
|
|
27
|
+
changes,
|
|
28
|
+
cwd,
|
|
29
|
+
isDryRun
|
|
30
|
+
});
|
|
31
|
+
await migrateProjectId({
|
|
32
|
+
changes,
|
|
33
|
+
cwd,
|
|
34
|
+
isDryRun,
|
|
35
|
+
warnings
|
|
36
|
+
});
|
|
37
|
+
await ensureBootstrapCached({
|
|
38
|
+
changes,
|
|
39
|
+
cwd,
|
|
40
|
+
isDryRun
|
|
41
|
+
});
|
|
42
|
+
await migrateRemoveDeprecatedEnvVars({
|
|
43
|
+
changes,
|
|
44
|
+
cwd,
|
|
45
|
+
isDryRun,
|
|
46
|
+
warnings
|
|
47
|
+
});
|
|
48
|
+
await migrateConfigAst({
|
|
49
|
+
changes,
|
|
50
|
+
cwd,
|
|
51
|
+
isDryRun
|
|
52
|
+
});
|
|
53
|
+
await migratePackageVersion({
|
|
54
|
+
changes,
|
|
55
|
+
cwd,
|
|
56
|
+
isDryRun
|
|
57
|
+
});
|
|
58
|
+
for (const warning of warnings){
|
|
59
|
+
p.log.warning(warning);
|
|
60
|
+
}
|
|
61
|
+
if (changes.length === 0) {
|
|
62
|
+
p.log.success('Everything is up to date.');
|
|
63
|
+
return;
|
|
64
|
+
}
|
|
65
|
+
if (isDryRun) {
|
|
66
|
+
p.log.info(`Dry run: ${changes.length} change(s) detected.`);
|
|
67
|
+
} else {
|
|
68
|
+
p.log.success(`${changes.length} change(s) applied.`);
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
const DEPRECATED_ENV_VARS = [
|
|
72
|
+
'FIGMA_CONTENT_API_CONTENT_SYSTEM_ID',
|
|
73
|
+
'FIGMA_TENANT_ID',
|
|
74
|
+
'FIGMA_OAUTH_CLIENT_ID',
|
|
75
|
+
'FIGMA_OAUTH_CLIENT_SECRET'
|
|
76
|
+
];
|
|
77
|
+
async function migrateEnvRename({ changes, cwd, isDryRun }) {
|
|
78
|
+
try {
|
|
79
|
+
const oldValue = await getEnvVar(cwd, 'FIGMA_ENV');
|
|
80
|
+
if (oldValue === null) {
|
|
81
|
+
return;
|
|
82
|
+
}
|
|
83
|
+
if (isDryRun) {
|
|
84
|
+
p.log.message(`${pc.dim('○')} Would rename FIGMA_ENV → FIGMA_INFRA_ENV`);
|
|
85
|
+
changes.push('Rename FIGMA_ENV → FIGMA_INFRA_ENV');
|
|
86
|
+
return;
|
|
87
|
+
}
|
|
88
|
+
await addOrUpdateEnvVar(cwd, 'FIGMA_INFRA_ENV', oldValue);
|
|
89
|
+
await removeEnvVar(cwd, 'FIGMA_ENV');
|
|
90
|
+
p.log.message(`${pc.green('●')} Env: Renamed FIGMA_ENV → FIGMA_INFRA_ENV`);
|
|
91
|
+
changes.push('Renamed FIGMA_ENV → FIGMA_INFRA_ENV');
|
|
92
|
+
} catch (error) {
|
|
93
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
94
|
+
p.log.warning(`Env rename migration failed: ${msg}`);
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
async function migrateProjectId({ changes, cwd, isDryRun, warnings = [] }) {
|
|
98
|
+
try {
|
|
99
|
+
const existingProjectId = await getEnvVar(cwd, 'FIGMA_PROJECT_ID');
|
|
100
|
+
if (existingProjectId) {
|
|
101
|
+
return;
|
|
102
|
+
}
|
|
103
|
+
const oldContentSystemId = await getEnvVar(cwd, 'FIGMA_CONTENT_API_CONTENT_SYSTEM_ID');
|
|
104
|
+
if (!oldContentSystemId) {
|
|
105
|
+
return;
|
|
106
|
+
}
|
|
107
|
+
if (isDryRun) {
|
|
108
|
+
p.log.message(`${pc.dim('○')} Would resolve FIGMA_PROJECT_ID from content system ID`);
|
|
109
|
+
changes.push('Resolve FIGMA_PROJECT_ID from content system ID');
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const store = getTokenStore();
|
|
113
|
+
const accessToken = await getValidAccessToken(store);
|
|
114
|
+
if (!accessToken) {
|
|
115
|
+
warnings.push('Not authenticated — could not resolve FIGMA_PROJECT_ID. Run `npx @payloadcms/figma login` first.');
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const cmsResourceId = await getCmsResourceId(accessToken, oldContentSystemId);
|
|
119
|
+
await addOrUpdateEnvVar(cwd, 'FIGMA_PROJECT_ID', cmsResourceId);
|
|
120
|
+
// Resolve actual environment name from bootstrap API
|
|
121
|
+
try {
|
|
122
|
+
const bootstrapInfo = await getBootstrapInfo(accessToken, cmsResourceId);
|
|
123
|
+
cacheAllEnvironments(store, cmsResourceId, bootstrapInfo);
|
|
124
|
+
const envName = bootstrapInfo.environments[0]?.name ?? 'production';
|
|
125
|
+
await addOrUpdateEnvVar(cwd, 'FIGMA_ENVIRONMENT_NAME', envName);
|
|
126
|
+
} catch {
|
|
127
|
+
await addOrUpdateEnvVar(cwd, 'FIGMA_ENVIRONMENT_NAME', 'production');
|
|
128
|
+
}
|
|
129
|
+
p.log.message(`${pc.green('●')} Env: Resolved FIGMA_PROJECT_ID from content system ID`);
|
|
130
|
+
changes.push('Resolved FIGMA_PROJECT_ID from content system ID');
|
|
131
|
+
} catch (error) {
|
|
132
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
133
|
+
p.log.warning(`Project ID migration failed: ${msg}`);
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
async function ensureBootstrapCached(params) {
|
|
137
|
+
try {
|
|
138
|
+
const projectId = await getEnvVar(params.cwd, 'FIGMA_PROJECT_ID');
|
|
139
|
+
if (!projectId) {
|
|
140
|
+
return;
|
|
141
|
+
}
|
|
142
|
+
const environmentName = await getEnvVar(params.cwd, 'FIGMA_ENVIRONMENT_NAME') ?? 'production';
|
|
143
|
+
const store = getTokenStore();
|
|
144
|
+
if (store.getBootstrapData(projectId, environmentName)) {
|
|
145
|
+
return;
|
|
146
|
+
}
|
|
147
|
+
const accessToken = await getValidAccessToken(store);
|
|
148
|
+
if (!accessToken) {
|
|
149
|
+
return;
|
|
150
|
+
}
|
|
151
|
+
const bootstrapInfo = await getBootstrapInfo(accessToken, projectId);
|
|
152
|
+
cacheAllEnvironments(store, projectId, bootstrapInfo);
|
|
153
|
+
// Fix FIGMA_ENVIRONMENT_NAME if it doesn't match any actual environment
|
|
154
|
+
const envNames = bootstrapInfo.environments.map((e)=>e.name);
|
|
155
|
+
if (!envNames.includes(environmentName) && envNames.length > 0) {
|
|
156
|
+
const correctName = envNames[0];
|
|
157
|
+
if (params.isDryRun) {
|
|
158
|
+
p.log.message(`${pc.dim('○')} Would fix FIGMA_ENVIRONMENT_NAME: ${environmentName} → ${correctName}`);
|
|
159
|
+
params.changes.push(`Fix FIGMA_ENVIRONMENT_NAME`);
|
|
160
|
+
return;
|
|
161
|
+
}
|
|
162
|
+
await addOrUpdateEnvVar(params.cwd, 'FIGMA_ENVIRONMENT_NAME', correctName);
|
|
163
|
+
p.log.message(`${pc.green('●')} Env: Fixed FIGMA_ENVIRONMENT_NAME: ${environmentName} → ${correctName}`);
|
|
164
|
+
params.changes.push(`Fixed FIGMA_ENVIRONMENT_NAME: ${environmentName} → ${correctName}`);
|
|
165
|
+
}
|
|
166
|
+
} catch {
|
|
167
|
+
// Best-effort — runtime will retry if needed
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
async function migrateRemoveDeprecatedEnvVars({ changes, cwd, isDryRun, warnings = [] }) {
|
|
171
|
+
try {
|
|
172
|
+
const presentVars = [];
|
|
173
|
+
for (const key of DEPRECATED_ENV_VARS){
|
|
174
|
+
const value = await getEnvVar(cwd, key);
|
|
175
|
+
if (value !== null) {
|
|
176
|
+
presentVars.push(key);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
if (presentVars.length === 0) {
|
|
180
|
+
return;
|
|
181
|
+
}
|
|
182
|
+
// Only remove when bootstrap data is available (proves the project is set up correctly)
|
|
183
|
+
const projectId = await getEnvVar(cwd, 'FIGMA_PROJECT_ID');
|
|
184
|
+
if (!projectId) {
|
|
185
|
+
warnings.push('Cannot remove deprecated env vars without FIGMA_PROJECT_ID. Run upgrade again after project ID migration.');
|
|
186
|
+
return;
|
|
187
|
+
}
|
|
188
|
+
const environmentName = await getEnvVar(cwd, 'FIGMA_ENVIRONMENT_NAME') ?? 'production';
|
|
189
|
+
const store = getTokenStore();
|
|
190
|
+
const bootstrapData = store.getBootstrapData(projectId, environmentName);
|
|
191
|
+
if (!bootstrapData) {
|
|
192
|
+
// Try fetching from API
|
|
193
|
+
const accessToken = await getValidAccessToken(store);
|
|
194
|
+
if (accessToken) {
|
|
195
|
+
try {
|
|
196
|
+
const bootstrapInfo = await getBootstrapInfo(accessToken, projectId);
|
|
197
|
+
cacheAllEnvironments(store, projectId, bootstrapInfo);
|
|
198
|
+
} catch {
|
|
199
|
+
warnings.push('Could not verify bootstrap data — keeping deprecated env vars. Run `npx @payloadcms/figma init` to complete migration.');
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
} else {
|
|
203
|
+
warnings.push('Not authenticated — keeping deprecated env vars. Run `npx @payloadcms/figma login` first.');
|
|
204
|
+
return;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (isDryRun) {
|
|
208
|
+
p.log.message(`${pc.dim('○')} Would remove deprecated env vars: ${presentVars.join(', ')}`);
|
|
209
|
+
changes.push(`Remove deprecated env vars: ${presentVars.join(', ')}`);
|
|
210
|
+
return;
|
|
211
|
+
}
|
|
212
|
+
const removed = [];
|
|
213
|
+
for (const key of presentVars){
|
|
214
|
+
await removeEnvVar(cwd, key);
|
|
215
|
+
removed.push(key);
|
|
216
|
+
}
|
|
217
|
+
p.log.message(`${pc.green('●')} Env: Removed deprecated env vars: ${removed.join(', ')}`);
|
|
218
|
+
changes.push(`Removed deprecated env vars: ${removed.join(', ')}`);
|
|
219
|
+
} catch (error) {
|
|
220
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
221
|
+
p.log.warning(`Deprecated env var removal failed: ${msg}`);
|
|
222
|
+
}
|
|
223
|
+
}
|
|
224
|
+
async function migrateConfigAst({ changes, cwd, isDryRun }) {
|
|
225
|
+
try {
|
|
226
|
+
const configPath = await findPayloadConfig(cwd);
|
|
227
|
+
if (!configPath) {
|
|
228
|
+
return;
|
|
229
|
+
}
|
|
230
|
+
const project = new Project({
|
|
231
|
+
skipAddingFilesFromTsConfig: true
|
|
232
|
+
});
|
|
233
|
+
const sourceFile = project.addSourceFileAtPath(configPath);
|
|
234
|
+
const wouldRemove = removeFigmaContentSystemId(sourceFile);
|
|
235
|
+
if (!wouldRemove) {
|
|
236
|
+
return;
|
|
237
|
+
}
|
|
238
|
+
if (isDryRun) {
|
|
239
|
+
p.log.message(`${pc.dim('○')} Would remove contentSystemId from payload.config.ts`);
|
|
240
|
+
changes.push('Remove contentSystemId from payload.config.ts');
|
|
241
|
+
return;
|
|
242
|
+
}
|
|
243
|
+
// Re-parse fresh since the detection already mutated the AST
|
|
244
|
+
const freshProject = new Project({
|
|
245
|
+
skipAddingFilesFromTsConfig: true
|
|
246
|
+
});
|
|
247
|
+
const freshSourceFile = freshProject.addSourceFileAtPath(configPath);
|
|
248
|
+
removeFigmaContentSystemId(freshSourceFile);
|
|
249
|
+
await freshSourceFile.save();
|
|
250
|
+
try {
|
|
251
|
+
const packageManager = await getPackageManager(cwd);
|
|
252
|
+
await formatFile(configPath, packageManager);
|
|
253
|
+
} catch {
|
|
254
|
+
// Formatting is best-effort
|
|
255
|
+
}
|
|
256
|
+
p.log.message(`${pc.green('●')} Config: Removed contentSystemId from payload.config.ts`);
|
|
257
|
+
changes.push('Removed contentSystemId from payload.config.ts');
|
|
258
|
+
} catch (error) {
|
|
259
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
260
|
+
p.log.warning(`Config AST migration failed: ${msg}`);
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
async function migratePackageVersion({ changes, cwd, isDryRun }) {
|
|
264
|
+
try {
|
|
265
|
+
const isInstalled = await checkPackageInstalled(cwd, '@payloadcms/figma');
|
|
266
|
+
if (!isInstalled) {
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const cliDir = path.dirname(fileURLToPath(import.meta.url));
|
|
270
|
+
const isFromRegistry = cliDir.includes('node_modules') || cliDir.includes('.npm');
|
|
271
|
+
if (isFromRegistry) {
|
|
272
|
+
await migrateRegistryPackageVersion({
|
|
273
|
+
changes,
|
|
274
|
+
cliDir,
|
|
275
|
+
cwd,
|
|
276
|
+
isDryRun
|
|
277
|
+
});
|
|
278
|
+
} else {
|
|
279
|
+
await migrateLocalPackageVersion({
|
|
280
|
+
changes,
|
|
281
|
+
cliDir,
|
|
282
|
+
cwd,
|
|
283
|
+
isDryRun
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
} catch (error) {
|
|
287
|
+
const msg = error instanceof Error ? error.message : 'Unknown error';
|
|
288
|
+
p.log.warning(`Package version sync failed: ${msg}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
async function migrateRegistryPackageVersion({ changes, cliDir: _cliDir, cwd, isDryRun }) {
|
|
292
|
+
const cliVersion = await getOwnVersion();
|
|
293
|
+
const pkgJsonPath = path.join(cwd, 'package.json');
|
|
294
|
+
const pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, 'utf-8'));
|
|
295
|
+
const installedVersion = pkgJson.dependencies?.['@payloadcms/figma']?.replace(/^[\^~>=<]+/, '');
|
|
296
|
+
if (!installedVersion || installedVersion === cliVersion) {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
if (isDryRun) {
|
|
300
|
+
p.log.message(`${pc.dim('○')} Would update @payloadcms/figma ${installedVersion} → ${cliVersion}`);
|
|
301
|
+
changes.push(`Update @payloadcms/figma ${installedVersion} → ${cliVersion}`);
|
|
302
|
+
return;
|
|
303
|
+
}
|
|
304
|
+
const packageManager = await getPackageManager(cwd);
|
|
305
|
+
await installPackage(cwd, '@payloadcms/figma', packageManager, cliVersion);
|
|
306
|
+
p.log.message(`${pc.green('●')} Package: Updated @payloadcms/figma ${installedVersion} → ${cliVersion}`);
|
|
307
|
+
changes.push(`Updated @payloadcms/figma ${installedVersion} → ${cliVersion}`);
|
|
308
|
+
}
|
|
309
|
+
async function migrateLocalPackageVersion({ changes, cliDir, cwd, isDryRun }) {
|
|
310
|
+
if (isDryRun) {
|
|
311
|
+
p.log.message(`${pc.dim('○')} Would install @payloadcms/figma from local build`);
|
|
312
|
+
changes.push('Install @payloadcms/figma from local build');
|
|
313
|
+
return;
|
|
314
|
+
}
|
|
315
|
+
// Dynamic import — findPackageRoot and packLocalPackage will be exported in a later task
|
|
316
|
+
const { findPackageRoot, packLocalPackage } = await import('../utils/handle-upgrade.js');
|
|
317
|
+
const pkgDir = await findPackageRoot(cliDir);
|
|
318
|
+
if (!pkgDir) {
|
|
319
|
+
return;
|
|
320
|
+
}
|
|
321
|
+
const packageManager = await getPackageManager(cwd);
|
|
322
|
+
const tgzPath = packLocalPackage(pkgDir);
|
|
323
|
+
const destTgz = path.join(cwd, path.basename(tgzPath));
|
|
324
|
+
await fs.rename(tgzPath, destTgz);
|
|
325
|
+
await installPackage(cwd, destTgz, packageManager);
|
|
326
|
+
await fs.unlink(destTgz).catch(()=>{});
|
|
327
|
+
p.log.message(`${pc.green('●')} Package: Installed @payloadcms/figma from local build`);
|
|
328
|
+
changes.push('Installed @payloadcms/figma from local build');
|
|
329
|
+
}
|
|
330
|
+
|
|
331
|
+
//# sourceMappingURL=upgrade.js.map
|
|
@@ -1494,6 +1494,117 @@ export type paths = {
|
|
|
1494
1494
|
};
|
|
1495
1495
|
};
|
|
1496
1496
|
};
|
|
1497
|
+
/** @description Unauthorized */
|
|
1498
|
+
401: {
|
|
1499
|
+
headers: {
|
|
1500
|
+
[name: string]: unknown;
|
|
1501
|
+
};
|
|
1502
|
+
content: {
|
|
1503
|
+
'application/json': {
|
|
1504
|
+
/** @example Error message describing the issue. */
|
|
1505
|
+
message: string;
|
|
1506
|
+
};
|
|
1507
|
+
};
|
|
1508
|
+
};
|
|
1509
|
+
/** @description Forbidden */
|
|
1510
|
+
403: {
|
|
1511
|
+
headers: {
|
|
1512
|
+
[name: string]: unknown;
|
|
1513
|
+
};
|
|
1514
|
+
content: {
|
|
1515
|
+
'application/json': {
|
|
1516
|
+
/** @example Error message describing the issue. */
|
|
1517
|
+
message: string;
|
|
1518
|
+
};
|
|
1519
|
+
};
|
|
1520
|
+
};
|
|
1521
|
+
/** @description Not Found */
|
|
1522
|
+
404: {
|
|
1523
|
+
headers: {
|
|
1524
|
+
[name: string]: unknown;
|
|
1525
|
+
};
|
|
1526
|
+
content: {
|
|
1527
|
+
'application/json': {
|
|
1528
|
+
/** @example Error message describing the issue. */
|
|
1529
|
+
message: string;
|
|
1530
|
+
};
|
|
1531
|
+
};
|
|
1532
|
+
};
|
|
1533
|
+
/** @description Internal Server Error */
|
|
1534
|
+
500: {
|
|
1535
|
+
headers: {
|
|
1536
|
+
[name: string]: unknown;
|
|
1537
|
+
};
|
|
1538
|
+
content: {
|
|
1539
|
+
'application/json': {
|
|
1540
|
+
/** @example Error message describing the issue. */
|
|
1541
|
+
message: string;
|
|
1542
|
+
};
|
|
1543
|
+
};
|
|
1544
|
+
};
|
|
1545
|
+
};
|
|
1546
|
+
};
|
|
1547
|
+
delete?: never;
|
|
1548
|
+
options?: never;
|
|
1549
|
+
head?: never;
|
|
1550
|
+
patch?: never;
|
|
1551
|
+
trace?: never;
|
|
1552
|
+
};
|
|
1553
|
+
'/api/v0/documents:findDistinct': {
|
|
1554
|
+
parameters: {
|
|
1555
|
+
query?: never;
|
|
1556
|
+
header?: never;
|
|
1557
|
+
path?: never;
|
|
1558
|
+
cookie?: never;
|
|
1559
|
+
};
|
|
1560
|
+
get?: never;
|
|
1561
|
+
put?: never;
|
|
1562
|
+
post: {
|
|
1563
|
+
parameters: {
|
|
1564
|
+
query?: never;
|
|
1565
|
+
header?: never;
|
|
1566
|
+
path?: never;
|
|
1567
|
+
cookie?: never;
|
|
1568
|
+
};
|
|
1569
|
+
requestBody?: {
|
|
1570
|
+
content: {
|
|
1571
|
+
'application/json': components['schemas']['FindDistinctDocumentsRequest'];
|
|
1572
|
+
};
|
|
1573
|
+
};
|
|
1574
|
+
responses: {
|
|
1575
|
+
/** @description Distinct values found */
|
|
1576
|
+
200: {
|
|
1577
|
+
headers: {
|
|
1578
|
+
[name: string]: unknown;
|
|
1579
|
+
};
|
|
1580
|
+
content: {
|
|
1581
|
+
'application/json': components['schemas']['FindDistinctDocumentsResponse'];
|
|
1582
|
+
};
|
|
1583
|
+
};
|
|
1584
|
+
/** @description Bad Request */
|
|
1585
|
+
400: {
|
|
1586
|
+
headers: {
|
|
1587
|
+
[name: string]: unknown;
|
|
1588
|
+
};
|
|
1589
|
+
content: {
|
|
1590
|
+
'application/json': {
|
|
1591
|
+
/** @example Error message describing the issue. */
|
|
1592
|
+
message: string;
|
|
1593
|
+
};
|
|
1594
|
+
};
|
|
1595
|
+
};
|
|
1596
|
+
/** @description Unauthorized */
|
|
1597
|
+
401: {
|
|
1598
|
+
headers: {
|
|
1599
|
+
[name: string]: unknown;
|
|
1600
|
+
};
|
|
1601
|
+
content: {
|
|
1602
|
+
'application/json': {
|
|
1603
|
+
/** @example Error message describing the issue. */
|
|
1604
|
+
message: string;
|
|
1605
|
+
};
|
|
1606
|
+
};
|
|
1607
|
+
};
|
|
1497
1608
|
/** @description Forbidden */
|
|
1498
1609
|
403: {
|
|
1499
1610
|
headers: {
|
|
@@ -2953,12 +3064,21 @@ export type components = {
|
|
|
2953
3064
|
contentSystemScope?: string;
|
|
2954
3065
|
};
|
|
2955
3066
|
HealthResponse: {
|
|
2956
|
-
/**
|
|
2957
|
-
|
|
2958
|
-
|
|
2959
|
-
|
|
2960
|
-
|
|
2961
|
-
|
|
3067
|
+
/**
|
|
3068
|
+
* @example ok
|
|
3069
|
+
* @enum {string}
|
|
3070
|
+
*/
|
|
3071
|
+
status: 'ok';
|
|
3072
|
+
/**
|
|
3073
|
+
* @example connected
|
|
3074
|
+
* @enum {string}
|
|
3075
|
+
*/
|
|
3076
|
+
database: 'connected' | 'disconnected';
|
|
3077
|
+
/**
|
|
3078
|
+
* @example available
|
|
3079
|
+
* @enum {string}
|
|
3080
|
+
*/
|
|
3081
|
+
s3: 'available' | 'unavailable';
|
|
2962
3082
|
/** @example 2026-01-01T00:00:00.000Z */
|
|
2963
3083
|
timestamp: string;
|
|
2964
3084
|
};
|
|
@@ -3177,14 +3297,51 @@ export type components = {
|
|
|
3177
3297
|
count: number;
|
|
3178
3298
|
};
|
|
3179
3299
|
};
|
|
3300
|
+
/** @example es */
|
|
3301
|
+
LocaleClause: string;
|
|
3180
3302
|
/**
|
|
3181
|
-
* @example
|
|
3182
|
-
*
|
|
3303
|
+
* @example {
|
|
3304
|
+
* "paths": [
|
|
3305
|
+
* "field_a",
|
|
3306
|
+
* "field_b"
|
|
3307
|
+
* ]
|
|
3308
|
+
* }
|
|
3183
3309
|
*/
|
|
3184
|
-
|
|
3310
|
+
UniquePath: {
|
|
3311
|
+
paths: string[];
|
|
3312
|
+
};
|
|
3313
|
+
PathTypeRelationship: {
|
|
3314
|
+
/** @enum {string} */
|
|
3315
|
+
type: 'relationship';
|
|
3316
|
+
collection: string | string[];
|
|
3317
|
+
hasMany?: boolean;
|
|
3318
|
+
};
|
|
3319
|
+
PathTypeJoin: {
|
|
3320
|
+
/** @enum {string} */
|
|
3321
|
+
type: 'join';
|
|
3322
|
+
collection: string | string[];
|
|
3323
|
+
hasMany?: boolean;
|
|
3324
|
+
on: string;
|
|
3325
|
+
};
|
|
3326
|
+
/** @enum {string} */
|
|
3327
|
+
PathTypeBlocks: 'blocks';
|
|
3328
|
+
/** @example array */
|
|
3329
|
+
PathType: 'array' | components['schemas']['PathTypeRelationship'] | components['schemas']['PathTypeJoin'] | components['schemas']['PathTypeBlocks'];
|
|
3185
3330
|
/**
|
|
3186
3331
|
* @example {
|
|
3187
|
-
* "author.tagIds": "array"
|
|
3332
|
+
* "author.tagIds": "array",
|
|
3333
|
+
* "author": {
|
|
3334
|
+
* "type": "relationship",
|
|
3335
|
+
* "collection": "users",
|
|
3336
|
+
* "hasMany": false
|
|
3337
|
+
* },
|
|
3338
|
+
* "relatedPosts": {
|
|
3339
|
+
* "type": "join",
|
|
3340
|
+
* "collection": "posts",
|
|
3341
|
+
* "hasMany": true,
|
|
3342
|
+
* "on": "category"
|
|
3343
|
+
* },
|
|
3344
|
+
* "blocks": "blocks"
|
|
3188
3345
|
* }
|
|
3189
3346
|
*/
|
|
3190
3347
|
PathTypesMeta: {
|
|
@@ -3192,6 +3349,7 @@ export type components = {
|
|
|
3192
3349
|
};
|
|
3193
3350
|
RequestMeta: {
|
|
3194
3351
|
localizedPaths?: string[];
|
|
3352
|
+
uniquePaths?: components['schemas']['UniquePath'][];
|
|
3195
3353
|
pathTypes?: components['schemas']['PathTypesMeta'];
|
|
3196
3354
|
};
|
|
3197
3355
|
DataValue: string | number | boolean | unknown | components['schemas']['DataValue'][] | {
|
|
@@ -3227,6 +3385,7 @@ export type components = {
|
|
|
3227
3385
|
contentSystemId: string;
|
|
3228
3386
|
/** @example posts */
|
|
3229
3387
|
collection: string;
|
|
3388
|
+
locale?: components['schemas']['LocaleClause'];
|
|
3230
3389
|
meta?: components['schemas']['RequestMeta'];
|
|
3231
3390
|
where?: components['schemas']['WhereClause'];
|
|
3232
3391
|
};
|
|
@@ -3291,29 +3450,46 @@ export type components = {
|
|
|
3291
3450
|
page?: number;
|
|
3292
3451
|
sort?: components['schemas']['SortClause'];
|
|
3293
3452
|
}[];
|
|
3294
|
-
/** @example es */
|
|
3295
|
-
LocaleClause: string;
|
|
3296
3453
|
/**
|
|
3297
3454
|
* @example {
|
|
3298
|
-
* "
|
|
3299
|
-
* "
|
|
3300
|
-
* "
|
|
3301
|
-
* "
|
|
3302
|
-
*
|
|
3303
|
-
*
|
|
3455
|
+
* "title": true,
|
|
3456
|
+
* "author": {
|
|
3457
|
+
* "name": true,
|
|
3458
|
+
* "email": true
|
|
3459
|
+
* },
|
|
3460
|
+
* "tags": true
|
|
3304
3461
|
* }
|
|
3305
3462
|
*/
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3463
|
+
IncludeSelectClause: {
|
|
3464
|
+
[key: string]: true | {
|
|
3465
|
+
[key: string]: components['schemas']['IncludeSelectClause'];
|
|
3466
|
+
};
|
|
3467
|
+
};
|
|
3468
|
+
/**
|
|
3469
|
+
* @example {
|
|
3470
|
+
* "title": false,
|
|
3471
|
+
* "author": {
|
|
3472
|
+
* "name": false,
|
|
3473
|
+
* "email": false
|
|
3474
|
+
* },
|
|
3475
|
+
* "tags": false
|
|
3476
|
+
* }
|
|
3477
|
+
*/
|
|
3478
|
+
ExcludeSelectClause: {
|
|
3479
|
+
[key: string]: false | {
|
|
3480
|
+
[key: string]: components['schemas']['ExcludeSelectClause'];
|
|
3481
|
+
};
|
|
3310
3482
|
};
|
|
3483
|
+
/** @description Field selection - use include mode (true) or exclude mode (false), but not both */
|
|
3484
|
+
SelectClause: components['schemas']['IncludeSelectClause'] | components['schemas']['ExcludeSelectClause'];
|
|
3311
3485
|
CreateDocumentRequest: {
|
|
3312
3486
|
/** @example cms-xxxxx-xxxxx */
|
|
3313
3487
|
contentSystemId: string;
|
|
3314
3488
|
/** @example posts */
|
|
3315
3489
|
collection: string;
|
|
3316
3490
|
doc: components['schemas']['DocumentData'];
|
|
3491
|
+
locale?: components['schemas']['LocaleClause'];
|
|
3492
|
+
meta?: components['schemas']['RequestMeta'];
|
|
3317
3493
|
returning?: false | {
|
|
3318
3494
|
join?: components['schemas']['JoinClause'];
|
|
3319
3495
|
locale?: components['schemas']['LocaleClause'];
|
|
@@ -3353,6 +3529,47 @@ export type components = {
|
|
|
3353
3529
|
sort?: components['schemas']['SortClause'];
|
|
3354
3530
|
where?: components['schemas']['WhereClause'];
|
|
3355
3531
|
};
|
|
3532
|
+
FindDistinctDocumentsResponse: {
|
|
3533
|
+
result: {
|
|
3534
|
+
/**
|
|
3535
|
+
* @example [
|
|
3536
|
+
* "value1",
|
|
3537
|
+
* "value2"
|
|
3538
|
+
* ]
|
|
3539
|
+
*/
|
|
3540
|
+
data: unknown[];
|
|
3541
|
+
totalDocs: number;
|
|
3542
|
+
limit: number;
|
|
3543
|
+
page: number;
|
|
3544
|
+
totalPages: number;
|
|
3545
|
+
pagingCounter: number;
|
|
3546
|
+
hasPrevPage: boolean;
|
|
3547
|
+
hasNextPage: boolean;
|
|
3548
|
+
prevPage: number | null;
|
|
3549
|
+
nextPage: number | null;
|
|
3550
|
+
};
|
|
3551
|
+
};
|
|
3552
|
+
FindDistinctDocumentsRequest: {
|
|
3553
|
+
/** @example cms-xxxxx-xxxxx */
|
|
3554
|
+
contentSystemId: string;
|
|
3555
|
+
/** @example posts */
|
|
3556
|
+
collection: string;
|
|
3557
|
+
/**
|
|
3558
|
+
* @description Path to the field to get distinct values for
|
|
3559
|
+
* @example title
|
|
3560
|
+
*/
|
|
3561
|
+
distinctBy: string;
|
|
3562
|
+
join?: components['schemas']['JoinClause'];
|
|
3563
|
+
/** @example 10 */
|
|
3564
|
+
limit?: number;
|
|
3565
|
+
locale?: components['schemas']['LocaleClause'];
|
|
3566
|
+
/** @example 1 */
|
|
3567
|
+
page?: number;
|
|
3568
|
+
meta?: components['schemas']['RequestMeta'];
|
|
3569
|
+
select?: components['schemas']['SelectClause'];
|
|
3570
|
+
sort?: components['schemas']['SortClause'];
|
|
3571
|
+
where?: components['schemas']['WhereClause'];
|
|
3572
|
+
};
|
|
3356
3573
|
UpdateDocumentResponse: {
|
|
3357
3574
|
result?: {
|
|
3358
3575
|
/** @example 1 */
|
|
@@ -3388,6 +3605,7 @@ export type components = {
|
|
|
3388
3605
|
doc: components['schemas']['DataWithOperations'];
|
|
3389
3606
|
/** @example 10 */
|
|
3390
3607
|
limit?: number;
|
|
3608
|
+
locale?: components['schemas']['LocaleClause'];
|
|
3391
3609
|
meta?: components['schemas']['RequestMeta'];
|
|
3392
3610
|
returning?: false | {
|
|
3393
3611
|
join?: components['schemas']['JoinClause'];
|
|
@@ -3396,7 +3614,6 @@ export type components = {
|
|
|
3396
3614
|
};
|
|
3397
3615
|
sort?: components['schemas']['SortClause'];
|
|
3398
3616
|
where: components['schemas']['WhereClause'];
|
|
3399
|
-
locale?: components['schemas']['LocaleClause'];
|
|
3400
3617
|
};
|
|
3401
3618
|
DeleteDocumentResponse: {
|
|
3402
3619
|
result?: {
|
|
@@ -3414,6 +3631,7 @@ export type components = {
|
|
|
3414
3631
|
contentSystemId: string;
|
|
3415
3632
|
/** @example posts */
|
|
3416
3633
|
collection: string;
|
|
3634
|
+
locale?: components['schemas']['LocaleClause'];
|
|
3417
3635
|
meta?: components['schemas']['RequestMeta'];
|
|
3418
3636
|
returning?: false | {
|
|
3419
3637
|
join?: components['schemas']['JoinClause'];
|
|
@@ -3421,7 +3639,6 @@ export type components = {
|
|
|
3421
3639
|
select?: components['schemas']['SelectClause'];
|
|
3422
3640
|
};
|
|
3423
3641
|
where: components['schemas']['WhereClause'];
|
|
3424
|
-
locale?: components['schemas']['LocaleClause'];
|
|
3425
3642
|
};
|
|
3426
3643
|
CountDocumentVersionResponse: {
|
|
3427
3644
|
result: {
|
|
@@ -3434,6 +3651,7 @@ export type components = {
|
|
|
3434
3651
|
contentSystemId: string;
|
|
3435
3652
|
/** @example posts */
|
|
3436
3653
|
collection: string;
|
|
3654
|
+
locale?: components['schemas']['LocaleClause'];
|
|
3437
3655
|
meta?: components['schemas']['RequestMeta'];
|
|
3438
3656
|
where?: components['schemas']['WhereClause'];
|
|
3439
3657
|
};
|
|
@@ -3495,6 +3713,8 @@ export type components = {
|
|
|
3495
3713
|
parent?: string | number;
|
|
3496
3714
|
version: components['schemas']['DocumentData'] & unknown;
|
|
3497
3715
|
};
|
|
3716
|
+
locale?: components['schemas']['LocaleClause'];
|
|
3717
|
+
meta?: components['schemas']['RequestMeta'];
|
|
3498
3718
|
returning?: false | {
|
|
3499
3719
|
join?: components['schemas']['JoinClause'];
|
|
3500
3720
|
locale?: components['schemas']['LocaleClause'];
|
|
@@ -3569,9 +3789,9 @@ export type components = {
|
|
|
3569
3789
|
where: components['schemas']['WhereClause'];
|
|
3570
3790
|
/** @example 10 */
|
|
3571
3791
|
limit?: number;
|
|
3792
|
+
locale?: components['schemas']['LocaleClause'];
|
|
3572
3793
|
meta?: components['schemas']['RequestMeta'];
|
|
3573
3794
|
sort?: components['schemas']['SortClause'];
|
|
3574
|
-
locale?: components['schemas']['LocaleClause'];
|
|
3575
3795
|
returning?: false | {
|
|
3576
3796
|
join?: components['schemas']['JoinClause'];
|
|
3577
3797
|
locale?: components['schemas']['LocaleClause'];
|
|
@@ -3594,6 +3814,7 @@ export type components = {
|
|
|
3594
3814
|
contentSystemId: string;
|
|
3595
3815
|
/** @example posts */
|
|
3596
3816
|
collection: string;
|
|
3817
|
+
locale?: components['schemas']['LocaleClause'];
|
|
3597
3818
|
meta?: components['schemas']['RequestMeta'];
|
|
3598
3819
|
returning?: false | {
|
|
3599
3820
|
join?: components['schemas']['JoinClause'];
|
|
@@ -62,18 +62,6 @@ function missingOAuthCredential(name) {
|
|
|
62
62
|
}
|
|
63
63
|
}
|
|
64
64
|
export async function buildFigmaConfig(config) {
|
|
65
|
-
// Auto-migrate old env vars in local dev (never in Lambda/production)
|
|
66
|
-
if (process.env.NODE_ENV !== 'production' && !process.env.AWS_LAMBDA_FUNCTION_NAME) {
|
|
67
|
-
try {
|
|
68
|
-
const { handleEnvUpgrade } = await import('../utils/handle-upgrade.js');
|
|
69
|
-
const upgradeChanges = await handleEnvUpgrade(process.cwd());
|
|
70
|
-
if (upgradeChanges.length > 0) {
|
|
71
|
-
log.warning(`Auto-migrated .env: ${upgradeChanges.join(', ')}`);
|
|
72
|
-
}
|
|
73
|
-
} catch {
|
|
74
|
-
// Never block config build due to upgrade check
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
65
|
const envConfig = getEnvConfig();
|
|
78
66
|
// Resolve contentSystemId: config first, then local store fallback (dev)
|
|
79
67
|
let { contentSystemId } = config.figma;
|
package/dist/types.d.ts
CHANGED
|
@@ -1,12 +1,9 @@
|
|
|
1
1
|
/**
|
|
2
|
-
*
|
|
3
|
-
* Non-blocking — returns list of changes made, never throws.
|
|
2
|
+
* Walk up from a directory to find the nearest package.json with name "@payloadcms/figma".
|
|
4
3
|
*/
|
|
5
|
-
export declare function
|
|
4
|
+
export declare function findPackageRoot(startDir: string): Promise<null | string>;
|
|
6
5
|
/**
|
|
7
|
-
*
|
|
8
|
-
* Called from CLI entry point before command routing.
|
|
9
|
-
* Non-blocking — returns list of changes made, never throws.
|
|
6
|
+
* Build and pack the local @payloadcms/figma package, returning the tgz path.
|
|
10
7
|
*/
|
|
11
|
-
export declare function
|
|
8
|
+
export declare function packLocalPackage(pkgDir: string): string;
|
|
12
9
|
//# sourceMappingURL=handle-upgrade.d.ts.map
|
|
@@ -1,36 +1,9 @@
|
|
|
1
1
|
import { execSync } from 'child_process';
|
|
2
2
|
import fs from 'fs/promises';
|
|
3
3
|
import path from 'path';
|
|
4
|
-
import { Project } from 'ts-morph';
|
|
5
|
-
import { fileURLToPath } from 'url';
|
|
6
|
-
import { getBootstrapInfo, getCmsResourceId } from '../api/control-plane.js';
|
|
7
|
-
import { getValidAccessToken } from '../auth/oauth-flow.js';
|
|
8
|
-
import { getTokenStore } from '../auth/token-store.js';
|
|
9
|
-
import { cacheAllEnvironments } from './cache-bootstrap.js';
|
|
10
|
-
import { addOrUpdateEnvVar, getEnvVar, removeEnvVar } from './env-management.js';
|
|
11
|
-
import { formatFile } from './formatter.js';
|
|
12
|
-
import * as log from './log.js';
|
|
13
|
-
import { getPackageManager } from './package-manager.js';
|
|
14
|
-
import { removeFigmaContentSystemId } from './payload-config-ast.js';
|
|
15
|
-
import { findPayloadConfig } from './payload-config-finder.js';
|
|
16
|
-
import { checkPackageInstalled, installPackage } from './payload-package-check.js';
|
|
17
|
-
import { getOwnVersion } from './version-check.js';
|
|
18
|
-
const OLD_ENV_VARS = [
|
|
19
|
-
'FIGMA_ENV',
|
|
20
|
-
'FIGMA_CONTENT_API_CONTENT_SYSTEM_ID',
|
|
21
|
-
'FIGMA_TENANT_ID',
|
|
22
|
-
'FIGMA_OAUTH_CLIENT_ID',
|
|
23
|
-
'FIGMA_OAUTH_CLIENT_SECRET'
|
|
24
|
-
];
|
|
25
|
-
const REMOVABLE_ENV_VARS = [
|
|
26
|
-
'FIGMA_CONTENT_API_CONTENT_SYSTEM_ID',
|
|
27
|
-
'FIGMA_TENANT_ID',
|
|
28
|
-
'FIGMA_OAUTH_CLIENT_ID',
|
|
29
|
-
'FIGMA_OAUTH_CLIENT_SECRET'
|
|
30
|
-
];
|
|
31
4
|
/**
|
|
32
5
|
* Walk up from a directory to find the nearest package.json with name "@payloadcms/figma".
|
|
33
|
-
*/ async function findPackageRoot(startDir) {
|
|
6
|
+
*/ export async function findPackageRoot(startDir) {
|
|
34
7
|
let dir = startDir;
|
|
35
8
|
while(true){
|
|
36
9
|
const pkgPath = path.join(dir, 'package.json');
|
|
@@ -51,7 +24,7 @@ const REMOVABLE_ENV_VARS = [
|
|
|
51
24
|
}
|
|
52
25
|
/**
|
|
53
26
|
* Build and pack the local @payloadcms/figma package, returning the tgz path.
|
|
54
|
-
*/ function packLocalPackage(pkgDir) {
|
|
27
|
+
*/ export function packLocalPackage(pkgDir) {
|
|
55
28
|
execSync('pnpm build', {
|
|
56
29
|
cwd: pkgDir,
|
|
57
30
|
stdio: 'pipe'
|
|
@@ -64,179 +37,5 @@ const REMOVABLE_ENV_VARS = [
|
|
|
64
37
|
const tgzPath = path.join(pkgDir, tgzName);
|
|
65
38
|
return tgzPath;
|
|
66
39
|
}
|
|
67
|
-
/**
|
|
68
|
-
* Attempt to resolve bootstrap data: check cache first, then API call.
|
|
69
|
-
*/ async function resolveBootstrapData(projectId, environmentName) {
|
|
70
|
-
const store = getTokenStore();
|
|
71
|
-
const cached = store.getBootstrapData(projectId, environmentName);
|
|
72
|
-
if (cached) {
|
|
73
|
-
return cached;
|
|
74
|
-
}
|
|
75
|
-
try {
|
|
76
|
-
const accessToken = await getValidAccessToken(store);
|
|
77
|
-
if (!accessToken) {
|
|
78
|
-
return null;
|
|
79
|
-
}
|
|
80
|
-
const bootstrapInfo = await getBootstrapInfo(accessToken, projectId);
|
|
81
|
-
cacheAllEnvironments(store, projectId, bootstrapInfo);
|
|
82
|
-
return store.getBootstrapData(projectId, environmentName);
|
|
83
|
-
} catch {
|
|
84
|
-
return null;
|
|
85
|
-
}
|
|
86
|
-
}
|
|
87
|
-
/**
|
|
88
|
-
* Migrate .env file from old env var format to new format.
|
|
89
|
-
* Non-blocking — returns list of changes made, never throws.
|
|
90
|
-
*/ export async function handleEnvUpgrade(projectPath) {
|
|
91
|
-
try {
|
|
92
|
-
const oldValues = {};
|
|
93
|
-
let hasOldVars = false;
|
|
94
|
-
for (const key of OLD_ENV_VARS){
|
|
95
|
-
const value = await getEnvVar(projectPath, key);
|
|
96
|
-
oldValues[key] = value;
|
|
97
|
-
if (value !== null) {
|
|
98
|
-
hasOldVars = true;
|
|
99
|
-
}
|
|
100
|
-
}
|
|
101
|
-
if (!hasOldVars) {
|
|
102
|
-
return [];
|
|
103
|
-
}
|
|
104
|
-
const changes = [];
|
|
105
|
-
// Rename FIGMA_ENV → FIGMA_INFRA_ENV
|
|
106
|
-
if (oldValues.FIGMA_ENV !== null) {
|
|
107
|
-
await addOrUpdateEnvVar(projectPath, 'FIGMA_INFRA_ENV', oldValues.FIGMA_ENV);
|
|
108
|
-
await removeEnvVar(projectPath, 'FIGMA_ENV');
|
|
109
|
-
changes.push('Renamed FIGMA_ENV → FIGMA_INFRA_ENV');
|
|
110
|
-
}
|
|
111
|
-
// Remove old vars if bootstrap data is available
|
|
112
|
-
const projectId = await getEnvVar(projectPath, 'FIGMA_PROJECT_ID');
|
|
113
|
-
const environmentName = await getEnvVar(projectPath, 'FIGMA_ENVIRONMENT_NAME') ?? 'production';
|
|
114
|
-
if (projectId) {
|
|
115
|
-
const bootstrapData = await resolveBootstrapData(projectId, environmentName);
|
|
116
|
-
if (bootstrapData) {
|
|
117
|
-
const removed = [];
|
|
118
|
-
for (const key of REMOVABLE_ENV_VARS){
|
|
119
|
-
if (oldValues[key] !== null) {
|
|
120
|
-
await removeEnvVar(projectPath, key);
|
|
121
|
-
removed.push(key);
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
if (removed.length > 0) {
|
|
125
|
-
changes.push(`Removed deprecated env vars: ${removed.join(', ')}`);
|
|
126
|
-
}
|
|
127
|
-
} else {
|
|
128
|
-
log.warning('Could not resolve bootstrap data — keeping deprecated env vars. ' + 'Run `npx @payloadcms/figma init` to complete migration.');
|
|
129
|
-
}
|
|
130
|
-
}
|
|
131
|
-
return changes;
|
|
132
|
-
} catch (error) {
|
|
133
|
-
log.warning(`Upgrade migration failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
134
|
-
return [];
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Full upgrade migration: .env + payload.config.ts AST changes + version sync.
|
|
139
|
-
* Called from CLI entry point before command routing.
|
|
140
|
-
* Non-blocking — returns list of changes made, never throws.
|
|
141
|
-
*/ export async function handleUpgrade(projectPath) {
|
|
142
|
-
const changes = await handleEnvUpgrade(projectPath);
|
|
143
|
-
// Resolve CMS Resource ID from old content system ID via dataset API
|
|
144
|
-
try {
|
|
145
|
-
const existingProjectId = await getEnvVar(projectPath, 'FIGMA_PROJECT_ID');
|
|
146
|
-
if (!existingProjectId) {
|
|
147
|
-
const oldContentSystemId = await getEnvVar(projectPath, 'FIGMA_CONTENT_API_CONTENT_SYSTEM_ID');
|
|
148
|
-
if (oldContentSystemId) {
|
|
149
|
-
const store = getTokenStore();
|
|
150
|
-
const accessToken = await getValidAccessToken(store);
|
|
151
|
-
if (accessToken) {
|
|
152
|
-
const cmsResourceId = await getCmsResourceId(accessToken, oldContentSystemId);
|
|
153
|
-
await addOrUpdateEnvVar(projectPath, 'FIGMA_PROJECT_ID', cmsResourceId);
|
|
154
|
-
await addOrUpdateEnvVar(projectPath, 'FIGMA_ENVIRONMENT_NAME', 'production');
|
|
155
|
-
changes.push('Resolved FIGMA_PROJECT_ID from content system ID');
|
|
156
|
-
// Fetch bootstrap data and cache it, then remove old vars
|
|
157
|
-
try {
|
|
158
|
-
const bootstrapInfo = await getBootstrapInfo(accessToken, cmsResourceId);
|
|
159
|
-
cacheAllEnvironments(store, cmsResourceId, bootstrapInfo);
|
|
160
|
-
const removed = [];
|
|
161
|
-
for (const key of REMOVABLE_ENV_VARS){
|
|
162
|
-
const value = await getEnvVar(projectPath, key);
|
|
163
|
-
if (value !== null) {
|
|
164
|
-
await removeEnvVar(projectPath, key);
|
|
165
|
-
removed.push(key);
|
|
166
|
-
}
|
|
167
|
-
}
|
|
168
|
-
if (removed.length > 0) {
|
|
169
|
-
changes.push(`Removed deprecated env vars: ${removed.join(', ')}`);
|
|
170
|
-
}
|
|
171
|
-
} catch {
|
|
172
|
-
log.warning('Could not fetch bootstrap data — keeping deprecated env vars. ' + 'Run `npx @payloadcms/figma init` to complete migration.');
|
|
173
|
-
}
|
|
174
|
-
} else {
|
|
175
|
-
log.warning('Not authenticated — could not resolve FIGMA_PROJECT_ID. ' + 'Run `npx @payloadcms/figma init` to complete migration.');
|
|
176
|
-
}
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
} catch (error) {
|
|
180
|
-
log.warning(`Project ID migration failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
181
|
-
}
|
|
182
|
-
try {
|
|
183
|
-
const configPath = await findPayloadConfig(projectPath);
|
|
184
|
-
if (configPath) {
|
|
185
|
-
const project = new Project({
|
|
186
|
-
skipAddingFilesFromTsConfig: true
|
|
187
|
-
});
|
|
188
|
-
const sourceFile = project.addSourceFileAtPath(configPath);
|
|
189
|
-
const removed = removeFigmaContentSystemId(sourceFile);
|
|
190
|
-
if (removed) {
|
|
191
|
-
await sourceFile.save();
|
|
192
|
-
try {
|
|
193
|
-
const packageManager = await getPackageManager(projectPath);
|
|
194
|
-
await formatFile(configPath, packageManager);
|
|
195
|
-
} catch {
|
|
196
|
-
// Formatting is best-effort
|
|
197
|
-
}
|
|
198
|
-
changes.push('Removed contentSystemId from payload.config.ts');
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
} catch (error) {
|
|
202
|
-
log.warning(`Config migration failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
203
|
-
}
|
|
204
|
-
// Sync @payloadcms/figma version in project's package.json
|
|
205
|
-
try {
|
|
206
|
-
const isInstalled = await checkPackageInstalled(projectPath, '@payloadcms/figma');
|
|
207
|
-
if (isInstalled) {
|
|
208
|
-
const cliDir = path.dirname(fileURLToPath(import.meta.url));
|
|
209
|
-
const isFromRegistry = cliDir.includes('node_modules') || cliDir.includes('.npm');
|
|
210
|
-
if (isFromRegistry) {
|
|
211
|
-
// Registry install: sync to CLI version
|
|
212
|
-
const cliVersion = await getOwnVersion();
|
|
213
|
-
const pkgJsonPath = path.join(projectPath, 'package.json');
|
|
214
|
-
const pkgJson = JSON.parse(await fs.readFile(pkgJsonPath, 'utf-8'));
|
|
215
|
-
const installedVersion = pkgJson.dependencies?.['@payloadcms/figma']?.replace(/^[\^~>=<]+/, '');
|
|
216
|
-
if (installedVersion && installedVersion !== cliVersion) {
|
|
217
|
-
const packageManager = await getPackageManager(projectPath);
|
|
218
|
-
await installPackage(projectPath, '@payloadcms/figma', packageManager, cliVersion);
|
|
219
|
-
changes.push(`Updated @payloadcms/figma ${installedVersion} → ${cliVersion}`);
|
|
220
|
-
}
|
|
221
|
-
} else {
|
|
222
|
-
// Local CLI: pack and install tgz into the project
|
|
223
|
-
const pkgDir = await findPackageRoot(cliDir);
|
|
224
|
-
if (pkgDir) {
|
|
225
|
-
log.debug('CLI running from local path — packing and installing into project...');
|
|
226
|
-
const packageManager = await getPackageManager(projectPath);
|
|
227
|
-
const tgzPath = packLocalPackage(pkgDir);
|
|
228
|
-
const destTgz = path.join(projectPath, path.basename(tgzPath));
|
|
229
|
-
await fs.rename(tgzPath, destTgz);
|
|
230
|
-
await installPackage(projectPath, destTgz, packageManager);
|
|
231
|
-
await fs.unlink(destTgz).catch(()=>{});
|
|
232
|
-
changes.push('Installed @payloadcms/figma from local build');
|
|
233
|
-
}
|
|
234
|
-
}
|
|
235
|
-
}
|
|
236
|
-
} catch (error) {
|
|
237
|
-
log.warning(`Package version sync failed: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
238
|
-
}
|
|
239
|
-
return changes;
|
|
240
|
-
}
|
|
241
40
|
|
|
242
41
|
//# sourceMappingURL=handle-upgrade.js.map
|
package/dist/utils/messages.js
CHANGED
|
@@ -17,6 +17,7 @@ export function helpMessage() {
|
|
|
17
17
|
${pc.cyan('debug')} Show debug info for troubleshooting
|
|
18
18
|
${pc.cyan('env')} Switch active environment
|
|
19
19
|
${pc.cyan('deploy')} Deploy your project to Figma
|
|
20
|
+
${pc.cyan('upgrade')} Run upgrade migrations
|
|
20
21
|
${pc.cyan('build-lambda-zip')} Build Lambda deployment zip
|
|
21
22
|
|
|
22
23
|
${pc.bold('OPTIONS')}
|
|
@@ -50,6 +51,11 @@ export function helpMessage() {
|
|
|
50
51
|
${pc.dim('--yes, -y')} Skip confirmation prompts
|
|
51
52
|
${pc.dim('--skip-build')} Skip building and use existing build
|
|
52
53
|
|
|
54
|
+
${pc.bold('UPGRADE COMMAND')}
|
|
55
|
+
|
|
56
|
+
${pc.cyan('@payloadcms/figma upgrade')} Run all upgrade migrations
|
|
57
|
+
${pc.dim('--dry-run')} Preview changes without applying
|
|
58
|
+
|
|
53
59
|
${pc.bold('GLOBAL OPTIONS')}
|
|
54
60
|
|
|
55
61
|
${pc.dim('--infra-env <env>')} Target infrastructure (production or staging)
|