@payloadcms/figma 0.0.1-alpha.55 → 0.0.1-alpha.57

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.
Files changed (37) hide show
  1. package/dist/auth/crypto-utils.d.ts +6 -0
  2. package/dist/auth/crypto-utils.js +11 -9
  3. package/dist/auth/oauth-flow.d.ts +5 -0
  4. package/dist/auth/oauth-flow.js +20 -3
  5. package/dist/auth/token-store.d.ts +2 -0
  6. package/dist/auth/token-store.js +57 -13
  7. package/dist/cli.js +3 -0
  8. package/dist/commands/debug.js +15 -0
  9. package/dist/commands/deploy.js +12 -7
  10. package/dist/commands/init.js +63 -55
  11. package/dist/constants.d.ts +9 -1
  12. package/dist/constants.js +16 -1
  13. package/dist/db-content-api/index.d.ts +1 -0
  14. package/dist/db-content-api/index.js +53 -7
  15. package/dist/db-content-api/utilities/data/index.d.ts +7 -0
  16. package/dist/db-content-api/utilities/data/index.js +36 -4
  17. package/dist/db-content-api/utilities/meta/buildMeta.d.ts +5 -0
  18. package/dist/db-content-api/utilities/meta/buildMeta.js +9 -1
  19. package/dist/db-content-api/utilities/meta/buildUniquePaths.d.ts +13 -0
  20. package/dist/db-content-api/utilities/meta/buildUniquePaths.js +62 -0
  21. package/dist/db-content-api/utilities/where.js +7 -1
  22. package/dist/deploy/schedule-extract-plugin.d.ts +11 -0
  23. package/dist/deploy/schedule-extract-plugin.js +34 -0
  24. package/dist/plugin/build-config.d.ts +2 -1
  25. package/dist/plugin/build-config.js +4 -1
  26. package/dist/types.d.ts +4 -0
  27. package/dist/utils/build-lambda-zip.js +1 -1
  28. package/dist/utils/formatter.js +20 -6
  29. package/dist/utils/lambda-config.js +69 -67
  30. package/dist/utils/messages.d.ts +0 -1
  31. package/dist/utils/messages.js +1 -3
  32. package/dist/utils/payload-config-ast.d.ts +0 -5
  33. package/dist/utils/payload-config-ast.js +7 -76
  34. package/dist/utils/payload-config-modifier.js +9 -1
  35. package/dist/utils/resolve-environment.d.ts +1 -1
  36. package/dist/utils/resolve-environment.js +4 -1
  37. package/package.json +1 -2
@@ -1,6 +1,6 @@
1
- import { parseModule, Syntax } from 'esprima-next';
2
1
  import fs from 'fs/promises';
3
2
  import path from 'path';
