@payloadcms/figma 0.0.1-alpha.50 → 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.
@@ -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: string;
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
@@ -7,6 +7,7 @@ import { addFigmaProperty, applyModifications, detectRequiredChanges } from './p
7
7
  import { findPayloadConfig } from './payload-config-finder.js';
8
8
  import { checkPackageInstalled, getPayloadVersion, installPackage, uninstallPackage } from './payload-package-check.js';
9
9
  import { runTypeScriptCheck } from './typescript-validator.js';
10
+ import { getOwnVersion } from './version-check.js';
10
11
  /**
11
12
  * Main orchestrator for payload config modification
12
13
  * Checks package, detects needed changes, applies modifications
@@ -36,7 +37,8 @@ import { runTypeScriptCheck } from './typescript-validator.js';
36
37
  if (!isInstalled) {
37
38
  log.debug('@payloadcms/figma not installed, attempting installation...');
38
39
  try {
39
- await installPackage(projectPath, '@payloadcms/figma', packageManager);
40
+ const figmaVersion = await getOwnVersion();
41
+ await installPackage(projectPath, '@payloadcms/figma', packageManager, figmaVersion);
40
42
  changes.push('Installed @payloadcms/figma');
41
43
  modified = true;
42
44
  log.debug('@payloadcms/figma installed successfully');
@@ -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
@@ -9,6 +9,7 @@ import { downloadTemplateFromGitHub } from './download-template.js';
9
9
  import { tryInitRepoAndCommit } from './git.js';
10
10
  import { applyLambdaModifications } from './lambda-config.js';
11
11
  import { getRunCommand } from './package-manager.js';
12
+ import { getOwnVersion } from './version-check.js';
12
13
  /**
13
14
  * Detect if current directory has a Payload project
14
15
  *
@@ -86,26 +87,28 @@ import { getRunCommand } from './package-manager.js';
86
87
  *
87
88
  * @param packageJson - Package JSON object to update
88
89
  * @param latestVersion - Latest Payload version to use
89
- */ function replaceWorkspaceVersions(packageJson, latestVersion) {
90
+ */ function replaceWorkspaceVersions(packageJson, latestVersion, figmaVersion) {
90
91
  const deps = packageJson.dependencies;
91
92
  if (!deps) {
92
93
  return;
93
94
  }
94
95
  for (const [key, value] of Object.entries(deps)){
95
- // Replace workspace:* or workspace:^ with actual version
96
- if (typeof value === 'string' && value.startsWith('workspace:')) {
96
+ if (key === '@payloadcms/figma') {
97
+ deps[key] = figmaVersion;
98
+ } else if (typeof value === 'string' && value.startsWith('workspace:')) {
97
99
  deps[key] = latestVersion;
98
100
  } else if (key === 'payload' || key.startsWith('@payloadcms/')) {
99
101
  deps[key] = latestVersion;
100
102
  }
101
103
  }
102
- // Also handle devDependencies if present
103
104
  const devDeps = packageJson.devDependencies;
104
105
  if (!devDeps) {
105
106
  return;
106
107
  }
107
108
  for (const [key, value] of Object.entries(devDeps)){
108
- if (typeof value === 'string' && value.startsWith('workspace:')) {
109
+ if (key === '@payloadcms/figma') {
110
+ devDeps[key] = figmaVersion;
111
+ } else if (typeof value === 'string' && value.startsWith('workspace:')) {
109
112
  devDeps[key] = latestVersion;
110
113
  } else if (key === 'payload' || key.startsWith('@payloadcms/')) {
111
114
  devDeps[key] = latestVersion;
@@ -127,8 +130,11 @@ import { getRunCommand } from './package-manager.js';
127
130
  // Apply Lambda modifications BEFORE updating package.json
128
131
  // This ensures we don't overwrite version replacements
129
132
  await applyLambdaModifications(projectPath, packageManager);
130
- // Get latest Payload version from npm
131
- const latestVersion = await getLatestPackageVersion('payload');
133
+ // Get latest Payload version from npm and CLI's own version
134
+ const [latestVersion, figmaVersion] = await Promise.all([
135
+ getLatestPackageVersion('payload'),
136
+ getOwnVersion()
137
+ ]);
132
138
  // Delete any existing lock files from template (they reference workspace:* versions)
133
139
  // This ensures pnpm install creates a fresh lock file with actual versions
134
140
  const lockFiles = [
@@ -150,7 +156,7 @@ import { getRunCommand } from './package-manager.js';
150
156
  const packageJson = JSON.parse(packageJsonContent);
151
157
  packageJson.name = projectName;
152
158
  // Replace workspace:* versions with actual versions
153
- replaceWorkspaceVersions(packageJson, latestVersion);
159
+ replaceWorkspaceVersions(packageJson, latestVersion, figmaVersion);
154
160
  await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
155
161
  // Ensure .gitignore has required entries
156
162
  // Note: .env file is created by init command with FIGMA_CONTENT_API_CONTENT_SYSTEM_ID
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/figma",
3
- "version": "0.0.1-alpha.50",
3
+ "version": "0.0.1-alpha.52",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "type": "module",
6
6
  "exports": {