@payloadcms/figma 0.0.1-alpha.0
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/LICENSE.md +11 -0
- package/bin/cli.js +4 -0
- package/dist/api/control-plane.d.ts +124 -0
- package/dist/api/control-plane.d.ts.map +1 -0
- package/dist/api/control-plane.js +245 -0
- package/dist/api/control-plane.js.map +1 -0
- package/dist/api/control-plane.spec.d.ts +2 -0
- package/dist/api/control-plane.spec.d.ts.map +1 -0
- package/dist/api/control-plane.spec.js +296 -0
- package/dist/api/control-plane.spec.js.map +1 -0
- package/dist/api/figma-api.d.ts +31 -0
- package/dist/api/figma-api.d.ts.map +1 -0
- package/dist/api/figma-api.js +169 -0
- package/dist/api/figma-api.js.map +1 -0
- package/dist/api/figma-api.spec.d.ts +14 -0
- package/dist/api/figma-api.spec.d.ts.map +1 -0
- package/dist/api/figma-api.spec.js +201 -0
- package/dist/api/figma-api.spec.js.map +1 -0
- package/dist/auth/__tests__/fixtures.d.ts +26 -0
- package/dist/auth/__tests__/fixtures.d.ts.map +1 -0
- package/dist/auth/__tests__/fixtures.js +67 -0
- package/dist/auth/__tests__/fixtures.js.map +1 -0
- package/dist/auth/__tests__/mocks.d.ts +33 -0
- package/dist/auth/__tests__/mocks.d.ts.map +1 -0
- package/dist/auth/__tests__/mocks.js +63 -0
- package/dist/auth/__tests__/mocks.js.map +1 -0
- package/dist/auth/browser.d.ts +31 -0
- package/dist/auth/browser.d.ts.map +1 -0
- package/dist/auth/browser.js +41 -0
- package/dist/auth/browser.js.map +1 -0
- package/dist/auth/callback-server.d.ts +61 -0
- package/dist/auth/callback-server.d.ts.map +1 -0
- package/dist/auth/callback-server.js +168 -0
- package/dist/auth/callback-server.js.map +1 -0
- package/dist/auth/callback-server.spec.d.ts +2 -0
- package/dist/auth/callback-server.spec.d.ts.map +1 -0
- package/dist/auth/callback-server.spec.js +85 -0
- package/dist/auth/callback-server.spec.js.map +1 -0
- package/dist/auth/crypto-utils.d.ts +33 -0
- package/dist/auth/crypto-utils.d.ts.map +1 -0
- package/dist/auth/crypto-utils.js +96 -0
- package/dist/auth/crypto-utils.js.map +1 -0
- package/dist/auth/crypto-utils.spec.d.ts +2 -0
- package/dist/auth/crypto-utils.spec.d.ts.map +1 -0
- package/dist/auth/crypto-utils.spec.js +36 -0
- package/dist/auth/crypto-utils.spec.js.map +1 -0
- package/dist/auth/jwt-validator.d.ts +41 -0
- package/dist/auth/jwt-validator.d.ts.map +1 -0
- package/dist/auth/jwt-validator.js +113 -0
- package/dist/auth/jwt-validator.js.map +1 -0
- package/dist/auth/jwt-validator.spec.d.ts +10 -0
- package/dist/auth/jwt-validator.spec.d.ts.map +1 -0
- package/dist/auth/jwt-validator.spec.js +236 -0
- package/dist/auth/jwt-validator.spec.js.map +1 -0
- package/dist/auth/oauth-flow.d.ts +62 -0
- package/dist/auth/oauth-flow.d.ts.map +1 -0
- package/dist/auth/oauth-flow.js +172 -0
- package/dist/auth/oauth-flow.js.map +1 -0
- package/dist/auth/oauth-flow.spec.d.ts +2 -0
- package/dist/auth/oauth-flow.spec.d.ts.map +1 -0
- package/dist/auth/oauth-flow.spec.js +134 -0
- package/dist/auth/oauth-flow.spec.js.map +1 -0
- package/dist/auth/pages/error.html +85 -0
- package/dist/auth/pages/success.html +74 -0
- package/dist/auth/pkce.d.ts +51 -0
- package/dist/auth/pkce.d.ts.map +1 -0
- package/dist/auth/pkce.js +71 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/pkce.spec.d.ts +2 -0
- package/dist/auth/pkce.spec.d.ts.map +1 -0
- package/dist/auth/pkce.spec.js +32 -0
- package/dist/auth/pkce.spec.js.map +1 -0
- package/dist/auth/project-token.d.ts +47 -0
- package/dist/auth/project-token.d.ts.map +1 -0
- package/dist/auth/project-token.js +134 -0
- package/dist/auth/project-token.js.map +1 -0
- package/dist/auth/project-token.spec.d.ts +2 -0
- package/dist/auth/project-token.spec.d.ts.map +1 -0
- package/dist/auth/project-token.spec.js +332 -0
- package/dist/auth/project-token.spec.js.map +1 -0
- package/dist/auth/refresh.d.ts +35 -0
- package/dist/auth/refresh.d.ts.map +1 -0
- package/dist/auth/refresh.js +149 -0
- package/dist/auth/refresh.js.map +1 -0
- package/dist/auth/refresh.spec.d.ts +2 -0
- package/dist/auth/refresh.spec.d.ts.map +1 -0
- package/dist/auth/refresh.spec.js +105 -0
- package/dist/auth/refresh.spec.js.map +1 -0
- package/dist/auth/token-store.d.ts +110 -0
- package/dist/auth/token-store.d.ts.map +1 -0
- package/dist/auth/token-store.js +188 -0
- package/dist/auth/token-store.js.map +1 -0
- package/dist/auth/token-store.spec.d.ts +2 -0
- package/dist/auth/token-store.spec.d.ts.map +1 -0
- package/dist/auth/token-store.spec.js +276 -0
- package/dist/auth/token-store.spec.js.map +1 -0
- package/dist/auth/types.d.ts +197 -0
- package/dist/auth/types.d.ts.map +1 -0
- package/dist/auth/types.js +6 -0
- package/dist/auth/types.js.map +1 -0
- package/dist/cli.d.ts +5 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +108 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/__tests__/test-utils.d.ts +28 -0
- package/dist/commands/__tests__/test-utils.d.ts.map +1 -0
- package/dist/commands/__tests__/test-utils.js +34 -0
- package/dist/commands/__tests__/test-utils.js.map +1 -0
- package/dist/commands/deploy.d.ts +16 -0
- package/dist/commands/deploy.d.ts.map +1 -0
- package/dist/commands/deploy.js +297 -0
- package/dist/commands/deploy.js.map +1 -0
- package/dist/commands/deploy.spec.d.ts +2 -0
- package/dist/commands/deploy.spec.d.ts.map +1 -0
- package/dist/commands/deploy.spec.js +18 -0
- package/dist/commands/deploy.spec.js.map +1 -0
- package/dist/commands/init.d.ts +30 -0
- package/dist/commands/init.d.ts.map +1 -0
- package/dist/commands/init.js +410 -0
- package/dist/commands/init.js.map +1 -0
- package/dist/commands/init.spec.d.ts +2 -0
- package/dist/commands/init.spec.d.ts.map +1 -0
- package/dist/commands/init.spec.js +283 -0
- package/dist/commands/init.spec.js.map +1 -0
- package/dist/commands/list-tokens.d.ts +16 -0
- package/dist/commands/list-tokens.d.ts.map +1 -0
- package/dist/commands/list-tokens.js +44 -0
- package/dist/commands/list-tokens.js.map +1 -0
- package/dist/commands/login.d.ts +17 -0
- package/dist/commands/login.d.ts.map +1 -0
- package/dist/commands/login.js +69 -0
- package/dist/commands/login.js.map +1 -0
- package/dist/commands/logout.d.ts +16 -0
- package/dist/commands/logout.d.ts.map +1 -0
- package/dist/commands/logout.js +43 -0
- package/dist/commands/logout.js.map +1 -0
- package/dist/config/oauth.d.ts +19 -0
- package/dist/config/oauth.d.ts.map +1 -0
- package/dist/config/oauth.js +43 -0
- package/dist/config/oauth.js.map +1 -0
- package/dist/constants.d.ts +27 -0
- package/dist/constants.d.ts.map +1 -0
- package/dist/constants.js +27 -0
- package/dist/constants.js.map +1 -0
- package/dist/index.d.ts +5 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -0
- package/dist/plugin/adapter.d.ts +5 -0
- package/dist/plugin/adapter.d.ts.map +1 -0
- package/dist/plugin/adapter.js +139 -0
- package/dist/plugin/adapter.js.map +1 -0
- package/dist/plugin/build-config.d.ts +37 -0
- package/dist/plugin/build-config.d.ts.map +1 -0
- package/dist/plugin/build-config.js +25 -0
- package/dist/plugin/build-config.js.map +1 -0
- package/dist/plugin/build-config.spec.d.ts +2 -0
- package/dist/plugin/build-config.spec.d.ts.map +1 -0
- package/dist/plugin/build-config.spec.js +72 -0
- package/dist/plugin/build-config.spec.js.map +1 -0
- package/dist/types/config.d.ts +45 -0
- package/dist/types/config.d.ts.map +1 -0
- package/dist/types/config.js +9 -0
- package/dist/types/config.js.map +1 -0
- package/dist/types.d.ts +60 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +3 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/asset-collection.d.ts +30 -0
- package/dist/utils/asset-collection.d.ts.map +1 -0
- package/dist/utils/asset-collection.js +117 -0
- package/dist/utils/asset-collection.js.map +1 -0
- package/dist/utils/asset-collection.spec.d.ts +2 -0
- package/dist/utils/asset-collection.spec.d.ts.map +1 -0
- package/dist/utils/asset-collection.spec.js +155 -0
- package/dist/utils/asset-collection.spec.js.map +1 -0
- package/dist/utils/build-detection.d.ts +32 -0
- package/dist/utils/build-detection.d.ts.map +1 -0
- package/dist/utils/build-detection.js +55 -0
- package/dist/utils/build-detection.js.map +1 -0
- package/dist/utils/build-detection.spec.d.ts +2 -0
- package/dist/utils/build-detection.spec.d.ts.map +1 -0
- package/dist/utils/build-detection.spec.js +110 -0
- package/dist/utils/build-detection.spec.js.map +1 -0
- package/dist/utils/config.d.ts +33 -0
- package/dist/utils/config.d.ts.map +1 -0
- package/dist/utils/config.js +78 -0
- package/dist/utils/config.js.map +1 -0
- package/dist/utils/config.spec.d.ts +2 -0
- package/dist/utils/config.spec.d.ts.map +1 -0
- package/dist/utils/config.spec.js +167 -0
- package/dist/utils/config.spec.js.map +1 -0
- package/dist/utils/download-template.d.ts +15 -0
- package/dist/utils/download-template.d.ts.map +1 -0
- package/dist/utils/download-template.js +74 -0
- package/dist/utils/download-template.js.map +1 -0
- package/dist/utils/download-template.spec.d.ts +2 -0
- package/dist/utils/download-template.spec.d.ts.map +1 -0
- package/dist/utils/download-template.spec.js +76 -0
- package/dist/utils/download-template.spec.js.map +1 -0
- package/dist/utils/env-management.d.ts +16 -0
- package/dist/utils/env-management.d.ts.map +1 -0
- package/dist/utils/env-management.js +98 -0
- package/dist/utils/env-management.js.map +1 -0
- package/dist/utils/env-management.spec.d.ts +2 -0
- package/dist/utils/env-management.spec.d.ts.map +1 -0
- package/dist/utils/env-management.spec.js +123 -0
- package/dist/utils/env-management.spec.js.map +1 -0
- package/dist/utils/format.d.ts +23 -0
- package/dist/utils/format.d.ts.map +1 -0
- package/dist/utils/format.js +49 -0
- package/dist/utils/format.js.map +1 -0
- package/dist/utils/formatter.d.ts +11 -0
- package/dist/utils/formatter.d.ts.map +1 -0
- package/dist/utils/formatter.js +47 -0
- package/dist/utils/formatter.js.map +1 -0
- package/dist/utils/git.d.ts +15 -0
- package/dist/utils/git.d.ts.map +1 -0
- package/dist/utils/git.js +92 -0
- package/dist/utils/git.js.map +1 -0
- package/dist/utils/git.spec.d.ts +2 -0
- package/dist/utils/git.spec.d.ts.map +1 -0
- package/dist/utils/git.spec.js +99 -0
- package/dist/utils/git.spec.js.map +1 -0
- package/dist/utils/is-debug.d.ts +6 -0
- package/dist/utils/is-debug.d.ts.map +1 -0
- package/dist/utils/is-debug.js +8 -0
- package/dist/utils/is-debug.js.map +1 -0
- package/dist/utils/lambda-config.d.ts +7 -0
- package/dist/utils/lambda-config.d.ts.map +1 -0
- package/dist/utils/lambda-config.js +144 -0
- package/dist/utils/lambda-config.js.map +1 -0
- package/dist/utils/lambda-config.spec.d.ts +2 -0
- package/dist/utils/lambda-config.spec.d.ts.map +1 -0
- package/dist/utils/lambda-config.spec.js +141 -0
- package/dist/utils/lambda-config.spec.js.map +1 -0
- package/dist/utils/log.d.ts +6 -0
- package/dist/utils/log.d.ts.map +1 -0
- package/dist/utils/log.js +22 -0
- package/dist/utils/log.js.map +1 -0
- package/dist/utils/messages.d.ts +10 -0
- package/dist/utils/messages.d.ts.map +1 -0
- package/dist/utils/messages.js +96 -0
- package/dist/utils/messages.js.map +1 -0
- package/dist/utils/package-manager.d.ts +12 -0
- package/dist/utils/package-manager.d.ts.map +1 -0
- package/dist/utils/package-manager.js +37 -0
- package/dist/utils/package-manager.js.map +1 -0
- package/dist/utils/payload-config-ast.d.ts +30 -0
- package/dist/utils/payload-config-ast.d.ts.map +1 -0
- package/dist/utils/payload-config-ast.js +259 -0
- package/dist/utils/payload-config-ast.js.map +1 -0
- package/dist/utils/payload-config-ast.spec.d.ts +2 -0
- package/dist/utils/payload-config-ast.spec.d.ts.map +1 -0
- package/dist/utils/payload-config-ast.spec.js +303 -0
- package/dist/utils/payload-config-ast.spec.js.map +1 -0
- package/dist/utils/payload-config-finder.d.ts +9 -0
- package/dist/utils/payload-config-finder.d.ts.map +1 -0
- package/dist/utils/payload-config-finder.js +26 -0
- package/dist/utils/payload-config-finder.js.map +1 -0
- package/dist/utils/payload-config-modifier.d.ts +18 -0
- package/dist/utils/payload-config-modifier.d.ts.map +1 -0
- package/dist/utils/payload-config-modifier.int.spec.d.ts +2 -0
- package/dist/utils/payload-config-modifier.int.spec.d.ts.map +1 -0
- package/dist/utils/payload-config-modifier.int.spec.js +116 -0
- package/dist/utils/payload-config-modifier.int.spec.js.map +1 -0
- package/dist/utils/payload-config-modifier.js +232 -0
- package/dist/utils/payload-config-modifier.js.map +1 -0
- package/dist/utils/payload-config-modifier.spec.d.ts +2 -0
- package/dist/utils/payload-config-modifier.spec.d.ts.map +1 -0
- package/dist/utils/payload-config-modifier.spec.js +162 -0
- package/dist/utils/payload-config-modifier.spec.js.map +1 -0
- package/dist/utils/payload-package-check.d.ts +15 -0
- package/dist/utils/payload-package-check.d.ts.map +1 -0
- package/dist/utils/payload-package-check.js +116 -0
- package/dist/utils/payload-package-check.js.map +1 -0
- package/dist/utils/payload-package-check.spec.d.ts +2 -0
- package/dist/utils/payload-package-check.spec.d.ts.map +1 -0
- package/dist/utils/payload-package-check.spec.js +148 -0
- package/dist/utils/payload-package-check.spec.js.map +1 -0
- package/dist/utils/project.d.ts +58 -0
- package/dist/utils/project.d.ts.map +1 -0
- package/dist/utils/project.js +252 -0
- package/dist/utils/project.js.map +1 -0
- package/dist/utils/project.spec.d.ts +2 -0
- package/dist/utils/project.spec.d.ts.map +1 -0
- package/dist/utils/project.spec.js +222 -0
- package/dist/utils/project.spec.js.map +1 -0
- package/dist/utils/s3-upload.d.ts +43 -0
- package/dist/utils/s3-upload.d.ts.map +1 -0
- package/dist/utils/s3-upload.js +128 -0
- package/dist/utils/s3-upload.js.map +1 -0
- package/dist/utils/s3-upload.spec.d.ts +2 -0
- package/dist/utils/s3-upload.spec.d.ts.map +1 -0
- package/dist/utils/s3-upload.spec.js +140 -0
- package/dist/utils/s3-upload.spec.js.map +1 -0
- package/dist/utils/token-display.d.ts +14 -0
- package/dist/utils/token-display.d.ts.map +1 -0
- package/dist/utils/token-display.js +62 -0
- package/dist/utils/token-display.js.map +1 -0
- package/dist/utils/typescript-validator.d.ts +11 -0
- package/dist/utils/typescript-validator.d.ts.map +1 -0
- package/dist/utils/typescript-validator.js +58 -0
- package/dist/utils/typescript-validator.js.map +1 -0
- package/package.json +69 -0
|
@@ -0,0 +1,144 @@
|
|
|
1
|
+
import { parseModule, Syntax } from 'esprima-next';
|
|
2
|
+
import fs from 'fs/promises';
|
|
3
|
+
import path from 'path';
|
|
4
|
+
const RUN_SH_CONTENT = `#!/bin/bash -x
|
|
5
|
+
|
|
6
|
+
[ ! -d '/tmp/cache' ] && mkdir -p /tmp/cache
|
|
7
|
+
|
|
8
|
+
NODE_ENV=production exec node server.js
|
|
9
|
+
`;
|
|
10
|
+
const BUILD_FOR_LAMBDA_SH_CONTENT = `#!/bin/bash
|
|
11
|
+
|
|
12
|
+
cp -r .next/static .next/standalone/.next/static
|
|
13
|
+
cp run.sh .next/standalone/run.sh
|
|
14
|
+
cd .next/standalone
|
|
15
|
+
zip -r --symlinks lambda.zip .
|
|
16
|
+
mv lambda.zip ../..
|
|
17
|
+
`;
|
|
18
|
+
/**
|
|
19
|
+
* Apply Lambda-specific modifications to a Payload project
|
|
20
|
+
*
|
|
21
|
+
* @param projectPath - Path to project directory
|
|
22
|
+
*/ export async function applyLambdaModifications(projectPath) {
|
|
23
|
+
// 1. Create run.sh
|
|
24
|
+
const runShPath = path.join(projectPath, 'run.sh');
|
|
25
|
+
await fs.writeFile(runShPath, RUN_SH_CONTENT, 'utf-8');
|
|
26
|
+
await fs.chmod(runShPath, 0o755); // rwxr-xr-x
|
|
27
|
+
// 2. Create build_for_lambda.sh
|
|
28
|
+
const buildShPath = path.join(projectPath, 'build_for_lambda.sh');
|
|
29
|
+
await fs.writeFile(buildShPath, BUILD_FOR_LAMBDA_SH_CONTENT, 'utf-8');
|
|
30
|
+
await fs.chmod(buildShPath, 0o755);
|
|
31
|
+
// 3. Modify next config to add standalone output
|
|
32
|
+
await addStandaloneToNextConfig(projectPath);
|
|
33
|
+
// 4. Create/update .npmrc
|
|
34
|
+
const npmrcPath = path.join(projectPath, '.npmrc');
|
|
35
|
+
let npmrcContent = '';
|
|
36
|
+
try {
|
|
37
|
+
npmrcContent = await fs.readFile(npmrcPath, 'utf-8');
|
|
38
|
+
} catch {
|
|
39
|
+
// File doesn't exist, start fresh
|
|
40
|
+
}
|
|
41
|
+
if (!npmrcContent.includes('node-linker=hoisted')) {
|
|
42
|
+
npmrcContent += npmrcContent && !npmrcContent.endsWith('\n') ? '\n' : '';
|
|
43
|
+
npmrcContent += 'node-linker=hoisted\n';
|
|
44
|
+
await fs.writeFile(npmrcPath, npmrcContent, 'utf-8');
|
|
45
|
+
}
|
|
46
|
+
// 5. Add lambda:buildzip script to package.json
|
|
47
|
+
await addLambdaBuildScript(projectPath);
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Find the Next.js config file (next.config.js or next.config.mjs)
|
|
51
|
+
*
|
|
52
|
+
* @todo Support TypeScript config files in future
|
|
53
|
+
*/ async function findNextConfigPath(projectPath) {
|
|
54
|
+
const configFiles = [
|
|
55
|
+
'next.config.js',
|
|
56
|
+
'next.config.mjs'
|
|
57
|
+
];
|
|
58
|
+
for (const configFile of configFiles){
|
|
59
|
+
const configPath = path.join(projectPath, configFile);
|
|
60
|
+
try {
|
|
61
|
+
await fs.access(configPath);
|
|
62
|
+
return configPath;
|
|
63
|
+
} catch {
|
|
64
|
+
// File doesn't exist, try next one
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
throw new Error('Could not find next.config.js or next.config.mjs');
|
|
68
|
+
}
|
|
69
|
+
/**
|
|
70
|
+
* Add standalone output to Next.js config using AST parsing
|
|
71
|
+
*/ async function addStandaloneToNextConfig(projectPath) {
|
|
72
|
+
const nextConfigPath = await findNextConfigPath(projectPath);
|
|
73
|
+
const content = await fs.readFile(nextConfigPath, 'utf-8');
|
|
74
|
+
// Check if output already configured (quick check before parsing)
|
|
75
|
+
if (content.includes('output:')) {
|
|
76
|
+
return; // Already configured
|
|
77
|
+
}
|
|
78
|
+
const ast = parseModule(content, {
|
|
79
|
+
loc: true
|
|
80
|
+
});
|
|
81
|
+
// Find export default declaration
|
|
82
|
+
const exportDefaultDeclaration = ast.body.find((p)=>p.type === Syntax.ExportDefaultDeclaration);
|
|
83
|
+
if (!exportDefaultDeclaration?.declaration?.loc) {
|
|
84
|
+
throw new Error(`Could not find export default declaration in ${path.basename(nextConfigPath)}`);
|
|
85
|
+
}
|
|
86
|
+
// Find the object expression to modify
|
|
87
|
+
let targetObjectExpression;
|
|
88
|
+
if (exportDefaultDeclaration.declaration.type === 'ObjectExpression') {
|
|
89
|
+
// Direct export: export default { ... }
|
|
90
|
+
targetObjectExpression = exportDefaultDeclaration.declaration;
|
|
91
|
+
} else if (exportDefaultDeclaration.declaration.type === 'CallExpression') {
|
|
92
|
+
// Wrapped export: export default withPayload(nextConfig, ...)
|
|
93
|
+
const callExpr = exportDefaultDeclaration.declaration;
|
|
94
|
+
const firstArg = callExpr.arguments?.[0];
|
|
95
|
+
if (firstArg?.type === 'Identifier') {
|
|
96
|
+
// Find the variable declaration for this identifier
|
|
97
|
+
const configVarName = firstArg.name;
|
|
98
|
+
const varDeclaration = ast.body.find((node)=>{
|
|
99
|
+
if (node.type === Syntax.VariableDeclaration) {
|
|
100
|
+
const varNode = node;
|
|
101
|
+
return varNode.declarations?.some((decl)=>decl.id?.type === 'Identifier' && decl.id.name === configVarName && decl.init?.type === 'ObjectExpression');
|
|
102
|
+
}
|
|
103
|
+
return false;
|
|
104
|
+
});
|
|
105
|
+
if (varDeclaration) {
|
|
106
|
+
const declarator = varDeclaration.declarations?.find((decl)=>decl.id?.type === 'Identifier' && decl.id.name === configVarName);
|
|
107
|
+
if (declarator?.init?.type === 'ObjectExpression') {
|
|
108
|
+
targetObjectExpression = declarator.init;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
if (!targetObjectExpression?.loc) {
|
|
114
|
+
throw new Error(`Could not find Next.js config object in ${path.basename(nextConfigPath)}. ` + `Expected either 'export default { ... }' or 'export default wrapper(configVar, ...)'`);
|
|
115
|
+
}
|
|
116
|
+
const { loc } = targetObjectExpression;
|
|
117
|
+
const lines = content.split('\n');
|
|
118
|
+
// Insert output: 'standalone' as first property
|
|
119
|
+
const insertLine = loc.start.line - 1;
|
|
120
|
+
const insertColumn = loc.start.column + 1 // After opening brace
|
|
121
|
+
;
|
|
122
|
+
// Find the content of the line with the opening brace
|
|
123
|
+
const targetLine = lines[insertLine];
|
|
124
|
+
if (!targetLine) {
|
|
125
|
+
throw new Error(`Could not find target line in ${path.basename(nextConfigPath)}`);
|
|
126
|
+
}
|
|
127
|
+
lines[insertLine] = targetLine.slice(0, insertColumn) + "\n output: 'standalone'," + targetLine.slice(insertColumn);
|
|
128
|
+
const modifiedContent = lines.join('\n');
|
|
129
|
+
await fs.writeFile(nextConfigPath, modifiedContent, 'utf-8');
|
|
130
|
+
}
|
|
131
|
+
/**
|
|
132
|
+
* Add lambda:buildzip script to package.json
|
|
133
|
+
*/ async function addLambdaBuildScript(projectPath) {
|
|
134
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
135
|
+
const content = await fs.readFile(packageJsonPath, 'utf-8');
|
|
136
|
+
const packageJson = JSON.parse(content);
|
|
137
|
+
if (!packageJson.scripts) {
|
|
138
|
+
packageJson.scripts = {};
|
|
139
|
+
}
|
|
140
|
+
packageJson.scripts['lambda:buildzip'] = 'npm run build && ./build_for_lambda.sh';
|
|
141
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
//# sourceMappingURL=lambda-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/lambda-config.ts"],"sourcesContent":["import { parseModule, Syntax } from 'esprima-next'\nimport fs from 'fs/promises'\nimport path from 'path'\n\nconst RUN_SH_CONTENT = `#!/bin/bash -x\n\n[ ! -d '/tmp/cache' ] && mkdir -p /tmp/cache\n\nNODE_ENV=production exec node server.js\n`\n\nconst BUILD_FOR_LAMBDA_SH_CONTENT = `#!/bin/bash\n\ncp -r .next/static .next/standalone/.next/static\ncp run.sh .next/standalone/run.sh\ncd .next/standalone\nzip -r --symlinks lambda.zip .\nmv lambda.zip ../..\n`\n\n/**\n * Apply Lambda-specific modifications to a Payload project\n *\n * @param projectPath - Path to project directory\n */\nexport async function applyLambdaModifications(projectPath: string): Promise<void> {\n // 1. Create run.sh\n const runShPath = path.join(projectPath, 'run.sh')\n await fs.writeFile(runShPath, RUN_SH_CONTENT, 'utf-8')\n await fs.chmod(runShPath, 0o755) // rwxr-xr-x\n\n // 2. Create build_for_lambda.sh\n const buildShPath = path.join(projectPath, 'build_for_lambda.sh')\n await fs.writeFile(buildShPath, BUILD_FOR_LAMBDA_SH_CONTENT, 'utf-8')\n await fs.chmod(buildShPath, 0o755)\n\n // 3. Modify next config to add standalone output\n await addStandaloneToNextConfig(projectPath)\n\n // 4. Create/update .npmrc\n const npmrcPath = path.join(projectPath, '.npmrc')\n let npmrcContent = ''\n\n try {\n npmrcContent = await fs.readFile(npmrcPath, 'utf-8')\n } catch {\n // File doesn't exist, start fresh\n }\n\n if (!npmrcContent.includes('node-linker=hoisted')) {\n npmrcContent += npmrcContent && !npmrcContent.endsWith('\\n') ? '\\n' : ''\n npmrcContent += 'node-linker=hoisted\\n'\n await fs.writeFile(npmrcPath, npmrcContent, 'utf-8')\n }\n\n // 5. Add lambda:buildzip script to package.json\n await addLambdaBuildScript(projectPath)\n}\n\n/**\n * Find the Next.js config file (next.config.js or next.config.mjs)\n *\n * @todo Support TypeScript config files in future\n */\nasync function findNextConfigPath(projectPath: string): Promise<string> {\n const configFiles = ['next.config.js', 'next.config.mjs']\n\n for (const configFile of configFiles) {\n const configPath = path.join(projectPath, configFile)\n try {\n await fs.access(configPath)\n return configPath\n } catch {\n // File doesn't exist, try next one\n }\n }\n\n throw new Error('Could not find next.config.js or next.config.mjs')\n}\n\n/**\n * Add standalone output to Next.js config using AST parsing\n */\nasync function addStandaloneToNextConfig(projectPath: string): Promise<void> {\n const nextConfigPath = await findNextConfigPath(projectPath)\n const content = await fs.readFile(nextConfigPath, 'utf-8')\n\n // Check if output already configured (quick check before parsing)\n if (content.includes('output:')) {\n return // Already configured\n }\n\n const ast = parseModule(content, { loc: true })\n\n // Find export default declaration\n const exportDefaultDeclaration = ast.body.find(\n (p) => p.type === Syntax.ExportDefaultDeclaration,\n ) as ExportDefaultDeclaration | undefined\n\n if (!exportDefaultDeclaration?.declaration?.loc) {\n throw new Error(`Could not find export default declaration in ${path.basename(nextConfigPath)}`)\n }\n\n // Find the object expression to modify\n let targetObjectExpression: ObjectExpressionNode | undefined\n\n if (exportDefaultDeclaration.declaration.type === 'ObjectExpression') {\n // Direct export: export default { ... }\n targetObjectExpression = exportDefaultDeclaration.declaration as ObjectExpressionNode\n } else if (exportDefaultDeclaration.declaration.type === 'CallExpression') {\n // Wrapped export: export default withPayload(nextConfig, ...)\n const callExpr = exportDefaultDeclaration.declaration as CallExpressionNode\n const firstArg = callExpr.arguments?.[0]\n\n if (firstArg?.type === 'Identifier') {\n // Find the variable declaration for this identifier\n const configVarName = (firstArg as IdentifierNode).name\n const varDeclaration = ast.body.find((node) => {\n if (node.type === Syntax.VariableDeclaration) {\n const varNode = node as VariableDeclarationNode\n return varNode.declarations?.some(\n (decl) =>\n decl.id?.type === 'Identifier' &&\n (decl.id as IdentifierNode).name === configVarName &&\n decl.init?.type === 'ObjectExpression',\n )\n }\n return false\n }) as undefined | VariableDeclarationNode\n\n if (varDeclaration) {\n const declarator = varDeclaration.declarations?.find(\n (decl) =>\n decl.id?.type === 'Identifier' && (decl.id as IdentifierNode).name === configVarName,\n )\n if (declarator?.init?.type === 'ObjectExpression') {\n targetObjectExpression = declarator.init as ObjectExpressionNode\n }\n }\n }\n }\n\n if (!targetObjectExpression?.loc) {\n throw new Error(\n `Could not find Next.js config object in ${path.basename(nextConfigPath)}. ` +\n `Expected either 'export default { ... }' or 'export default wrapper(configVar, ...)'`,\n )\n }\n\n const { loc } = targetObjectExpression\n const lines = content.split('\\n')\n\n // Insert output: 'standalone' as first property\n const insertLine = loc.start.line - 1\n const insertColumn = loc.start.column + 1 // After opening brace\n\n // Find the content of the line with the opening brace\n const targetLine = lines[insertLine]\n if (!targetLine) {\n throw new Error(`Could not find target line in ${path.basename(nextConfigPath)}`)\n }\n\n lines[insertLine] =\n targetLine.slice(0, insertColumn) + \"\\n output: 'standalone',\" + targetLine.slice(insertColumn)\n\n const modifiedContent = lines.join('\\n')\n await fs.writeFile(nextConfigPath, modifiedContent, 'utf-8')\n}\n\ntype ExportDefaultDeclaration = {\n declaration: {\n arguments?: unknown[]\n loc: {\n end: { column: number; line: number }\n start: { column: number; line: number }\n }\n type: string\n }\n type: string\n}\n\ntype ObjectExpressionNode = {\n loc: {\n end: { column: number; line: number }\n start: { column: number; line: number }\n }\n type: 'ObjectExpression'\n}\n\ntype IdentifierNode = {\n name: string\n type: 'Identifier'\n}\n\ntype CallExpressionNode = {\n arguments?: Array<{ type: string }>\n type: 'CallExpression'\n}\n\ntype VariableDeclarationNode = {\n declarations?: Array<{\n id?: { name?: string; type: string }\n init?: { loc?: ObjectExpressionNode['loc']; type: string }\n }>\n type: 'VariableDeclaration'\n}\n\n/**\n * Add lambda:buildzip script to package.json\n */\nasync function addLambdaBuildScript(projectPath: string): Promise<void> {\n const packageJsonPath = path.join(projectPath, 'package.json')\n const content = await fs.readFile(packageJsonPath, 'utf-8')\n const packageJson = JSON.parse(content)\n\n if (!packageJson.scripts) {\n packageJson.scripts = {}\n }\n\n packageJson.scripts['lambda:buildzip'] = 'npm run build && ./build_for_lambda.sh'\n\n await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\\n', 'utf-8')\n}\n"],"names":["parseModule","Syntax","fs","path","RUN_SH_CONTENT","BUILD_FOR_LAMBDA_SH_CONTENT","applyLambdaModifications","projectPath","runShPath","join","writeFile","chmod","buildShPath","addStandaloneToNextConfig","npmrcPath","npmrcContent","readFile","includes","endsWith","addLambdaBuildScript","findNextConfigPath","configFiles","configFile","configPath","access","Error","nextConfigPath","content","ast","loc","exportDefaultDeclaration","body","find","p","type","ExportDefaultDeclaration","declaration","basename","targetObjectExpression","callExpr","firstArg","arguments","configVarName","name","varDeclaration","node","VariableDeclaration","varNode","declarations","some","decl","id","init","declarator","lines","split","insertLine","start","line","insertColumn","column","targetLine","slice","modifiedContent","packageJsonPath","packageJson","JSON","parse","scripts","stringify"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"lambda-config.spec.d.ts","sourceRoot":"","sources":["../../src/utils/lambda-config.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it } from 'vitest';
|
|
4
|
+
import { applyLambdaModifications } from './lambda-config.js';
|
|
5
|
+
describe('applyLambdaModifications', ()=>{
|
|
6
|
+
const testDir = path.join(process.cwd(), '.test-lambda-config');
|
|
7
|
+
beforeEach(async ()=>{
|
|
8
|
+
await fs.mkdir(testDir, {
|
|
9
|
+
recursive: true
|
|
10
|
+
});
|
|
11
|
+
// Create minimal Next.js project structure
|
|
12
|
+
await fs.writeFile(path.join(testDir, 'package.json'), JSON.stringify({
|
|
13
|
+
name: 'test-project',
|
|
14
|
+
scripts: {
|
|
15
|
+
build: 'next build'
|
|
16
|
+
}
|
|
17
|
+
}, null, 2));
|
|
18
|
+
await fs.writeFile(path.join(testDir, 'next.config.js'), `export default {}\n`);
|
|
19
|
+
});
|
|
20
|
+
afterEach(async ()=>{
|
|
21
|
+
await fs.rm(testDir, {
|
|
22
|
+
force: true,
|
|
23
|
+
recursive: true
|
|
24
|
+
});
|
|
25
|
+
});
|
|
26
|
+
it('should create run.sh with correct permissions', async ()=>{
|
|
27
|
+
await applyLambdaModifications(testDir);
|
|
28
|
+
const runShPath = path.join(testDir, 'run.sh');
|
|
29
|
+
const content = await fs.readFile(runShPath, 'utf-8');
|
|
30
|
+
expect(content).toContain('#!/bin/bash -x');
|
|
31
|
+
expect(content).toContain('NODE_ENV=production exec node server.js');
|
|
32
|
+
// Check executable permissions
|
|
33
|
+
const stats = await fs.stat(runShPath);
|
|
34
|
+
expect(stats.mode & 0o111).toBeTruthy(); // Has execute bit
|
|
35
|
+
});
|
|
36
|
+
it('should create build_for_lambda.sh with correct permissions', async ()=>{
|
|
37
|
+
await applyLambdaModifications(testDir);
|
|
38
|
+
const buildShPath = path.join(testDir, 'build_for_lambda.sh');
|
|
39
|
+
const content = await fs.readFile(buildShPath, 'utf-8');
|
|
40
|
+
expect(content).toContain('cp -r .next/static .next/standalone/.next/static');
|
|
41
|
+
expect(content).toContain('zip -r --symlinks lambda.zip .');
|
|
42
|
+
const stats = await fs.stat(buildShPath);
|
|
43
|
+
expect(stats.mode & 0o111).toBeTruthy();
|
|
44
|
+
});
|
|
45
|
+
it('should add standalone output to next.config.js', async ()=>{
|
|
46
|
+
await applyLambdaModifications(testDir);
|
|
47
|
+
const nextConfig = await fs.readFile(path.join(testDir, 'next.config.js'), 'utf-8');
|
|
48
|
+
expect(nextConfig).toContain("output: 'standalone'");
|
|
49
|
+
});
|
|
50
|
+
it('should create .npmrc with node-linker=hoisted', async ()=>{
|
|
51
|
+
await applyLambdaModifications(testDir);
|
|
52
|
+
const npmrc = await fs.readFile(path.join(testDir, '.npmrc'), 'utf-8');
|
|
53
|
+
expect(npmrc).toContain('node-linker=hoisted');
|
|
54
|
+
});
|
|
55
|
+
it('should add lambda:buildzip script to package.json', async ()=>{
|
|
56
|
+
await applyLambdaModifications(testDir);
|
|
57
|
+
const packageJson = JSON.parse(await fs.readFile(path.join(testDir, 'package.json'), 'utf-8'));
|
|
58
|
+
expect(packageJson.scripts['lambda:buildzip']).toBe('npm run build && ./build_for_lambda.sh');
|
|
59
|
+
});
|
|
60
|
+
it('should handle complex next.config.js with existing properties', async ()=>{
|
|
61
|
+
// Create a more complex config file
|
|
62
|
+
await fs.writeFile(path.join(testDir, 'next.config.js'), `export default {
|
|
63
|
+
reactStrictMode: true,
|
|
64
|
+
images: {
|
|
65
|
+
domains: ['example.com'],
|
|
66
|
+
},
|
|
67
|
+
}
|
|
68
|
+
`);
|
|
69
|
+
await applyLambdaModifications(testDir);
|
|
70
|
+
const nextConfig = await fs.readFile(path.join(testDir, 'next.config.js'), 'utf-8');
|
|
71
|
+
expect(nextConfig).toContain("output: 'standalone'");
|
|
72
|
+
expect(nextConfig).toContain('reactStrictMode: true');
|
|
73
|
+
expect(nextConfig).toContain("domains: ['example.com']");
|
|
74
|
+
});
|
|
75
|
+
it('should not duplicate output if already present', async ()=>{
|
|
76
|
+
// Create config with output already set
|
|
77
|
+
await fs.writeFile(path.join(testDir, 'next.config.js'), `export default {
|
|
78
|
+
output: 'standalone',
|
|
79
|
+
reactStrictMode: true,
|
|
80
|
+
}
|
|
81
|
+
`);
|
|
82
|
+
await applyLambdaModifications(testDir);
|
|
83
|
+
const nextConfig = await fs.readFile(path.join(testDir, 'next.config.js'), 'utf-8');
|
|
84
|
+
// Should only contain output once
|
|
85
|
+
const outputCount = (nextConfig.match(/output:/g) || []).length;
|
|
86
|
+
expect(outputCount).toBe(1);
|
|
87
|
+
});
|
|
88
|
+
it('should throw error if config object cannot be found', async ()=>{
|
|
89
|
+
// Create config with function call but no variable declaration
|
|
90
|
+
await fs.writeFile(path.join(testDir, 'next.config.js'), `export default withSomeWrapper({})
|
|
91
|
+
`);
|
|
92
|
+
await expect(applyLambdaModifications(testDir)).rejects.toThrow('Could not find Next.js config object');
|
|
93
|
+
});
|
|
94
|
+
it('should work with next.config.mjs', async ()=>{
|
|
95
|
+
// Remove .js file and create .mjs instead
|
|
96
|
+
await fs.rm(path.join(testDir, 'next.config.js'), {
|
|
97
|
+
force: true
|
|
98
|
+
});
|
|
99
|
+
await fs.writeFile(path.join(testDir, 'next.config.mjs'), `export default {
|
|
100
|
+
reactStrictMode: true,
|
|
101
|
+
}
|
|
102
|
+
`);
|
|
103
|
+
await applyLambdaModifications(testDir);
|
|
104
|
+
const nextConfig = await fs.readFile(path.join(testDir, 'next.config.mjs'), 'utf-8');
|
|
105
|
+
expect(nextConfig).toContain("output: 'standalone'");
|
|
106
|
+
expect(nextConfig).toContain('reactStrictMode: true');
|
|
107
|
+
});
|
|
108
|
+
it('should handle wrapped export (e.g., withPayload)', async ()=>{
|
|
109
|
+
// Create config with wrapped export
|
|
110
|
+
await fs.writeFile(path.join(testDir, 'next.config.js'), `import { withPayload } from '@payloadcms/next/withPayload'
|
|
111
|
+
|
|
112
|
+
/** @type {import('next').NextConfig} */
|
|
113
|
+
const nextConfig = {
|
|
114
|
+
reactStrictMode: true,
|
|
115
|
+
webpack: (webpackConfig) => {
|
|
116
|
+
webpackConfig.resolve.extensionAlias = {
|
|
117
|
+
'.js': ['.ts', '.tsx', '.js', '.jsx'],
|
|
118
|
+
}
|
|
119
|
+
return webpackConfig
|
|
120
|
+
},
|
|
121
|
+
}
|
|
122
|
+
|
|
123
|
+
export default withPayload(nextConfig, { devBundleServerPackages: false })
|
|
124
|
+
`);
|
|
125
|
+
await applyLambdaModifications(testDir);
|
|
126
|
+
const nextConfig = await fs.readFile(path.join(testDir, 'next.config.js'), 'utf-8');
|
|
127
|
+
expect(nextConfig).toContain("output: 'standalone'");
|
|
128
|
+
expect(nextConfig).toContain('reactStrictMode: true');
|
|
129
|
+
expect(nextConfig).toContain('webpack: (webpackConfig)');
|
|
130
|
+
expect(nextConfig).toContain('withPayload(nextConfig');
|
|
131
|
+
});
|
|
132
|
+
it('should throw error if no next config file exists', async ()=>{
|
|
133
|
+
// Remove config file
|
|
134
|
+
await fs.rm(path.join(testDir, 'next.config.js'), {
|
|
135
|
+
force: true
|
|
136
|
+
});
|
|
137
|
+
await expect(applyLambdaModifications(testDir)).rejects.toThrow('Could not find next.config.js or next.config.mjs');
|
|
138
|
+
});
|
|
139
|
+
});
|
|
140
|
+
|
|
141
|
+
//# sourceMappingURL=lambda-config.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/lambda-config.spec.ts"],"sourcesContent":["import fs from 'fs/promises'\nimport path from 'path'\nimport { afterEach, beforeEach, describe, expect, it } from 'vitest'\n\nimport { applyLambdaModifications } from './lambda-config.js'\n\ndescribe('applyLambdaModifications', () => {\n const testDir = path.join(process.cwd(), '.test-lambda-config')\n\n beforeEach(async () => {\n await fs.mkdir(testDir, { recursive: true })\n\n // Create minimal Next.js project structure\n await fs.writeFile(\n path.join(testDir, 'package.json'),\n JSON.stringify(\n {\n name: 'test-project',\n scripts: {\n build: 'next build',\n },\n },\n null,\n 2,\n ),\n )\n\n await fs.writeFile(path.join(testDir, 'next.config.js'), `export default {}\\n`)\n })\n\n afterEach(async () => {\n await fs.rm(testDir, { force: true, recursive: true })\n })\n\n it('should create run.sh with correct permissions', async () => {\n await applyLambdaModifications(testDir)\n\n const runShPath = path.join(testDir, 'run.sh')\n const content = await fs.readFile(runShPath, 'utf-8')\n\n expect(content).toContain('#!/bin/bash -x')\n expect(content).toContain('NODE_ENV=production exec node server.js')\n\n // Check executable permissions\n const stats = await fs.stat(runShPath)\n expect(stats.mode & 0o111).toBeTruthy() // Has execute bit\n })\n\n it('should create build_for_lambda.sh with correct permissions', async () => {\n await applyLambdaModifications(testDir)\n\n const buildShPath = path.join(testDir, 'build_for_lambda.sh')\n const content = await fs.readFile(buildShPath, 'utf-8')\n\n expect(content).toContain('cp -r .next/static .next/standalone/.next/static')\n expect(content).toContain('zip -r --symlinks lambda.zip .')\n\n const stats = await fs.stat(buildShPath)\n expect(stats.mode & 0o111).toBeTruthy()\n })\n\n it('should add standalone output to next.config.js', async () => {\n await applyLambdaModifications(testDir)\n\n const nextConfig = await fs.readFile(path.join(testDir, 'next.config.js'), 'utf-8')\n expect(nextConfig).toContain(\"output: 'standalone'\")\n })\n\n it('should create .npmrc with node-linker=hoisted', async () => {\n await applyLambdaModifications(testDir)\n\n const npmrc = await fs.readFile(path.join(testDir, '.npmrc'), 'utf-8')\n expect(npmrc).toContain('node-linker=hoisted')\n })\n\n it('should add lambda:buildzip script to package.json', async () => {\n await applyLambdaModifications(testDir)\n\n const packageJson = JSON.parse(await fs.readFile(path.join(testDir, 'package.json'), 'utf-8'))\n\n expect(packageJson.scripts['lambda:buildzip']).toBe('npm run build && ./build_for_lambda.sh')\n })\n\n it('should handle complex next.config.js with existing properties', async () => {\n // Create a more complex config file\n await fs.writeFile(\n path.join(testDir, 'next.config.js'),\n `export default {\n reactStrictMode: true,\n images: {\n domains: ['example.com'],\n },\n}\n`,\n )\n\n await applyLambdaModifications(testDir)\n\n const nextConfig = await fs.readFile(path.join(testDir, 'next.config.js'), 'utf-8')\n expect(nextConfig).toContain(\"output: 'standalone'\")\n expect(nextConfig).toContain('reactStrictMode: true')\n expect(nextConfig).toContain(\"domains: ['example.com']\")\n })\n\n it('should not duplicate output if already present', async () => {\n // Create config with output already set\n await fs.writeFile(\n path.join(testDir, 'next.config.js'),\n `export default {\n output: 'standalone',\n reactStrictMode: true,\n}\n`,\n )\n\n await applyLambdaModifications(testDir)\n\n const nextConfig = await fs.readFile(path.join(testDir, 'next.config.js'), 'utf-8')\n // Should only contain output once\n const outputCount = (nextConfig.match(/output:/g) || []).length\n expect(outputCount).toBe(1)\n })\n\n it('should throw error if config object cannot be found', async () => {\n // Create config with function call but no variable declaration\n await fs.writeFile(\n path.join(testDir, 'next.config.js'),\n `export default withSomeWrapper({})\n`,\n )\n\n await expect(applyLambdaModifications(testDir)).rejects.toThrow(\n 'Could not find Next.js config object',\n )\n })\n\n it('should work with next.config.mjs', async () => {\n // Remove .js file and create .mjs instead\n await fs.rm(path.join(testDir, 'next.config.js'), { force: true })\n await fs.writeFile(\n path.join(testDir, 'next.config.mjs'),\n `export default {\n reactStrictMode: true,\n}\n`,\n )\n\n await applyLambdaModifications(testDir)\n\n const nextConfig = await fs.readFile(path.join(testDir, 'next.config.mjs'), 'utf-8')\n expect(nextConfig).toContain(\"output: 'standalone'\")\n expect(nextConfig).toContain('reactStrictMode: true')\n })\n\n it('should handle wrapped export (e.g., withPayload)', async () => {\n // Create config with wrapped export\n await fs.writeFile(\n path.join(testDir, 'next.config.js'),\n `import { withPayload } from '@payloadcms/next/withPayload'\n\n/** @type {import('next').NextConfig} */\nconst nextConfig = {\n reactStrictMode: true,\n webpack: (webpackConfig) => {\n webpackConfig.resolve.extensionAlias = {\n '.js': ['.ts', '.tsx', '.js', '.jsx'],\n }\n return webpackConfig\n },\n}\n\nexport default withPayload(nextConfig, { devBundleServerPackages: false })\n`,\n )\n\n await applyLambdaModifications(testDir)\n\n const nextConfig = await fs.readFile(path.join(testDir, 'next.config.js'), 'utf-8')\n expect(nextConfig).toContain(\"output: 'standalone'\")\n expect(nextConfig).toContain('reactStrictMode: true')\n expect(nextConfig).toContain('webpack: (webpackConfig)')\n expect(nextConfig).toContain('withPayload(nextConfig')\n })\n\n it('should throw error if no next config file exists', async () => {\n // Remove config file\n await fs.rm(path.join(testDir, 'next.config.js'), { force: true })\n\n await expect(applyLambdaModifications(testDir)).rejects.toThrow(\n 'Could not find next.config.js or next.config.mjs',\n )\n })\n})\n"],"names":["fs","path","afterEach","beforeEach","describe","expect","it","applyLambdaModifications","testDir","join","process","cwd","mkdir","recursive","writeFile","JSON","stringify","name","scripts","build","rm","force","runShPath","content","readFile","toContain","stats","stat","mode","toBeTruthy","buildShPath","nextConfig","npmrc","packageJson","parse","toBe","outputCount","match","length","rejects","toThrow"],"mappings":"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"}
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export declare const warning: (message: string) => void;
|
|
2
|
+
export declare const info: (message: string) => void;
|
|
3
|
+
export declare const error: (message: string) => void;
|
|
4
|
+
export declare const debug: (message: string) => void;
|
|
5
|
+
export declare const log: (message: string) => void;
|
|
6
|
+
//# sourceMappingURL=log.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"log.d.ts","sourceRoot":"","sources":["../../src/utils/log.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,OAAO,YAAa,MAAM,KAAG,IAEzC,CAAA;AAED,eAAO,MAAM,IAAI,YAAa,MAAM,KAAG,IAEtC,CAAA;AAED,eAAO,MAAM,KAAK,YAAa,MAAM,KAAG,IAEvC,CAAA;AAED,eAAO,MAAM,KAAK,YAAa,MAAM,KAAG,IAIvC,CAAA;AAED,eAAO,MAAM,GAAG,YAAa,MAAM,KAAG,IAErC,CAAA"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as p from '@clack/prompts';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import { isDebug } from './is-debug.js';
|
|
4
|
+
export const warning = (message)=>{
|
|
5
|
+
p.log.warn(pc.yellow('? ') + pc.bold(message));
|
|
6
|
+
};
|
|
7
|
+
export const info = (message)=>{
|
|
8
|
+
p.log.step(pc.bold(message));
|
|
9
|
+
};
|
|
10
|
+
export const error = (message)=>{
|
|
11
|
+
p.log.error(pc.bold(message));
|
|
12
|
+
};
|
|
13
|
+
export const debug = (message)=>{
|
|
14
|
+
if (isDebug()) {
|
|
15
|
+
p.log.step(`${pc.bgMagenta('[DEBUG]')} ${pc.gray(message)}`);
|
|
16
|
+
}
|
|
17
|
+
};
|
|
18
|
+
export const log = (message)=>{
|
|
19
|
+
p.log.message(message);
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
//# sourceMappingURL=log.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/log.ts"],"sourcesContent":["import * as p from '@clack/prompts'\nimport pc from 'picocolors'\n\nimport { isDebug } from './is-debug.js'\n\nexport const warning = (message: string): void => {\n p.log.warn(pc.yellow('? ') + pc.bold(message))\n}\n\nexport const info = (message: string): void => {\n p.log.step(pc.bold(message))\n}\n\nexport const error = (message: string): void => {\n p.log.error(pc.bold(message))\n}\n\nexport const debug = (message: string): void => {\n if (isDebug()) {\n p.log.step(`${pc.bgMagenta('[DEBUG]')} ${pc.gray(message)}`)\n }\n}\n\nexport const log = (message: string): void => {\n p.log.message(message)\n}\n"],"names":["p","pc","isDebug","warning","message","log","warn","yellow","bold","info","step","error","debug","bgMagenta","gray"],"mappings":"AAAA,YAAYA,OAAO,iBAAgB;AACnC,OAAOC,QAAQ,aAAY;AAE3B,SAASC,OAAO,QAAQ,gBAAe;AAEvC,OAAO,MAAMC,UAAU,CAACC;IACtBJ,EAAEK,GAAG,CAACC,IAAI,CAACL,GAAGM,MAAM,CAAC,QAAQN,GAAGO,IAAI,CAACJ;AACvC,EAAC;AAED,OAAO,MAAMK,OAAO,CAACL;IACnBJ,EAAEK,GAAG,CAACK,IAAI,CAACT,GAAGO,IAAI,CAACJ;AACrB,EAAC;AAED,OAAO,MAAMO,QAAQ,CAACP;IACpBJ,EAAEK,GAAG,CAACM,KAAK,CAACV,GAAGO,IAAI,CAACJ;AACtB,EAAC;AAED,OAAO,MAAMQ,QAAQ,CAACR;IACpB,IAAIF,WAAW;QACbF,EAAEK,GAAG,CAACK,IAAI,CAAC,GAAGT,GAAGY,SAAS,CAAC,WAAW,CAAC,EAAEZ,GAAGa,IAAI,CAACV,UAAU;IAC7D;AACF,EAAC;AAED,OAAO,MAAMC,MAAM,CAACD;IAClBJ,EAAEK,GAAG,CAACD,OAAO,CAACA;AAChB,EAAC"}
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { PackageManager } from '../types.js';
|
|
2
|
+
export declare function helpMessage(): void;
|
|
3
|
+
export declare function successMessage(projectDir: string, packageManager: PackageManager): string;
|
|
4
|
+
export declare function successfulNextInit(): string;
|
|
5
|
+
export declare function moveMessage(args: {
|
|
6
|
+
nextAppDir: string;
|
|
7
|
+
projectDir: string;
|
|
8
|
+
}): string;
|
|
9
|
+
export declare function feedbackOutro(): string;
|
|
10
|
+
//# sourceMappingURL=messages.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"messages.d.ts","sourceRoot":"","sources":["../../src/utils/messages.ts"],"names":[],"mappings":"AAKA,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,aAAa,CAAA;AAIjD,wBAAgB,WAAW,IAAI,IAAI,CA2ClC;AASD,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,cAAc,EAAE,cAAc,GAAG,MAAM,CAiBzF;AAED,wBAAgB,kBAAkB,IAAI,MAAM,CAO3C;AAED,wBAAgB,WAAW,CAAC,IAAI,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAA;CAAE,GAAG,MAAM,CAgBpF;AAED,wBAAgB,aAAa,IAAI,MAAM,CAEtC"}
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
/* eslint-disable no-console */ import path from 'path';
|
|
2
|
+
import pc from 'picocolors';
|
|
3
|
+
import terminalLink from 'terminal-link';
|
|
4
|
+
const header = (message)=>pc.bold(message);
|
|
5
|
+
export function helpMessage() {
|
|
6
|
+
console.log(`
|
|
7
|
+
${pc.bold('USAGE')}
|
|
8
|
+
|
|
9
|
+
${pc.dim('payloadcms-figma <command> [options]')}
|
|
10
|
+
|
|
11
|
+
${pc.bold('COMMANDS')}
|
|
12
|
+
|
|
13
|
+
${pc.cyan('login')} Authenticate with Figma OAuth2
|
|
14
|
+
${pc.cyan('logout')} Clear all stored tokens
|
|
15
|
+
${pc.cyan('list-tokens')} Show stored token information
|
|
16
|
+
${pc.cyan('init')} Initialize a Figma CMS project
|
|
17
|
+
${pc.cyan('deploy')} Deploy your project to Figma
|
|
18
|
+
|
|
19
|
+
${pc.bold('OPTIONS')}
|
|
20
|
+
|
|
21
|
+
${pc.dim('-h, --help Show help')}
|
|
22
|
+
${pc.dim('--debug Enable debug logging')}
|
|
23
|
+
|
|
24
|
+
${pc.bold('AUTHENTICATION')}
|
|
25
|
+
|
|
26
|
+
${pc.cyan('payloadcms-figma login')} Authenticate with Figma
|
|
27
|
+
${pc.cyan('payloadcms-figma logout')} Clear all tokens (with confirmation)
|
|
28
|
+
${pc.cyan('payloadcms-figma list-tokens')} Display stored OAuth and project tokens
|
|
29
|
+
|
|
30
|
+
${pc.bold('INIT COMMAND')}
|
|
31
|
+
|
|
32
|
+
${pc.cyan('payloadcms-figma init --id <cms-id>')} Initialize project with CMS ID
|
|
33
|
+
${pc.cyan('payloadcms-figma init')} Initialize (prompts for CMS ID)
|
|
34
|
+
${pc.cyan('payloadcms-figma init --name my-cms')} Specify project name for new projects
|
|
35
|
+
${pc.cyan('payloadcms-figma init --force')} Force reconfiguration of existing project
|
|
36
|
+
${pc.cyan('payloadcms-figma init --skip-auth')} Skip authentication (testing only)
|
|
37
|
+
|
|
38
|
+
${pc.bold('DEPLOY COMMAND')}
|
|
39
|
+
|
|
40
|
+
${pc.cyan('payloadcms-figma deploy')} Deploy your project to Figma
|
|
41
|
+
${pc.dim('--yes, -y')} Skip confirmation prompts
|
|
42
|
+
|
|
43
|
+
${pc.bold('DOCUMENTATION')}
|
|
44
|
+
|
|
45
|
+
${createTerminalLink('Getting Started', 'https://payloadcms.com/docs/getting-started/what-is-payload')}
|
|
46
|
+
${createTerminalLink('Figma CMS Docs', 'https://www.figma.com/developers/api')}
|
|
47
|
+
`);
|
|
48
|
+
}
|
|
49
|
+
// Create terminalLink with fallback for unsupported terminals
|
|
50
|
+
function createTerminalLink(text, url) {
|
|
51
|
+
return terminalLink(text, url, {
|
|
52
|
+
fallback: (text, url)=>`${text}: ${url}`
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
export function successMessage(projectDir, packageManager) {
|
|
56
|
+
const relativePath = path.relative(process.cwd(), projectDir);
|
|
57
|
+
return `
|
|
58
|
+
${header('Launch Application:')}
|
|
59
|
+
|
|
60
|
+
- cd ./${relativePath}
|
|
61
|
+
- ${packageManager === 'npm' ? 'npm run' : packageManager} dev or follow directions in README.md
|
|
62
|
+
|
|
63
|
+
${header('Documentation:')}
|
|
64
|
+
|
|
65
|
+
- ${createTerminalLink('Getting Started', 'https://payloadcms.com/docs/getting-started/what-is-payload')}
|
|
66
|
+
- ${createTerminalLink('Configuration', 'https://payloadcms.com/docs/configuration/overview')}
|
|
67
|
+
|
|
68
|
+
`;
|
|
69
|
+
}
|
|
70
|
+
export function successfulNextInit() {
|
|
71
|
+
return `- ${createTerminalLink('Getting Started', 'https://payloadcms.com/docs/getting-started/what-is-payload')}
|
|
72
|
+
- ${createTerminalLink('Configuration', 'https://payloadcms.com/docs/configuration/overview')}
|
|
73
|
+
`;
|
|
74
|
+
}
|
|
75
|
+
export function moveMessage(args) {
|
|
76
|
+
const relativeAppDir = path.relative(process.cwd(), args.nextAppDir);
|
|
77
|
+
return `
|
|
78
|
+
${header('Next Steps:')}
|
|
79
|
+
|
|
80
|
+
Payload does not support a top-level layout.tsx file in the app directory.
|
|
81
|
+
|
|
82
|
+
${pc.bold('To continue:')}
|
|
83
|
+
|
|
84
|
+
- Create a new directory in ./${relativeAppDir} such as ./${relativeAppDir}/${pc.bold('(app)')}
|
|
85
|
+
- Move all files from ./${relativeAppDir} into that directory
|
|
86
|
+
|
|
87
|
+
It is recommended to do this from your IDE if your app has existing file references.
|
|
88
|
+
|
|
89
|
+
Once moved, rerun the payloadcms-figma command again.
|
|
90
|
+
`;
|
|
91
|
+
}
|
|
92
|
+
export function feedbackOutro() {
|
|
93
|
+
return `${pc.bgCyan(pc.black(' Have feedback? '))} Visit us on ${createTerminalLink('GitHub', 'https://github.com/payloadcms/payload')}.`;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
//# sourceMappingURL=messages.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/messages.ts"],"sourcesContent":["/* eslint-disable no-console */\nimport path from 'path'\nimport pc from 'picocolors'\nimport terminalLink from 'terminal-link'\n\nimport type { PackageManager } from '../types.js'\n\nconst header = (message: string): string => pc.bold(message)\n\nexport function helpMessage(): void {\n console.log(`\n ${pc.bold('USAGE')}\n\n ${pc.dim('payloadcms-figma <command> [options]')}\n\n ${pc.bold('COMMANDS')}\n\n ${pc.cyan('login')} Authenticate with Figma OAuth2\n ${pc.cyan('logout')} Clear all stored tokens\n ${pc.cyan('list-tokens')} Show stored token information\n ${pc.cyan('init')} Initialize a Figma CMS project\n ${pc.cyan('deploy')} Deploy your project to Figma\n\n ${pc.bold('OPTIONS')}\n\n ${pc.dim('-h, --help Show help')}\n ${pc.dim('--debug Enable debug logging')}\n\n ${pc.bold('AUTHENTICATION')}\n\n ${pc.cyan('payloadcms-figma login')} Authenticate with Figma\n ${pc.cyan('payloadcms-figma logout')} Clear all tokens (with confirmation)\n ${pc.cyan('payloadcms-figma list-tokens')} Display stored OAuth and project tokens\n\n ${pc.bold('INIT COMMAND')}\n\n ${pc.cyan('payloadcms-figma init --id <cms-id>')} Initialize project with CMS ID\n ${pc.cyan('payloadcms-figma init')} Initialize (prompts for CMS ID)\n ${pc.cyan('payloadcms-figma init --name my-cms')} Specify project name for new projects\n ${pc.cyan('payloadcms-figma init --force')} Force reconfiguration of existing project\n ${pc.cyan('payloadcms-figma init --skip-auth')} Skip authentication (testing only)\n\n ${pc.bold('DEPLOY COMMAND')}\n\n ${pc.cyan('payloadcms-figma deploy')} Deploy your project to Figma\n ${pc.dim('--yes, -y')} Skip confirmation prompts\n\n ${pc.bold('DOCUMENTATION')}\n\n ${createTerminalLink('Getting Started', 'https://payloadcms.com/docs/getting-started/what-is-payload')}\n ${createTerminalLink('Figma CMS Docs', 'https://www.figma.com/developers/api')}\n`)\n}\n\n// Create terminalLink with fallback for unsupported terminals\nfunction createTerminalLink(text: string, url: string) {\n return terminalLink(text, url, {\n fallback: (text, url) => `${text}: ${url}`,\n })\n}\n\nexport function successMessage(projectDir: string, packageManager: PackageManager): string {\n const relativePath = path.relative(process.cwd(), projectDir)\n return `\n${header('Launch Application:')}\n\n - cd ./${relativePath}\n - ${packageManager === 'npm' ? 'npm run' : packageManager} dev or follow directions in README.md\n\n${header('Documentation:')}\n\n - ${createTerminalLink(\n 'Getting Started',\n 'https://payloadcms.com/docs/getting-started/what-is-payload',\n )}\n - ${createTerminalLink('Configuration', 'https://payloadcms.com/docs/configuration/overview')}\n\n`\n}\n\nexport function successfulNextInit(): string {\n return `- ${createTerminalLink(\n 'Getting Started',\n 'https://payloadcms.com/docs/getting-started/what-is-payload',\n )}\n- ${createTerminalLink('Configuration', 'https://payloadcms.com/docs/configuration/overview')}\n`\n}\n\nexport function moveMessage(args: { nextAppDir: string; projectDir: string }): string {\n const relativeAppDir = path.relative(process.cwd(), args.nextAppDir)\n return `\n${header('Next Steps:')}\n\nPayload does not support a top-level layout.tsx file in the app directory.\n\n${pc.bold('To continue:')}\n\n- Create a new directory in ./${relativeAppDir} such as ./${relativeAppDir}/${pc.bold('(app)')}\n- Move all files from ./${relativeAppDir} into that directory\n\nIt is recommended to do this from your IDE if your app has existing file references.\n\nOnce moved, rerun the payloadcms-figma command again.\n`\n}\n\nexport function feedbackOutro(): string {\n return `${pc.bgCyan(pc.black(' Have feedback? '))} Visit us on ${createTerminalLink('GitHub', 'https://github.com/payloadcms/payload')}.`\n}\n"],"names":["path","pc","terminalLink","header","message","bold","helpMessage","console","log","dim","cyan","createTerminalLink","text","url","fallback","successMessage","projectDir","packageManager","relativePath","relative","process","cwd","successfulNextInit","moveMessage","args","relativeAppDir","nextAppDir","feedbackOutro","bgCyan","black"],"mappings":"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"}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Supported package managers
|
|
3
|
+
*/
|
|
4
|
+
export type PackageManager = 'npm' | 'pnpm' | 'yarn';
|
|
5
|
+
/**
|
|
6
|
+
* Detect package manager from lockfiles
|
|
7
|
+
*
|
|
8
|
+
* @param projectDir - Project directory to check
|
|
9
|
+
* @returns Detected package manager, defaults to npm
|
|
10
|
+
*/
|
|
11
|
+
export declare function getPackageManager(projectDir: string): Promise<PackageManager>;
|
|
12
|
+
//# sourceMappingURL=package-manager.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-manager.d.ts","sourceRoot":"","sources":["../../src/utils/package-manager.ts"],"names":[],"mappings":"AAGA;;GAEG;AACH,MAAM,MAAM,cAAc,GAAG,KAAK,GAAG,MAAM,GAAG,MAAM,CAAA;AAEpD;;;;;GAKG;AACH,wBAAsB,iBAAiB,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAoBnF"}
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/**
|
|
4
|
+
* Detect package manager from lockfiles
|
|
5
|
+
*
|
|
6
|
+
* @param projectDir - Project directory to check
|
|
7
|
+
* @returns Detected package manager, defaults to npm
|
|
8
|
+
*/ export async function getPackageManager(projectDir) {
|
|
9
|
+
try {
|
|
10
|
+
// Check for lockfiles in order of preference
|
|
11
|
+
if (await fileExists(path.join(projectDir, 'pnpm-lock.yaml'))) {
|
|
12
|
+
return 'pnpm';
|
|
13
|
+
}
|
|
14
|
+
if (await fileExists(path.join(projectDir, 'yarn.lock'))) {
|
|
15
|
+
return 'yarn';
|
|
16
|
+
}
|
|
17
|
+
if (await fileExists(path.join(projectDir, 'package-lock.json'))) {
|
|
18
|
+
return 'npm';
|
|
19
|
+
}
|
|
20
|
+
// Default to npm if no lockfile found
|
|
21
|
+
return 'npm';
|
|
22
|
+
} catch {
|
|
23
|
+
return 'npm';
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Check if file exists
|
|
28
|
+
*/ async function fileExists(filePath) {
|
|
29
|
+
try {
|
|
30
|
+
await fs.stat(filePath);
|
|
31
|
+
return true;
|
|
32
|
+
} catch {
|
|
33
|
+
return false;
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
//# sourceMappingURL=package-manager.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/package-manager.ts"],"sourcesContent":["import fs from 'fs/promises'\nimport path from 'path'\n\n/**\n * Supported package managers\n */\nexport type PackageManager = 'npm' | 'pnpm' | 'yarn'\n\n/**\n * Detect package manager from lockfiles\n *\n * @param projectDir - Project directory to check\n * @returns Detected package manager, defaults to npm\n */\nexport async function getPackageManager(projectDir: string): Promise<PackageManager> {\n try {\n // Check for lockfiles in order of preference\n if (await fileExists(path.join(projectDir, 'pnpm-lock.yaml'))) {\n return 'pnpm'\n }\n\n if (await fileExists(path.join(projectDir, 'yarn.lock'))) {\n return 'yarn'\n }\n\n if (await fileExists(path.join(projectDir, 'package-lock.json'))) {\n return 'npm'\n }\n\n // Default to npm if no lockfile found\n return 'npm'\n } catch {\n return 'npm'\n }\n}\n\n/**\n * Check if file exists\n */\nasync function fileExists(filePath: string): Promise<boolean> {\n try {\n await fs.stat(filePath)\n return true\n } catch {\n return false\n }\n}\n"],"names":["fs","path","getPackageManager","projectDir","fileExists","join","filePath","stat"],"mappings":"AAAA,OAAOA,QAAQ,cAAa;AAC5B,OAAOC,UAAU,OAAM;AAOvB;;;;;CAKC,GACD,OAAO,eAAeC,kBAAkBC,UAAkB;IACxD,IAAI;QACF,6CAA6C;QAC7C,IAAI,MAAMC,WAAWH,KAAKI,IAAI,CAACF,YAAY,oBAAoB;YAC7D,OAAO;QACT;QAEA,IAAI,MAAMC,WAAWH,KAAKI,IAAI,CAACF,YAAY,eAAe;YACxD,OAAO;QACT;QAEA,IAAI,MAAMC,WAAWH,KAAKI,IAAI,CAACF,YAAY,uBAAuB;YAChE,OAAO;QACT;QAEA,sCAAsC;QACtC,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF;AAEA;;CAEC,GACD,eAAeC,WAAWE,QAAgB;IACxC,IAAI;QACF,MAAMN,GAAGO,IAAI,CAACD;QACd,OAAO;IACT,EAAE,OAAM;QACN,OAAO;IACT;AACF"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { SourceFile } from 'ts-morph';
|
|
2
|
+
export type DetectionResult = {
|
|
3
|
+
buildConfigNotFound?: boolean;
|
|
4
|
+
dbProperty?: {
|
|
5
|
+
adapter: string;
|
|
6
|
+
importSource: string;
|
|
7
|
+
};
|
|
8
|
+
editorProperty?: {
|
|
9
|
+
importSource: string;
|
|
10
|
+
isDefault: boolean;
|
|
11
|
+
};
|
|
12
|
+
hasAlias: boolean;
|
|
13
|
+
hasOtherPayloadImports: boolean;
|
|
14
|
+
needsImportChange: boolean;
|
|
15
|
+
secretProperty?: boolean;
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Detect what changes are needed in the payload config file
|
|
19
|
+
*/
|
|
20
|
+
export declare function detectRequiredChanges(sourceFile: SourceFile): DetectionResult;
|
|
21
|
+
export type ASTModificationResult = {
|
|
22
|
+
changes: string[];
|
|
23
|
+
modified: boolean;
|
|
24
|
+
};
|
|
25
|
+
/**
|
|
26
|
+
* Apply modifications to the source file based on detection result
|
|
27
|
+
* Modifies the AST in memory - caller must call sourceFile.save()
|
|
28
|
+
*/
|
|
29
|
+
export declare function applyModifications(sourceFile: SourceFile, detection: DetectionResult): ASTModificationResult;
|
|
30
|
+
//# sourceMappingURL=payload-config-ast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"payload-config-ast.d.ts","sourceRoot":"","sources":["../../src/utils/payload-config-ast.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,UAAU,CAAA;AAO1C,MAAM,MAAM,eAAe,GAAG;IAC5B,mBAAmB,CAAC,EAAE,OAAO,CAAA;IAC7B,UAAU,CAAC,EAAE;QACX,OAAO,EAAE,MAAM,CAAA;QACf,YAAY,EAAE,MAAM,CAAA;KACrB,CAAA;IACD,cAAc,CAAC,EAAE;QACf,YAAY,EAAE,MAAM,CAAA;QACpB,SAAS,EAAE,OAAO,CAAA;KACnB,CAAA;IACD,QAAQ,EAAE,OAAO,CAAA;IACjB,sBAAsB,EAAE,OAAO,CAAA;IAC/B,iBAAiB,EAAE,OAAO,CAAA;IAC1B,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB,CAAA;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,UAAU,EAAE,UAAU,GAAG,eAAe,CA8I7E;AAED,MAAM,MAAM,qBAAqB,GAAG;IAClC,OAAO,EAAE,MAAM,EAAE,CAAA;IACjB,QAAQ,EAAE,OAAO,CAAA;CAClB,CAAA;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,UAAU,EACtB,SAAS,EAAE,eAAe,GACzB,qBAAqB,CAoJvB"}
|