@payloadcms/figma 0.0.1-alpha.51 → 0.0.1-alpha.52
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 +8 -0
- package/dist/api/control-plane.js +21 -0
- package/dist/cli.js +10 -0
- package/dist/plugin/build-config.d.ts +4 -9
- package/dist/plugin/build-config.js +12 -0
- package/dist/utils/env-management.d.ts +8 -0
- package/dist/utils/env-management.js +34 -0
- package/dist/utils/handle-upgrade.d.ts +12 -0
- package/dist/utils/handle-upgrade.js +242 -0
- package/dist/utils/payload-config-ast.d.ts +7 -0
- package/dist/utils/payload-config-ast.js +34 -0
- package/dist/utils/payload-package-check.js +1 -1
- package/package.json +1 -1
|
@@ -151,4 +151,12 @@ export type BootstrapInfo = {
|
|
|
151
151
|
* @param environmentName - Optional environment name filter
|
|
152
152
|
*/
|
|
153
153
|
export declare function getBootstrapInfo(accessToken: string, cmsResourceId: string, environmentName?: string): Promise<BootstrapInfo>;
|
|
154
|
+
/**
|
|
155
|
+
* Resolve a CMS Resource ID from a legacy dataset (content system) ID.
|
|
156
|
+
* Maps to: GET /v1/cms/dataset/:datasetId
|
|
157
|
+
*
|
|
158
|
+
* Used during upgrade migration to convert old FIGMA_CONTENT_API_CONTENT_SYSTEM_ID
|
|
159
|
+
* into the new FIGMA_PROJECT_ID (CMS Resource ID).
|
|
160
|
+
*/
|
|
161
|
+
export declare function getCmsResourceId(accessToken: string, datasetId: string): Promise<string>;
|
|
154
162
|
//# sourceMappingURL=control-plane.d.ts.map
|
|
@@ -276,6 +276,27 @@ import * as log from '../utils/log.js';
|
|
|
276
276
|
}
|
|
277
277
|
};
|
|
278
278
|
}
|
|
279
|
+
/**
|
|
280
|
+
* Resolve a CMS Resource ID from a legacy dataset (content system) ID.
|
|
281
|
+
* Maps to: GET /v1/cms/dataset/:datasetId
|
|
282
|
+
*
|
|
283
|
+
* Used during upgrade migration to convert old FIGMA_CONTENT_API_CONTENT_SYSTEM_ID
|
|
284
|
+
* into the new FIGMA_PROJECT_ID (CMS Resource ID).
|
|
285
|
+
*/ export async function getCmsResourceId(accessToken, datasetId) {
|
|
286
|
+
const url = `${getControlPlaneBaseUrl()}/v1/cms/dataset/${datasetId}`;
|
|
287
|
+
log.debug(`Calling getCmsResourceId API at ${url}`);
|
|
288
|
+
const response = await controlPlaneFetch({
|
|
289
|
+
context: 'get CMS resource ID from dataset',
|
|
290
|
+
options: {
|
|
291
|
+
headers: {
|
|
292
|
+
Authorization: `Bearer ${accessToken}`
|
|
293
|
+
}
|
|
294
|
+
},
|
|
295
|
+
url
|
|
296
|
+
});
|
|
297
|
+
const data = await response.json();
|
|
298
|
+
return data.meta.cms_resource_id;
|
|
299
|
+
}
|
|
279
300
|
const MAX_RETRIES = 3;
|
|
280
301
|
const INITIAL_RETRY_DELAY = 1000;
|
|
281
302
|
function sleep(ms) {
|
package/dist/cli.js
CHANGED
|
@@ -10,6 +10,7 @@ import { listTokensCommand } from './commands/list-tokens.js';
|
|
|
10
10
|
import { loginCommand } from './commands/login.js';
|
|
11
11
|
import { logoutCommand } from './commands/logout.js';
|
|
12
12
|
import { setInfraEnvironment } from './constants.js';
|
|
13
|
+
import { handleUpgrade } from './utils/handle-upgrade.js';
|
|
13
14
|
import { helpMessage } from './utils/messages.js';
|
|
14
15
|
/**
|
|
15
16
|
* Entrypoint for bin/cli.js
|
|
@@ -85,6 +86,15 @@ class Main {
|
|
|
85
86
|
helpMessage();
|
|
86
87
|
process.exit(0);
|
|
87
88
|
}
|
|
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
|
+
}
|
|
88
98
|
// Debug command outputs plain text for copy-paste — skip styled intro
|
|
89
99
|
if (subcommand === 'debug') {
|
|
90
100
|
await debugCommand();
|
|
@@ -8,20 +8,16 @@ import type { Config, SanitizedConfig } from 'payload';
|
|
|
8
8
|
* - `editor`: Optional (defaults to lexicalEditor() if not provided)
|
|
9
9
|
*
|
|
10
10
|
* @example
|
|
11
|
-
* // Minimal config
|
|
11
|
+
* // Minimal config (contentSystemId resolved from bootstrap data)
|
|
12
12
|
* const config: FigmaConfig = {
|
|
13
|
-
* figma: {
|
|
14
|
-
* contentSystemId: process.env.FIGMA_CONTENT_API_CONTENT_SYSTEM_ID!
|
|
15
|
-
* },
|
|
13
|
+
* figma: {},
|
|
16
14
|
* collections: [...]
|
|
17
15
|
* }
|
|
18
16
|
*
|
|
19
17
|
* @example
|
|
20
18
|
* // With custom editor
|
|
21
19
|
* const config: FigmaConfig = {
|
|
22
|
-
* figma: {
|
|
23
|
-
* contentSystemId: process.env.FIGMA_CONTENT_API_CONTENT_SYSTEM_ID!
|
|
24
|
-
* },
|
|
20
|
+
* figma: {},
|
|
25
21
|
* collections: [...],
|
|
26
22
|
* editor: lexicalEditor({ features: [...] })
|
|
27
23
|
* }
|
|
@@ -30,7 +26,6 @@ import type { Config, SanitizedConfig } from 'payload';
|
|
|
30
26
|
* // Disable Content System (use custom db)
|
|
31
27
|
* const config: FigmaConfig = {
|
|
32
28
|
* figma: {
|
|
33
|
-
* contentSystemId: process.env.FIGMA_CONTENT_API_CONTENT_SYSTEM_ID!,
|
|
34
29
|
* useContentSystem: false
|
|
35
30
|
* },
|
|
36
31
|
* db: mongooseAdapter({ url: process.env.DATABASE_URI }),
|
|
@@ -41,7 +36,7 @@ export type FigmaConfig = {
|
|
|
41
36
|
editor?: Config['editor'];
|
|
42
37
|
} & {
|
|
43
38
|
figma: {
|
|
44
|
-
contentSystemId
|
|
39
|
+
contentSystemId?: string;
|
|
45
40
|
storage?: boolean;
|
|
46
41
|
useContentSystem?: boolean;
|
|
47
42
|
};
|
|
@@ -62,6 +62,18 @@ 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
|
+
}
|
|
65
77
|
const envConfig = getEnvConfig();
|
|
66
78
|
// Resolve contentSystemId: config first, then local store fallback (dev)
|
|
67
79
|
let { contentSystemId } = config.figma;
|
|
@@ -22,4 +22,12 @@ export declare function getEnvVarSync(projectPath: string, key: string): null |
|
|
|
22
22
|
* @param value - Environment variable value
|
|
23
23
|
*/
|
|
24
24
|
export declare function addOrUpdateEnvVar(projectPath: string, key: string, value: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Remove an environment variable from .env file
|
|
27
|
+
*
|
|
28
|
+
* @param projectPath - Path to project directory
|
|
29
|
+
* @param key - Environment variable name to remove
|
|
30
|
+
* @returns true if key was found and removed, false otherwise
|
|
31
|
+
*/
|
|
32
|
+
export declare function removeEnvVar(projectPath: string, key: string): Promise<boolean>;
|
|
25
33
|
//# sourceMappingURL=env-management.d.ts.map
|
|
@@ -115,5 +115,39 @@ import path from 'path';
|
|
|
115
115
|
throw new Error(`Failed to update .env file: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
116
116
|
}
|
|
117
117
|
}
|
|
118
|
+
/**
|
|
119
|
+
* Remove an environment variable from .env file
|
|
120
|
+
*
|
|
121
|
+
* @param projectPath - Path to project directory
|
|
122
|
+
* @param key - Environment variable name to remove
|
|
123
|
+
* @returns true if key was found and removed, false otherwise
|
|
124
|
+
*/ export async function removeEnvVar(projectPath, key) {
|
|
125
|
+
const envPath = path.join(projectPath, '.env');
|
|
126
|
+
try {
|
|
127
|
+
const contents = await fs.readFile(envPath, 'utf-8');
|
|
128
|
+
const lines = contents.split(/\r?\n/);
|
|
129
|
+
const filteredLines = [];
|
|
130
|
+
let found = false;
|
|
131
|
+
for (const line of lines){
|
|
132
|
+
if (line.trim() && !line.trim().startsWith('#') && line.includes('=')) {
|
|
133
|
+
const equalsIndex = line.indexOf('=');
|
|
134
|
+
const lineKey = line.substring(0, equalsIndex).trim();
|
|
135
|
+
if (lineKey === key) {
|
|
136
|
+
found = true;
|
|
137
|
+
continue;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
filteredLines.push(line);
|
|
141
|
+
}
|
|
142
|
+
if (found) {
|
|
143
|
+
// Collapse consecutive blank lines and trim leading/trailing blank lines
|
|
144
|
+
const collapsed = filteredLines.join('\n').replace(/\n{3,}/g, '\n\n').replace(/^\n+/, '');
|
|
145
|
+
await fs.writeFile(envPath, collapsed, 'utf-8');
|
|
146
|
+
}
|
|
147
|
+
return found;
|
|
148
|
+
} catch {
|
|
149
|
+
return false;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
118
152
|
|
|
119
153
|
//# sourceMappingURL=env-management.js.map
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Migrate .env file from old env var format to new format.
|
|
3
|
+
* Non-blocking — returns list of changes made, never throws.
|
|
4
|
+
*/
|
|
5
|
+
export declare function handleEnvUpgrade(projectPath: string): Promise<string[]>;
|
|
6
|
+
/**
|
|
7
|
+
* Full upgrade migration: .env + payload.config.ts AST changes + version sync.
|
|
8
|
+
* Called from CLI entry point before command routing.
|
|
9
|
+
* Non-blocking — returns list of changes made, never throws.
|
|
10
|
+
*/
|
|
11
|
+
export declare function handleUpgrade(projectPath: string): Promise<string[]>;
|
|
12
|
+
//# sourceMappingURL=handle-upgrade.d.ts.map
|
|
@@ -0,0 +1,242 @@
|
|
|
1
|
+
import { execSync } from 'child_process';
|
|
2
|
+
import fs from 'fs/promises';
|
|
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
|
+
/**
|
|
32
|
+
* Walk up from a directory to find the nearest package.json with name "@payloadcms/figma".
|
|
33
|
+
*/ async function findPackageRoot(startDir) {
|
|
34
|
+
let dir = startDir;
|
|
35
|
+
while(true){
|
|
36
|
+
const pkgPath = path.join(dir, 'package.json');
|
|
37
|
+
try {
|
|
38
|
+
const pkg = JSON.parse(await fs.readFile(pkgPath, 'utf-8'));
|
|
39
|
+
if (pkg.name === '@payloadcms/figma') {
|
|
40
|
+
return dir;
|
|
41
|
+
}
|
|
42
|
+
} catch {
|
|
43
|
+
// No package.json here
|
|
44
|
+
}
|
|
45
|
+
const parent = path.dirname(dir);
|
|
46
|
+
if (parent === dir) {
|
|
47
|
+
return null;
|
|
48
|
+
}
|
|
49
|
+
dir = parent;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
/**
|
|
53
|
+
* Build and pack the local @payloadcms/figma package, returning the tgz path.
|
|
54
|
+
*/ function packLocalPackage(pkgDir) {
|
|
55
|
+
execSync('pnpm build', {
|
|
56
|
+
cwd: pkgDir,
|
|
57
|
+
stdio: 'pipe'
|
|
58
|
+
});
|
|
59
|
+
const tgzOutput = execSync('pnpm pack', {
|
|
60
|
+
cwd: pkgDir,
|
|
61
|
+
stdio: 'pipe'
|
|
62
|
+
}).toString().trim();
|
|
63
|
+
const tgzName = tgzOutput.split('\n').pop();
|
|
64
|
+
const tgzPath = path.join(pkgDir, tgzName);
|
|
65
|
+
return tgzPath;
|
|
66
|
+
}
|
|
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
|
+
|
|
242
|
+
//# sourceMappingURL=handle-upgrade.js.map
|
|
@@ -62,4 +62,11 @@ export declare function addFigmaProperty(sourceFile: SourceFile, config: FigmaPr
|
|
|
62
62
|
* Returns the figma object if it exists, null otherwise
|
|
63
63
|
*/
|
|
64
64
|
export declare function readFigmaConfig(sourceFile: SourceFile): FigmaPropertyConfig | null;
|
|
65
|
+
/**
|
|
66
|
+
* Remove the contentSystemId property from figma config object.
|
|
67
|
+
* Used during upgrade migration — contentSystemId is now resolved from bootstrap data.
|
|
68
|
+
*
|
|
69
|
+
* @returns true if the property was found and removed
|
|
70
|
+
*/
|
|
71
|
+
export declare function removeFigmaContentSystemId(sourceFile: SourceFile): boolean;
|
|
65
72
|
//# sourceMappingURL=payload-config-ast.d.ts.map
|
|
@@ -472,5 +472,39 @@ import * as log from './log.js';
|
|
|
472
472
|
useContentSystem
|
|
473
473
|
};
|
|
474
474
|
}
|
|
475
|
+
/**
|
|
476
|
+
* Remove the contentSystemId property from figma config object.
|
|
477
|
+
* Used during upgrade migration — contentSystemId is now resolved from bootstrap data.
|
|
478
|
+
*
|
|
479
|
+
* @returns true if the property was found and removed
|
|
480
|
+
*/ export function removeFigmaContentSystemId(sourceFile) {
|
|
481
|
+
const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);
|
|
482
|
+
const buildConfigCall = callExpressions.find((ce)=>{
|
|
483
|
+
const expr = ce.getExpression();
|
|
484
|
+
const text = expr.getText();
|
|
485
|
+
return text === 'buildFigmaConfig' || text.endsWith('.buildFigmaConfig');
|
|
486
|
+
});
|
|
487
|
+
if (!buildConfigCall) {
|
|
488
|
+
return false;
|
|
489
|
+
}
|
|
490
|
+
const configArg = buildConfigCall.getArguments()[0];
|
|
491
|
+
if (!configArg || !Node.isObjectLiteralExpression(configArg)) {
|
|
492
|
+
return false;
|
|
493
|
+
}
|
|
494
|
+
const figmaProperty = configArg.getProperty('figma');
|
|
495
|
+
if (!figmaProperty || !Node.isPropertyAssignment(figmaProperty)) {
|
|
496
|
+
return false;
|
|
497
|
+
}
|
|
498
|
+
const initializer = figmaProperty.getInitializer();
|
|
499
|
+
if (!initializer || !Node.isObjectLiteralExpression(initializer)) {
|
|
500
|
+
return false;
|
|
501
|
+
}
|
|
502
|
+
const contentSystemIdProp = initializer.getProperty('contentSystemId');
|
|
503
|
+
if (!contentSystemIdProp) {
|
|
504
|
+
return false;
|
|
505
|
+
}
|
|
506
|
+
contentSystemIdProp.remove();
|
|
507
|
+
return true;
|
|
508
|
+
}
|
|
475
509
|
|
|
476
510
|
//# sourceMappingURL=payload-config-ast.js.map
|
|
@@ -42,7 +42,7 @@ import * as log from './log.js';
|
|
|
42
42
|
*/ export async function installPackage(projectPath, packageName, packageManager, version = 'latest') {
|
|
43
43
|
return new Promise((resolve, reject)=>{
|
|
44
44
|
const command = packageManager;
|
|
45
|
-
const packageSpec = `${packageName}@${version}`;
|
|
45
|
+
const packageSpec = packageName.endsWith('.tgz') ? packageName : `${packageName}@${version}`;
|
|
46
46
|
const args = [
|
|
47
47
|
'add',
|
|
48
48
|
packageSpec
|