3
+ import { IndentationText, Node, Project, SyntaxKind } from 'ts-morph';
4
4
  const RUN_SH_CONTENT = `#!/bin/bash -x
5
5
 
6
6
  [ ! -d '/tmp/cache' ] && mkdir -p /tmp/cache
@@ -36,11 +36,11 @@ NODE_ENV=production exec node server.js
36
36
  await addLambdaBuildScript(projectPath, packageManager);
37
37
  }
38
38
  /**
39
- * Find the Next.js config file (next.config.js or next.config.mjs)
40
- *
41
- * @todo Support TypeScript config files in future
39
+ * Find the Next.js config file, checking TS extensions first
42
40
  */ async function findNextConfigPath(projectPath) {
43
41
  const configFiles = [
42
+ 'next.config.ts',
43
+ 'next.config.mts',
44
44
  'next.config.js',
45
45
  'next.config.mjs'
46
46
  ];
@@ -53,83 +53,85 @@ NODE_ENV=production exec node server.js
53
53
  // File doesn't exist, try next one
54
54
  }
55
55
  }
56
- throw new Error('Could not find next.config.js or next.config.mjs');
56
+ throw new Error('Could not find next.config.ts, next.config.mts, next.config.js, or next.config.mjs');
57
57
  }
58
58
  /**
59
- * Add required Next.js config properties using AST parsing
59
+ * Add required Next.js config properties using ts-morph AST parsing
60
60
  * - output: 'standalone' (for Lambda deployment)
61
61
  * - eslint: { ignoreDuringBuilds: true } (allow builds with lint errors)
62
62
  */ async function addNextConfigProperties(projectPath) {
63
63
  const nextConfigPath = await findNextConfigPath(projectPath);
64
- const content = await fs.readFile(nextConfigPath, 'utf-8');
65
- // Check which properties already exist
66
- const hasOutput = content.includes('output:');
67
- const hasEslint = content.includes('eslint:');
68
- // Early exit if both already configured
69
- if (hasOutput && hasEslint) {
70
- return;
71
- }
72
- const ast = parseModule(content, {
73
- loc: true
64
+ const project = new Project({
65
+ compilerOptions: {
66
+ allowJs: true
67
+ },
68
+ manipulationSettings: {
69
+ indentationText: IndentationText.TwoSpaces
70
+ },
71
+ skipAddingFilesFromTsConfig: true
74
72
  });
75
- // Find export default declaration
76
- const exportDefaultDeclaration = ast.body.find((p)=>p.type === Syntax.ExportDefaultDeclaration);
77
- if (!exportDefaultDeclaration?.declaration?.loc) {
78
- throw new Error(`Could not find export default declaration in ${path.basename(nextConfigPath)}`);
79
- }
80
- // Find the object expression to modify
81
- let targetObjectExpression;
82
- if (exportDefaultDeclaration.declaration.type === 'ObjectExpression') {
83
- // Direct export: export default { ... }
84
- targetObjectExpression = exportDefaultDeclaration.declaration;
85
- } else if (exportDefaultDeclaration.declaration.type === 'CallExpression') {
86
- // Wrapped export: export default withPayload(nextConfig, ...)
87
- const callExpr = exportDefaultDeclaration.declaration;
88
- const firstArg = callExpr.arguments?.[0];
89
- if (firstArg?.type === 'Identifier') {
90
- // Find the variable declaration for this identifier
91
- const configVarName = firstArg.name;
92
- const varDeclaration = ast.body.find((node)=>{
93
- if (node.type === Syntax.VariableDeclaration) {
94
- const varNode = node;
95
- return varNode.declarations?.some((decl)=>decl.id?.type === 'Identifier' && decl.id.name === configVarName && decl.init?.type === 'ObjectExpression');
96
- }
97
- return false;
98
- });
99
- if (varDeclaration) {
100
- const declarator = varDeclaration.declarations?.find((decl)=>decl.id?.type === 'Identifier' && decl.id.name === configVarName);
101
- if (declarator?.init?.type === 'ObjectExpression') {
102
- targetObjectExpression = declarator.init;
103
- }
104
- }
105
- }
106
- }
107
- if (!targetObjectExpression?.loc) {
73
+ const sourceFile = project.addSourceFileAtPath(nextConfigPath);
74
+ // Find the config object to modify
75
+ const configObject = findConfigObject(sourceFile);
76
+ if (!configObject) {
108
77
  throw new Error(`Could not find Next.js config object in ${path.basename(nextConfigPath)}. ` + `Expected either 'export default { ... }' or 'export default wrapper(configVar, ...)'`);
109
78
  }
110
- const { loc } = targetObjectExpression;
111
- const lines = content.split(/\r?\n/);
112
- // Build insertion string based on what's missing
113
- const parts = [];
79
+ // Check which properties already exist using AST (avoids false positives from comments)
80
+ const hasOutput = configObject.getProperty('output') !== undefined;
81
+ const hasEslint = configObject.getProperty('eslint') !== undefined;
82
+ if (hasOutput && hasEslint) {
83
+ return;
84
+ }
114
85
  if (!hasOutput) {
115
- parts.push("output: 'standalone',");
86
+ configObject.addPropertyAssignment({
87
+ name: 'output',
88
+ initializer: "'standalone'"
89
+ });
116
90
  }
117
91
  if (!hasEslint) {
118
- parts.push(`eslint: {
119
- ignoreDuringBuilds: true,
120
- },`);
92
+ configObject.addPropertyAssignment({
93
+ name: 'eslint',
94
+ initializer: `{ ignoreDuringBuilds: true }`
95
+ });
96
+ }
97
+ await sourceFile.save();
98
+ }
99
+ /**
100
+ * Find the config object literal from either:
101
+ * - Direct export: `export default { ... }`
102
+ * - Wrapped export: `export default withPayload(configVar, ...)`
103
+ * where configVar is a variable declaration with an object literal
104
+ */ function findConfigObject(sourceFile) {
105
+ const exportDefault = sourceFile.getFirstDescendantByKind(SyntaxKind.ExportAssignment);
106
+ if (!exportDefault) {
107
+ return undefined;
108
+ }
109
+ const expression = exportDefault.getExpression();
110
+ // Direct export: export default { ... }
111
+ if (Node.isObjectLiteralExpression(expression)) {
112
+ return expression;
121
113
  }
122
- const insertString = '\n ' + parts.join('\n ');
123
- // Insert after opening brace
124
- const insertLine = loc.start.line - 1;
125
- const insertColumn = loc.start.column + 1;
126
- const targetLine = lines[insertLine];
127
- if (!targetLine) {
128
- throw new Error(`Could not find target line in ${path.basename(nextConfigPath)}`);
114
+ // Wrapped export: export default withPayload(configVar, ...)
115
+ if (Node.isCallExpression(expression)) {
116
+ const firstArg = expression.getArguments()[0];
117
+ // Variable reference: export default withPayload(configVar)
118
+ if (firstArg && Node.isIdentifier(firstArg)) {
119
+ const configVarName = firstArg.getText();
120
+ // Find the variable declaration
121
+ const varStatements = sourceFile.getVariableStatements();
122
+ for (const statement of varStatements){
123
+ for (const decl of statement.getDeclarations()){
124
+ if (decl.getName() === configVarName) {
125
+ const initializer = decl.getInitializer();
126
+ if (initializer && Node.isObjectLiteralExpression(initializer)) {
127
+ return initializer;
128
+ }
129
+ }
130
+ }
131
+ }
132
+ }
129
133
  }
130
- lines[insertLine] = targetLine.slice(0, insertColumn) + insertString + targetLine.slice(insertColumn);
131
- const modifiedContent = lines.join('\n');
132
- await fs.writeFile(nextConfigPath, modifiedContent, 'utf-8');
134
+ return undefined;
133
135
  }
134
136
  /**
135
137
  * Add lambda:buildzip script to package.json
@@ -6,5 +6,4 @@ export declare function moveMessage(args: {
6
6
  nextAppDir: string;
7
7
  projectDir: string;
8
8
  }): string;
9
- export declare function feedbackOutro(): string;
10
9
  //# sourceMappingURL=messages.d.ts.map
@@ -36,6 +36,7 @@ export function helpMessage() {
36
36
 
37
37
  ${pc.cyan('@payloadcms/figma init --id <cms-resource-id>')} Initialize project
38
38
  ${pc.cyan('@payloadcms/figma init --id <id> --env staging')} Initialize for specific environment
39
+ ${pc.dim('--name, -n <name>')} Set project directory name (skips prompt)
39
40
  ${pc.dim('--force')} Force reconfiguration of existing project
40
41
 
41
42
  ${pc.bold('ENV COMMAND')}
@@ -109,8 +110,5 @@ It is recommended to do this from your IDE if your app has existing file referen
109
110
  Once moved, rerun the @payloadcms/figma command again.
110
111
  `;
111
112
  }
112
- export function feedbackOutro() {
113
- return `${pc.bgCyan(pc.black(' Have feedback? '))} Visit us on ${createTerminalLink('GitHub', 'https://github.com/payloadcms/payload')}.`;
114
- }
115
113
 
116
114
  //# sourceMappingURL=messages.js.map
@@ -57,11 +57,6 @@ export type FigmaPropertyConfig = {
57
57
  * Modifies the AST in memory - caller must call sourceFile.save()
58
58
  */
59
59
  export declare function addFigmaProperty(sourceFile: SourceFile, config: FigmaPropertyConfig): ASTModificationResult;
60
- /**
61
- * Read figma configuration from payload.config.ts
62
- * Returns the figma object if it exists, null otherwise
63
- */
64
- export declare function readFigmaConfig(sourceFile: SourceFile): FigmaPropertyConfig | null;
65
60
  /**
66
61
  * Remove the contentSystemId property from figma config object.
67
62
  * Used during upgrade migration — contentSystemId is now resolved from bootstrap data.
@@ -385,14 +385,9 @@ import * as log from './log.js';
385
385
  };
386
386
  }
387
387
  // Add figma property
388
- // Note: useContentSystem is optional and defaults to true, so we don't generate it during init
389
- // contentSystemId is stored in .env file and referenced via process.env with non-null assertion
390
- const figmaObj = config.useContentSystem === false ? `{
391
- contentSystemId: process.env.FIGMA_CONTENT_API_CONTENT_SYSTEM_ID!,
392
- useContentSystem: false,
393
- }` : `{
394
- contentSystemId: process.env.FIGMA_CONTENT_API_CONTENT_SYSTEM_ID!,
395
- }`;
388
+ // contentSystemId is resolved automatically by buildFigmaConfig from env vars or bootstrap cache.
389
+ // useContentSystem defaults to true, so we only generate it when explicitly false.
390
+ const figmaObj = config.useContentSystem === false ? `{\nuseContentSystem: false,\n}` : '{}';
396
391
  configArg.addPropertyAssignment({
397
392
  name: 'figma',
398
393
  initializer: figmaObj
@@ -404,74 +399,6 @@ import * as log from './log.js';
404
399
  modified
405
400
  };
406
401
  }
407
- /**
408
- * Read figma configuration from payload.config.ts
409
- * Returns the figma object if it exists, null otherwise
410
- */ export function readFigmaConfig(sourceFile) {
411
- // Find buildFigmaConfig call (this function is only used with Figma configs)
412
- const callExpressions = sourceFile.getDescendantsOfKind(SyntaxKind.CallExpression);
413
- const buildConfigCall = callExpressions.find((ce)=>{
414
- const expr = ce.getExpression();
415
- const text = expr.getText();
416
- return text === 'buildFigmaConfig' || text.endsWith('.buildFigmaConfig');
417
- });
418
- if (!buildConfigCall) {
419
- log.debug('No buildFigmaConfig call found');
420
- return null;
421
- }
422
- // Get config object argument
423
- const configArg = buildConfigCall.getArguments()[0];
424
- if (!configArg || !Node.isObjectLiteralExpression(configArg)) {
425
- log.debug('buildConfig argument is not an object literal');
426
- return null;
427
- }
428
- // Find figma property
429
- const figmaProperty = configArg.getProperty('figma');
430
- if (!figmaProperty || !Node.isPropertyAssignment(figmaProperty)) {
431
- log.debug('No figma property found in buildConfig');
432
- return null;
433
- }
434
- // Get initializer (the object value)
435
- const initializer = figmaProperty.getInitializer();
436
- if (!initializer || !Node.isObjectLiteralExpression(initializer)) {
437
- log.debug('figma property is not an object literal');
438
- return null;
439
- }
440
- // Extract values
441
- const contentSystemIdProp = initializer.getProperty('contentSystemId');
442
- const useContentSystemProp = initializer.getProperty('useContentSystem');
443
- if (!contentSystemIdProp) {
444
- log.debug('Missing required figma property: contentSystemId');
445
- return null;
446
- }
447
- // Extract contentSystemId - support both literal strings and env var references
448
- let contentSystemId;
449
- if (Node.isPropertyAssignment(contentSystemIdProp)) {
450
- const initializer = contentSystemIdProp.getInitializer();
451
- const text = initializer?.getText() || '';
452
- // Support both patterns:
453
- // 1. Literal string: 'cms_abc123' or "cms_abc123"
454
- // 2. Environment variable: process.env.FIGMA_CONTENT_API_CONTENT_SYSTEM_ID
455
- if (text.includes('process.env.FIGMA_CONTENT_API_CONTENT_SYSTEM_ID')) {
456
- // For env var reference, return a marker that indicates it's from env
457
- // The actual value will be read at runtime
458
- contentSystemId = 'process.env.FIGMA_CONTENT_API_CONTENT_SYSTEM_ID';
459
- } else {
460
- // Remove quotes for literal strings
461
- contentSystemId = text.replace(/['"]/g, '');
462
- }
463
- }
464
- const useContentSystem = Node.isPropertyAssignment(useContentSystemProp) ? useContentSystemProp.getInitializer()?.getText() === 'true' : undefined // Optional: undefined if not specified
465
- ;
466
- if (!contentSystemId) {
467
- log.debug('Could not extract contentSystemId value');
468
- return null;
469
- }
470
- return {
471
- contentSystemId,
472
- useContentSystem
473
- };
474
- }
475
402
  /**
476
403
  * Remove the contentSystemId property from figma config object.
477
404
  * Used during upgrade migration — contentSystemId is now resolved from bootstrap data.
@@ -504,6 +431,10 @@ import * as log from './log.js';
504
431
  return false;
505
432
  }
506
433
  contentSystemIdProp.remove();
434
+ // Collapse empty object to avoid ts-morph whitespace artifacts
435
+ if (initializer.getProperties().length === 0) {
436
+ initializer.replaceWithText('{}');
437
+ }
507
438
  return true;
508
439
  }
509
440
 
@@ -1,5 +1,5 @@
1
1
  import pc from 'picocolors';
2
- import { Project } from 'ts-morph';
2
+ import { IndentationText, Project } from 'ts-morph';
3
3
  import { formatFile } from './formatter.js';
4
4
  import * as log from './log.js';
5
5
  import { getAddCommand, getRunCommand } from './package-manager.js';
@@ -57,6 +57,10 @@ import { getOwnVersion } from './version-check.js';
57
57
  // 3. Parse config with ts-morph
58
58
  log.debug('Parsing config file with ts-morph...');
59
59
  const project = new Project({
60
+ manipulationSettings: {
61
+ indentationText: IndentationText.TwoSpaces,
62
+ useTrailingCommas: true
63
+ },
60
64
  skipAddingFilesFromTsConfig: true
61
65
  });
62
66
  const sourceFile = project.addSourceFileAtPath(configPath);
@@ -107,6 +111,10 @@ import { getOwnVersion } from './version-check.js';
107
111
  }
108
112
  // Save file if any modifications were made
109
113
  if (modified) {
114
+ sourceFile.formatText({
115
+ indentSize: 2,
116
+ tabSize: 2
117
+ });
110
118
  await sourceFile.save();
111
119
  log.debug('Config file saved');
112
120
  // 7. Handle package management
@@ -2,7 +2,7 @@ import type { BootstrapEnvironment } from '../api/control-plane.js';
2
2
  /**
3
3
  * Resolve which environment to use from the bootstrap response.
4
4
  *
5
- * - Single environment: auto-select (environmentName optional)
5
+ * - Single environment: auto-select (environmentName optional, validated if provided)
6
6
  * - Multiple environments: environmentName required, must match
7
7
  *
8
8
  * @throws Error if resolution fails (with available environment names)
@@ -1,7 +1,7 @@
1
1
  /**
2
2
  * Resolve which environment to use from the bootstrap response.
3
3
  *
4
- * - Single environment: auto-select (environmentName optional)
4
+ * - Single environment: auto-select (environmentName optional, validated if provided)
5
5
  * - Multiple environments: environmentName required, must match
6
6
  *
7
7
  * @throws Error if resolution fails (with available environment names)
@@ -11,6 +11,9 @@
11
11
  throw new Error('No environments found for this project.');
12
12
  }
13
13
  if (environments.length === 1) {
14
+ if (environmentName && environments[0].name !== environmentName) {
15
+ throw new Error(`Environment "${environmentName}" not found. Available: ${environments[0].name}`);
16
+ }
14
17
  return environments[0];
15
18
  }
16
19
  // Multiple environments — name required
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@payloadcms/figma",
3
- "version": "0.0.1-alpha.55",
3
+ "version": "0.0.1-alpha.57",
4
4
  "license": "SEE LICENSE IN LICENSE.md",
5
5
  "type": "module",
6
6
  "exports": {
@@ -34,7 +34,6 @@
34
34
  "arg": "^5.0.2",
35
35
  "conf": "^13.0.1",
36
36
  "cross-spawn": "7.0.6",
37
- "esprima-next": "^6.0.2",
38
37
  "figures": "^6.1.0",
39
38
  "jose": "6.0.12",
40
39
  "jsonwebtoken": "9.0.3",