@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,252 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Project detection and scaffolding utilities
|
|
3
|
+
*/ import { spawn } from 'child_process';
|
|
4
|
+
import fs from 'fs/promises';
|
|
5
|
+
import path from 'path';
|
|
6
|
+
import { ensureGitignore } from './config.js';
|
|
7
|
+
import { downloadTemplateFromGitHub } from './download-template.js';
|
|
8
|
+
import { manageEnvFiles } from './env-management.js';
|
|
9
|
+
import { tryInitRepoAndCommit } from './git.js';
|
|
10
|
+
import { applyLambdaModifications } from './lambda-config.js';
|
|
11
|
+
/**
|
|
12
|
+
* Detect if current directory has a Payload project
|
|
13
|
+
*
|
|
14
|
+
* @param projectPath - Path to check (defaults to cwd)
|
|
15
|
+
* @returns Project information
|
|
16
|
+
*/ export async function detectPayloadProject(projectPath = process.cwd()) {
|
|
17
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
18
|
+
try {
|
|
19
|
+
const content = await fs.readFile(packageJsonPath, 'utf-8');
|
|
20
|
+
const packageJson = JSON.parse(content);
|
|
21
|
+
// Check for payload in dependencies or devDependencies
|
|
22
|
+
const payloadVersion = packageJson.dependencies?.payload || packageJson.devDependencies?.payload;
|
|
23
|
+
// Detect package manager
|
|
24
|
+
let packageManager = 'npm';
|
|
25
|
+
try {
|
|
26
|
+
await fs.access(path.join(projectPath, 'pnpm-lock.yaml'));
|
|
27
|
+
packageManager = 'pnpm';
|
|
28
|
+
} catch {
|
|
29
|
+
try {
|
|
30
|
+
await fs.access(path.join(projectPath, 'yarn.lock'));
|
|
31
|
+
packageManager = 'yarn';
|
|
32
|
+
} catch {
|
|
33
|
+
packageManager = 'npm';
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
return {
|
|
37
|
+
hasPayload: !!payloadVersion,
|
|
38
|
+
packageManager,
|
|
39
|
+
path: projectPath,
|
|
40
|
+
payloadVersion: payloadVersion || undefined
|
|
41
|
+
};
|
|
42
|
+
} catch (error) {
|
|
43
|
+
if (error.code === 'ENOENT') {
|
|
44
|
+
// No package.json found
|
|
45
|
+
return {
|
|
46
|
+
hasPayload: false,
|
|
47
|
+
path: projectPath
|
|
48
|
+
};
|
|
49
|
+
}
|
|
50
|
+
throw new Error(`Failed to read package.json: ${error.message}`);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
/**
|
|
54
|
+
* Validate Payload version (must be 3.x)
|
|
55
|
+
*
|
|
56
|
+
* @param version - Version string from package.json
|
|
57
|
+
* @returns True if version is valid
|
|
58
|
+
*/ export function validatePayloadVersion(version) {
|
|
59
|
+
// Extract major version (handle ^3.0.0, ~3.0.0, 3.0.0, etc.)
|
|
60
|
+
const match = version.match(/(\d+)/);
|
|
61
|
+
if (!match) {
|
|
62
|
+
return false;
|
|
63
|
+
}
|
|
64
|
+
const majorVersion = parseInt(match[1], 10);
|
|
65
|
+
return majorVersion === 3;
|
|
66
|
+
}
|
|
67
|
+
/**
|
|
68
|
+
* Fetch the latest version of a package from npm registry
|
|
69
|
+
*
|
|
70
|
+
* @param packageName - Package name to fetch version for
|
|
71
|
+
* @returns Latest version string
|
|
72
|
+
*/ async function getLatestPackageVersion(packageName) {
|
|
73
|
+
const response = await fetch(`https://registry.npmjs.org/-/package/${packageName}/dist-tags`);
|
|
74
|
+
if (!response.ok) {
|
|
75
|
+
throw new Error(`Failed to fetch version for ${packageName}: ${response.statusText}`);
|
|
76
|
+
}
|
|
77
|
+
const data = await response.json();
|
|
78
|
+
if (typeof data.latest !== 'string') {
|
|
79
|
+
throw new Error(`Invalid version data received for ${packageName}`);
|
|
80
|
+
}
|
|
81
|
+
return data.latest;
|
|
82
|
+
}
|
|
83
|
+
/**
|
|
84
|
+
* Replace workspace versions in package.json with actual versions
|
|
85
|
+
*
|
|
86
|
+
* @param packageJson - Package JSON object to update
|
|
87
|
+
* @param latestVersion - Latest Payload version to use
|
|
88
|
+
*/ function replaceWorkspaceVersions(packageJson, latestVersion) {
|
|
89
|
+
const deps = packageJson.dependencies;
|
|
90
|
+
if (!deps) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
for (const [key, value] of Object.entries(deps)){
|
|
94
|
+
// Replace workspace:* or workspace:^ with actual version
|
|
95
|
+
if (typeof value === 'string' && value.startsWith('workspace:')) {
|
|
96
|
+
deps[key] = latestVersion;
|
|
97
|
+
} else if (key === 'payload' || key.startsWith('@payloadcms/')) {
|
|
98
|
+
deps[key] = latestVersion;
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Also handle devDependencies if present
|
|
102
|
+
const devDeps = packageJson.devDependencies;
|
|
103
|
+
if (!devDeps) {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
for (const [key, value] of Object.entries(devDeps)){
|
|
107
|
+
if (typeof value === 'string' && value.startsWith('workspace:')) {
|
|
108
|
+
devDeps[key] = latestVersion;
|
|
109
|
+
} else if (key === 'payload' || key.startsWith('@payloadcms/')) {
|
|
110
|
+
devDeps[key] = latestVersion;
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
}
|
|
114
|
+
/**
|
|
115
|
+
* Scaffold a new Payload project from GitHub template
|
|
116
|
+
*
|
|
117
|
+
* @param projectPath - Path where to create the project
|
|
118
|
+
* @param projectName - Name for the project
|
|
119
|
+
*/ export async function scaffoldProject(projectPath, projectName) {
|
|
120
|
+
// Create project directory if it doesn't exist
|
|
121
|
+
await fs.mkdir(projectPath, {
|
|
122
|
+
recursive: true
|
|
123
|
+
});
|
|
124
|
+
// Download template from GitHub
|
|
125
|
+
await downloadTemplateFromGitHub(projectPath);
|
|
126
|
+
// Apply Lambda modifications BEFORE updating package.json
|
|
127
|
+
// This ensures we don't overwrite version replacements
|
|
128
|
+
await applyLambdaModifications(projectPath);
|
|
129
|
+
// Get latest Payload version from npm
|
|
130
|
+
const latestVersion = await getLatestPackageVersion('payload');
|
|
131
|
+
// Delete any existing lock files from template (they reference workspace:* versions)
|
|
132
|
+
// This ensures pnpm install creates a fresh lock file with actual versions
|
|
133
|
+
const lockFiles = [
|
|
134
|
+
'pnpm-lock.yaml',
|
|
135
|
+
'yarn.lock',
|
|
136
|
+
'package-lock.json'
|
|
137
|
+
];
|
|
138
|
+
for (const lockFile of lockFiles){
|
|
139
|
+
try {
|
|
140
|
+
await fs.unlink(path.join(projectPath, lockFile));
|
|
141
|
+
} catch {
|
|
142
|
+
// File doesn't exist, ignore
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
// Update package.json: set name, replace workspace versions
|
|
146
|
+
// This must come AFTER applyLambdaModifications to ensure we have final versions
|
|
147
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
148
|
+
const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8');
|
|
149
|
+
const packageJson = JSON.parse(packageJsonContent);
|
|
150
|
+
packageJson.name = projectName;
|
|
151
|
+
// Replace workspace:* versions with actual versions
|
|
152
|
+
replaceWorkspaceVersions(packageJson, latestVersion);
|
|
153
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
|
|
154
|
+
// Manage environment files (generate PAYLOAD_SECRET)
|
|
155
|
+
await manageEnvFiles(projectPath);
|
|
156
|
+
// Ensure .gitignore has required entries
|
|
157
|
+
await ensureGitignore(projectPath, [
|
|
158
|
+
'.env',
|
|
159
|
+
'.env.local',
|
|
160
|
+
'lambda.zip'
|
|
161
|
+
]);
|
|
162
|
+
}
|
|
163
|
+
/**
|
|
164
|
+
* Initialize git repository after all setup is complete
|
|
165
|
+
*
|
|
166
|
+
* This should be called AFTER installDependencies so that lock files are included
|
|
167
|
+
*
|
|
168
|
+
* @param projectPath - Path to project directory
|
|
169
|
+
*/ export function initializeGitRepo(projectPath) {
|
|
170
|
+
tryInitRepoAndCommit(projectPath);
|
|
171
|
+
}
|
|
172
|
+
/**
|
|
173
|
+
* Install dependencies using the detected package manager
|
|
174
|
+
*
|
|
175
|
+
* @param projectPath - Path to project
|
|
176
|
+
* @param packageManager - Package manager to use
|
|
177
|
+
* @returns Promise that resolves when installation completes
|
|
178
|
+
*/ export async function installDependencies(projectPath, packageManager = 'npm') {
|
|
179
|
+
return new Promise((resolve, reject)=>{
|
|
180
|
+
const child = spawn(packageManager, [
|
|
181
|
+
'install'
|
|
182
|
+
], {
|
|
183
|
+
cwd: projectPath,
|
|
184
|
+
shell: true,
|
|
185
|
+
stdio: 'pipe'
|
|
186
|
+
});
|
|
187
|
+
let stdout = '';
|
|
188
|
+
let stderr = '';
|
|
189
|
+
// Capture stdout
|
|
190
|
+
child.stdout?.on('data', (data)=>{
|
|
191
|
+
stdout += data.toString();
|
|
192
|
+
});
|
|
193
|
+
// Capture stderr
|
|
194
|
+
child.stderr?.on('data', (data)=>{
|
|
195
|
+
stderr += data.toString();
|
|
196
|
+
});
|
|
197
|
+
child.on('close', (code)=>{
|
|
198
|
+
if (code === 0) {
|
|
199
|
+
resolve();
|
|
200
|
+
} else {
|
|
201
|
+
// Show captured output on error
|
|
202
|
+
const output = [
|
|
203
|
+
stdout,
|
|
204
|
+
stderr
|
|
205
|
+
].filter(Boolean).join('\n\n');
|
|
206
|
+
const errorMessage = output ? `${packageManager} install failed with code ${code}\n\nOutput:\n${output}` : `${packageManager} install failed with code ${code}`;
|
|
207
|
+
reject(new Error(errorMessage));
|
|
208
|
+
}
|
|
209
|
+
});
|
|
210
|
+
child.on('error', (error)=>{
|
|
211
|
+
reject(new Error(`Failed to run ${packageManager} install: ${error.message}`));
|
|
212
|
+
});
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
/**
|
|
216
|
+
* Check if required dependencies are installed
|
|
217
|
+
*
|
|
218
|
+
* @param projectPath - Path to project
|
|
219
|
+
* @returns True if all required dependencies exist
|
|
220
|
+
*/ export async function hasRequiredDependencies(projectPath) {
|
|
221
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
222
|
+
try {
|
|
223
|
+
const content = await fs.readFile(packageJsonPath, 'utf-8');
|
|
224
|
+
const packageJson = JSON.parse(content);
|
|
225
|
+
// Check for Payload and Next.js
|
|
226
|
+
const hasPayload = packageJson.dependencies?.payload || packageJson.devDependencies?.payload;
|
|
227
|
+
const hasNext = packageJson.dependencies?.next || packageJson.devDependencies?.next;
|
|
228
|
+
return !!(hasPayload && hasNext);
|
|
229
|
+
} catch {
|
|
230
|
+
return false;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Check if current directory is a project directory
|
|
235
|
+
*
|
|
236
|
+
* A project directory has package.json OR figma.config.json
|
|
237
|
+
*
|
|
238
|
+
* @param projectPath - Path to check (defaults to cwd)
|
|
239
|
+
* @returns True if in project directory
|
|
240
|
+
*/ export async function isInProjectDirectory(projectPath = process.cwd()) {
|
|
241
|
+
try {
|
|
242
|
+
// Check for package.json
|
|
243
|
+
const hasPackageJson = await fs.access(path.join(projectPath, 'package.json')).then(()=>true).catch(()=>false);
|
|
244
|
+
// Check for figma.config.json
|
|
245
|
+
const hasFigmaConfig = await fs.access(path.join(projectPath, 'figma.config.json')).then(()=>true).catch(()=>false);
|
|
246
|
+
return hasPackageJson || hasFigmaConfig;
|
|
247
|
+
} catch {
|
|
248
|
+
return false;
|
|
249
|
+
}
|
|
250
|
+
}
|
|
251
|
+
|
|
252
|
+
//# sourceMappingURL=project.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/project.ts"],"sourcesContent":["/**\n * Project detection and scaffolding utilities\n */\n\nimport { spawn } from 'child_process'\nimport fs from 'fs/promises'\nimport path from 'path'\n\nimport type { ProjectInfo } from '../types/config.js'\n\nimport { ensureGitignore } from './config.js'\nimport { downloadTemplateFromGitHub } from './download-template.js'\nimport { manageEnvFiles } from './env-management.js'\nimport { tryInitRepoAndCommit } from './git.js'\nimport { applyLambdaModifications } from './lambda-config.js'\n\n/**\n * Detect if current directory has a Payload project\n *\n * @param projectPath - Path to check (defaults to cwd)\n * @returns Project information\n */\nexport async function detectPayloadProject(\n projectPath: string = process.cwd(),\n): Promise<ProjectInfo> {\n const packageJsonPath = path.join(projectPath, 'package.json')\n\n try {\n const content = await fs.readFile(packageJsonPath, 'utf-8')\n const packageJson = JSON.parse(content)\n\n // Check for payload in dependencies or devDependencies\n const payloadVersion = packageJson.dependencies?.payload || packageJson.devDependencies?.payload\n\n // Detect package manager\n let packageManager: 'npm' | 'pnpm' | 'yarn' = 'npm'\n try {\n await fs.access(path.join(projectPath, 'pnpm-lock.yaml'))\n packageManager = 'pnpm'\n } catch {\n try {\n await fs.access(path.join(projectPath, 'yarn.lock'))\n packageManager = 'yarn'\n } catch {\n packageManager = 'npm'\n }\n }\n\n return {\n hasPayload: !!payloadVersion,\n packageManager,\n path: projectPath,\n payloadVersion: payloadVersion || undefined,\n }\n } catch (error) {\n if ((error as NodeJS.ErrnoException).code === 'ENOENT') {\n // No package.json found\n return {\n hasPayload: false,\n path: projectPath,\n }\n }\n throw new Error(`Failed to read package.json: ${(error as Error).message}`)\n }\n}\n\n/**\n * Validate Payload version (must be 3.x)\n *\n * @param version - Version string from package.json\n * @returns True if version is valid\n */\nexport function validatePayloadVersion(version: string): boolean {\n // Extract major version (handle ^3.0.0, ~3.0.0, 3.0.0, etc.)\n const match = version.match(/(\\d+)/)\n if (!match) {\n return false\n }\n\n const majorVersion = parseInt(match[1], 10)\n return majorVersion === 3\n}\n\n/**\n * Fetch the latest version of a package from npm registry\n *\n * @param packageName - Package name to fetch version for\n * @returns Latest version string\n */\nasync function getLatestPackageVersion(packageName: string): Promise<string> {\n const response = await fetch(`https://registry.npmjs.org/-/package/${packageName}/dist-tags`)\n\n if (!response.ok) {\n throw new Error(`Failed to fetch version for ${packageName}: ${response.statusText}`)\n }\n\n const data = (await response.json()) as Record<string, unknown>\n\n if (typeof data.latest !== 'string') {\n throw new Error(`Invalid version data received for ${packageName}`)\n }\n\n return data.latest\n}\n\n/**\n * Replace workspace versions in package.json with actual versions\n *\n * @param packageJson - Package JSON object to update\n * @param latestVersion - Latest Payload version to use\n */\nfunction replaceWorkspaceVersions(\n packageJson: Record<string, unknown>,\n latestVersion: string,\n): void {\n const deps = packageJson.dependencies as Record<string, string> | undefined\n if (!deps) {\n return\n }\n\n for (const [key, value] of Object.entries(deps)) {\n // Replace workspace:* or workspace:^ with actual version\n if (typeof value === 'string' && value.startsWith('workspace:')) {\n deps[key] = latestVersion\n }\n // Ensure all payload packages use the same version\n else if (key === 'payload' || key.startsWith('@payloadcms/')) {\n deps[key] = latestVersion\n }\n }\n\n // Also handle devDependencies if present\n const devDeps = packageJson.devDependencies as Record<string, string> | undefined\n if (!devDeps) {\n return\n }\n\n for (const [key, value] of Object.entries(devDeps)) {\n if (typeof value === 'string' && value.startsWith('workspace:')) {\n devDeps[key] = latestVersion\n } else if (key === 'payload' || key.startsWith('@payloadcms/')) {\n devDeps[key] = latestVersion\n }\n }\n}\n\n/**\n * Scaffold a new Payload project from GitHub template\n *\n * @param projectPath - Path where to create the project\n * @param projectName - Name for the project\n */\nexport async function scaffoldProject(projectPath: string, projectName: string): Promise<void> {\n // Create project directory if it doesn't exist\n await fs.mkdir(projectPath, { recursive: true })\n\n // Download template from GitHub\n await downloadTemplateFromGitHub(projectPath)\n\n // Apply Lambda modifications BEFORE updating package.json\n // This ensures we don't overwrite version replacements\n await applyLambdaModifications(projectPath)\n\n // Get latest Payload version from npm\n const latestVersion = await getLatestPackageVersion('payload')\n\n // Delete any existing lock files from template (they reference workspace:* versions)\n // This ensures pnpm install creates a fresh lock file with actual versions\n const lockFiles = ['pnpm-lock.yaml', 'yarn.lock', 'package-lock.json']\n for (const lockFile of lockFiles) {\n try {\n await fs.unlink(path.join(projectPath, lockFile))\n } catch {\n // File doesn't exist, ignore\n }\n }\n\n // Update package.json: set name, replace workspace versions\n // This must come AFTER applyLambdaModifications to ensure we have final versions\n const packageJsonPath = path.join(projectPath, 'package.json')\n const packageJsonContent = await fs.readFile(packageJsonPath, 'utf-8')\n const packageJson = JSON.parse(packageJsonContent) as Record<string, unknown>\n packageJson.name = projectName\n\n // Replace workspace:* versions with actual versions\n replaceWorkspaceVersions(packageJson, latestVersion)\n\n await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\\n', 'utf-8')\n\n // Manage environment files (generate PAYLOAD_SECRET)\n await manageEnvFiles(projectPath)\n\n // Ensure .gitignore has required entries\n await ensureGitignore(projectPath, ['.env', '.env.local', 'lambda.zip'])\n}\n\n/**\n * Initialize git repository after all setup is complete\n *\n * This should be called AFTER installDependencies so that lock files are included\n *\n * @param projectPath - Path to project directory\n */\nexport function initializeGitRepo(projectPath: string): void {\n tryInitRepoAndCommit(projectPath)\n}\n\n/**\n * Install dependencies using the detected package manager\n *\n * @param projectPath - Path to project\n * @param packageManager - Package manager to use\n * @returns Promise that resolves when installation completes\n */\nexport async function installDependencies(\n projectPath: string,\n packageManager: 'npm' | 'pnpm' | 'yarn' = 'npm',\n): Promise<void> {\n return new Promise((resolve, reject) => {\n const child = spawn(packageManager, ['install'], {\n cwd: projectPath,\n shell: true,\n stdio: 'pipe', // Capture output to avoid interfering with spinner\n })\n\n let stdout = ''\n let stderr = ''\n\n // Capture stdout\n child.stdout?.on('data', (data) => {\n stdout += data.toString()\n })\n\n // Capture stderr\n child.stderr?.on('data', (data) => {\n stderr += data.toString()\n })\n\n child.on('close', (code) => {\n if (code === 0) {\n resolve()\n } else {\n // Show captured output on error\n const output = [stdout, stderr].filter(Boolean).join('\\n\\n')\n const errorMessage = output\n ? `${packageManager} install failed with code ${code}\\n\\nOutput:\\n${output}`\n : `${packageManager} install failed with code ${code}`\n reject(new Error(errorMessage))\n }\n })\n\n child.on('error', (error) => {\n reject(new Error(`Failed to run ${packageManager} install: ${error.message}`))\n })\n })\n}\n\n/**\n * Check if required dependencies are installed\n *\n * @param projectPath - Path to project\n * @returns True if all required dependencies exist\n */\nexport async function hasRequiredDependencies(projectPath: string): Promise<boolean> {\n const packageJsonPath = path.join(projectPath, 'package.json')\n\n try {\n const content = await fs.readFile(packageJsonPath, 'utf-8')\n const packageJson = JSON.parse(content)\n\n // Check for Payload and Next.js\n const hasPayload = packageJson.dependencies?.payload || packageJson.devDependencies?.payload\n const hasNext = packageJson.dependencies?.next || packageJson.devDependencies?.next\n\n return !!(hasPayload && hasNext)\n } catch {\n return false\n }\n}\n\n/**\n * Check if current directory is a project directory\n *\n * A project directory has package.json OR figma.config.json\n *\n * @param projectPath - Path to check (defaults to cwd)\n * @returns True if in project directory\n */\nexport async function isInProjectDirectory(projectPath: string = process.cwd()): Promise<boolean> {\n try {\n // Check for package.json\n const hasPackageJson = await fs\n .access(path.join(projectPath, 'package.json'))\n .then(() => true)\n .catch(() => false)\n\n // Check for figma.config.json\n const hasFigmaConfig = await fs\n .access(path.join(projectPath, 'figma.config.json'))\n .then(() => true)\n .catch(() => false)\n\n return hasPackageJson || hasFigmaConfig\n } catch {\n return false\n }\n}\n"],"names":["spawn","fs","path","ensureGitignore","downloadTemplateFromGitHub","manageEnvFiles","tryInitRepoAndCommit","applyLambdaModifications","detectPayloadProject","projectPath","process","cwd","packageJsonPath","join","content","readFile","packageJson","JSON","parse","payloadVersion","dependencies","payload","devDependencies","packageManager","access","hasPayload","undefined","error","code","Error","message","validatePayloadVersion","version","match","majorVersion","parseInt","getLatestPackageVersion","packageName","response","fetch","ok","statusText","data","json","latest","replaceWorkspaceVersions","latestVersion","deps","key","value","Object","entries","startsWith","devDeps","scaffoldProject","projectName","mkdir","recursive","lockFiles","lockFile","unlink","packageJsonContent","name","writeFile","stringify","initializeGitRepo","installDependencies","Promise","resolve","reject","child","shell","stdio","stdout","stderr","on","toString","output","filter","Boolean","errorMessage","hasRequiredDependencies","hasNext","next","isInProjectDirectory","hasPackageJson","then","catch","hasFigmaConfig"],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"project.spec.d.ts","sourceRoot":"","sources":["../../src/utils/project.spec.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { afterEach, beforeEach, describe, expect, it, vi } from 'vitest';
|
|
4
|
+
import { detectPayloadProject, validatePayloadVersion } from './project.js';
|
|
5
|
+
describe('project utilities', ()=>{
|
|
6
|
+
let testDir;
|
|
7
|
+
beforeEach(async ()=>{
|
|
8
|
+
// Create unique temp directory for each test
|
|
9
|
+
testDir = path.join(process.cwd(), '.test-tmp', `project-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`);
|
|
10
|
+
await fs.mkdir(testDir, {
|
|
11
|
+
recursive: true
|
|
12
|
+
});
|
|
13
|
+
});
|
|
14
|
+
afterEach(async ()=>{
|
|
15
|
+
// Clean up test directory
|
|
16
|
+
try {
|
|
17
|
+
await fs.rm(testDir, {
|
|
18
|
+
force: true,
|
|
19
|
+
recursive: true
|
|
20
|
+
});
|
|
21
|
+
} catch {
|
|
22
|
+
// Ignore cleanup errors
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
describe('detectPayloadProject', ()=>{
|
|
26
|
+
it('should detect project with payload in dependencies', async ()=>{
|
|
27
|
+
const packageJson = {
|
|
28
|
+
name: 'test-project',
|
|
29
|
+
dependencies: {
|
|
30
|
+
next: '^15.0.0',
|
|
31
|
+
payload: '^3.54.0'
|
|
32
|
+
},
|
|
33
|
+
version: '1.0.0'
|
|
34
|
+
};
|
|
35
|
+
await fs.writeFile(path.join(testDir, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf-8');
|
|
36
|
+
const result = await detectPayloadProject(testDir);
|
|
37
|
+
expect(result.hasPayload).toBe(true);
|
|
38
|
+
expect(result.payloadVersion).toBe('^3.54.0');
|
|
39
|
+
expect(result.path).toBe(testDir);
|
|
40
|
+
});
|
|
41
|
+
it('should detect project with payload in devDependencies', async ()=>{
|
|
42
|
+
const packageJson = {
|
|
43
|
+
name: 'test-project',
|
|
44
|
+
devDependencies: {
|
|
45
|
+
payload: '3.50.0'
|
|
46
|
+
},
|
|
47
|
+
version: '1.0.0'
|
|
48
|
+
};
|
|
49
|
+
await fs.writeFile(path.join(testDir, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf-8');
|
|
50
|
+
const result = await detectPayloadProject(testDir);
|
|
51
|
+
expect(result.hasPayload).toBe(true);
|
|
52
|
+
expect(result.payloadVersion).toBe('3.50.0');
|
|
53
|
+
});
|
|
54
|
+
it('should return false if no payload dependency', async ()=>{
|
|
55
|
+
const packageJson = {
|
|
56
|
+
name: 'test-project',
|
|
57
|
+
dependencies: {
|
|
58
|
+
next: '^15.0.0',
|
|
59
|
+
react: '^19.0.0'
|
|
60
|
+
},
|
|
61
|
+
version: '1.0.0'
|
|
62
|
+
};
|
|
63
|
+
await fs.writeFile(path.join(testDir, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf-8');
|
|
64
|
+
const result = await detectPayloadProject(testDir);
|
|
65
|
+
expect(result.hasPayload).toBe(false);
|
|
66
|
+
expect(result.payloadVersion).toBeUndefined();
|
|
67
|
+
});
|
|
68
|
+
it('should return false if no package.json exists', async ()=>{
|
|
69
|
+
const result = await detectPayloadProject(testDir);
|
|
70
|
+
expect(result.hasPayload).toBe(false);
|
|
71
|
+
expect(result.payloadVersion).toBeUndefined();
|
|
72
|
+
});
|
|
73
|
+
it('should detect pnpm as package manager', async ()=>{
|
|
74
|
+
const packageJson = {
|
|
75
|
+
name: 'test-project',
|
|
76
|
+
dependencies: {
|
|
77
|
+
payload: '^3.0.0'
|
|
78
|
+
}
|
|
79
|
+
};
|
|
80
|
+
await fs.writeFile(path.join(testDir, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf-8');
|
|
81
|
+
await fs.writeFile(path.join(testDir, 'pnpm-lock.yaml'), '', 'utf-8');
|
|
82
|
+
const result = await detectPayloadProject(testDir);
|
|
83
|
+
expect(result.packageManager).toBe('pnpm');
|
|
84
|
+
});
|
|
85
|
+
it('should detect yarn as package manager', async ()=>{
|
|
86
|
+
const packageJson = {
|
|
87
|
+
name: 'test-project',
|
|
88
|
+
dependencies: {
|
|
89
|
+
payload: '^3.0.0'
|
|
90
|
+
}
|
|
91
|
+
};
|
|
92
|
+
await fs.writeFile(path.join(testDir, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf-8');
|
|
93
|
+
await fs.writeFile(path.join(testDir, 'yarn.lock'), '', 'utf-8');
|
|
94
|
+
const result = await detectPayloadProject(testDir);
|
|
95
|
+
expect(result.packageManager).toBe('yarn');
|
|
96
|
+
});
|
|
97
|
+
it('should default to npm as package manager', async ()=>{
|
|
98
|
+
const packageJson = {
|
|
99
|
+
name: 'test-project',
|
|
100
|
+
dependencies: {
|
|
101
|
+
payload: '^3.0.0'
|
|
102
|
+
}
|
|
103
|
+
};
|
|
104
|
+
await fs.writeFile(path.join(testDir, 'package.json'), JSON.stringify(packageJson, null, 2), 'utf-8');
|
|
105
|
+
const result = await detectPayloadProject(testDir);
|
|
106
|
+
expect(result.packageManager).toBe('npm');
|
|
107
|
+
});
|
|
108
|
+
it('should handle invalid package.json', async ()=>{
|
|
109
|
+
await fs.writeFile(path.join(testDir, 'package.json'), 'invalid json{', 'utf-8');
|
|
110
|
+
await expect(detectPayloadProject(testDir)).rejects.toThrow('Failed to read package.json');
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
describe('validatePayloadVersion', ()=>{
|
|
114
|
+
it('should accept version 3.x.x', ()=>{
|
|
115
|
+
expect(validatePayloadVersion('3.54.0')).toBe(true);
|
|
116
|
+
expect(validatePayloadVersion('3.0.0')).toBe(true);
|
|
117
|
+
expect(validatePayloadVersion('3.100.999')).toBe(true);
|
|
118
|
+
});
|
|
119
|
+
it('should accept version with caret', ()=>{
|
|
120
|
+
expect(validatePayloadVersion('^3.54.0')).toBe(true);
|
|
121
|
+
expect(validatePayloadVersion('^3.0.0')).toBe(true);
|
|
122
|
+
});
|
|
123
|
+
it('should accept version with tilde', ()=>{
|
|
124
|
+
expect(validatePayloadVersion('~3.54.0')).toBe(true);
|
|
125
|
+
expect(validatePayloadVersion('~3.0.0')).toBe(true);
|
|
126
|
+
});
|
|
127
|
+
it('should reject version 2.x.x', ()=>{
|
|
128
|
+
expect(validatePayloadVersion('2.54.0')).toBe(false);
|
|
129
|
+
expect(validatePayloadVersion('^2.0.0')).toBe(false);
|
|
130
|
+
});
|
|
131
|
+
it('should reject version 4.x.x', ()=>{
|
|
132
|
+
expect(validatePayloadVersion('4.0.0')).toBe(false);
|
|
133
|
+
expect(validatePayloadVersion('^4.0.0')).toBe(false);
|
|
134
|
+
});
|
|
135
|
+
it('should reject invalid version strings', ()=>{
|
|
136
|
+
expect(validatePayloadVersion('invalid')).toBe(false);
|
|
137
|
+
expect(validatePayloadVersion('x.y.z')).toBe(false);
|
|
138
|
+
expect(validatePayloadVersion('')).toBe(false);
|
|
139
|
+
});
|
|
140
|
+
it('should handle version ranges', ()=>{
|
|
141
|
+
expect(validatePayloadVersion('>=3.0.0')).toBe(true);
|
|
142
|
+
expect(validatePayloadVersion('>=3.0.0 <4.0.0')).toBe(true);
|
|
143
|
+
});
|
|
144
|
+
});
|
|
145
|
+
describe('scaffoldProject', ()=>{
|
|
146
|
+
it('should create project directory if it does not exist', async ()=>{
|
|
147
|
+
const { scaffoldProject } = await import('./project.js');
|
|
148
|
+
const newDir = path.join(testDir, 'new-project');
|
|
149
|
+
// Note: This will fail in test because template files don't exist in dist during test
|
|
150
|
+
// We're testing the directory creation part
|
|
151
|
+
try {
|
|
152
|
+
await scaffoldProject(newDir, 'test-project');
|
|
153
|
+
} catch {
|
|
154
|
+
// Expected to fail when trying to read templates
|
|
155
|
+
// But directory should still be created
|
|
156
|
+
}
|
|
157
|
+
const exists = await fs.access(newDir).then(()=>true).catch(()=>false);
|
|
158
|
+
expect(exists).toBe(true);
|
|
159
|
+
});
|
|
160
|
+
it('should replace workspace versions with actual npm versions', async ()=>{
|
|
161
|
+
const projectDir = path.join(testDir, 'workspace-test');
|
|
162
|
+
await fs.mkdir(projectDir, {
|
|
163
|
+
recursive: true
|
|
164
|
+
});
|
|
165
|
+
// Create a mock package.json with workspace versions
|
|
166
|
+
const mockPackageJson = {
|
|
167
|
+
name: 'template-name',
|
|
168
|
+
dependencies: {
|
|
169
|
+
'@payloadcms/db-mongodb': 'workspace:^',
|
|
170
|
+
'@payloadcms/richtext-lexical': 'workspace:*',
|
|
171
|
+
next: '^15.0.0',
|
|
172
|
+
payload: 'workspace:*'
|
|
173
|
+
},
|
|
174
|
+
devDependencies: {
|
|
175
|
+
'@payloadcms/graphql': 'workspace:*',
|
|
176
|
+
typescript: '^5.0.0'
|
|
177
|
+
},
|
|
178
|
+
version: '1.0.0'
|
|
179
|
+
};
|
|
180
|
+
await fs.writeFile(path.join(projectDir, 'package.json'), JSON.stringify(mockPackageJson, null, 2));
|
|
181
|
+
// Mock fetch to return a version
|
|
182
|
+
const mockFetch = vi.fn().mockResolvedValue({
|
|
183
|
+
json: ()=>Promise.resolve({
|
|
184
|
+
latest: '3.0.0'
|
|
185
|
+
}),
|
|
186
|
+
ok: true
|
|
187
|
+
});
|
|
188
|
+
global.fetch = mockFetch;
|
|
189
|
+
// Mock downloadTemplateFromGitHub to do nothing (already have package.json)
|
|
190
|
+
const downloadMock = vi.fn().mockResolvedValue(undefined);
|
|
191
|
+
vi.doMock('./download-template.js', ()=>({
|
|
192
|
+
downloadTemplateFromGitHub: downloadMock
|
|
193
|
+
}));
|
|
194
|
+
// Mock applyLambdaModifications to do nothing
|
|
195
|
+
const lambdaMock = vi.fn().mockResolvedValue(undefined);
|
|
196
|
+
vi.doMock('./lambda-config.js', ()=>({
|
|
197
|
+
applyLambdaModifications: lambdaMock
|
|
198
|
+
}));
|
|
199
|
+
// Re-import to get mocked version
|
|
200
|
+
vi.resetModules();
|
|
201
|
+
const { scaffoldProject } = await import('./project.js');
|
|
202
|
+
await scaffoldProject(projectDir, 'my-project');
|
|
203
|
+
// Read the updated package.json
|
|
204
|
+
const updatedPackageJson = JSON.parse(await fs.readFile(path.join(projectDir, 'package.json'), 'utf-8'));
|
|
205
|
+
// Verify name was updated
|
|
206
|
+
expect(updatedPackageJson.name).toBe('my-project');
|
|
207
|
+
// Verify workspace versions were replaced
|
|
208
|
+
expect(updatedPackageJson.dependencies.payload).toBe('3.0.0');
|
|
209
|
+
expect(updatedPackageJson.dependencies['@payloadcms/db-mongodb']).toBe('3.0.0');
|
|
210
|
+
expect(updatedPackageJson.dependencies['@payloadcms/richtext-lexical']).toBe('3.0.0');
|
|
211
|
+
// Verify non-payload packages unchanged
|
|
212
|
+
expect(updatedPackageJson.dependencies.next).toBe('^15.0.0');
|
|
213
|
+
// Verify devDependencies
|
|
214
|
+
expect(updatedPackageJson.devDependencies['@payloadcms/graphql']).toBe('3.0.0');
|
|
215
|
+
expect(updatedPackageJson.devDependencies.typescript).toBe('^5.0.0');
|
|
216
|
+
// Verify npm registry was called
|
|
217
|
+
expect(mockFetch).toHaveBeenCalledWith('https://registry.npmjs.org/-/package/payload/dist-tags');
|
|
218
|
+
});
|
|
219
|
+
});
|
|
220
|
+
});
|
|
221
|
+
|
|
222
|
+
//# sourceMappingURL=project.spec.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/utils/project.spec.ts"],"sourcesContent":["import fs from 'fs/promises'\nimport path from 'path'\nimport { afterEach, beforeEach, describe, expect, it, vi } from 'vitest'\n\nimport { detectPayloadProject, validatePayloadVersion } from './project.js'\n\ndescribe('project utilities', () => {\n let testDir: string\n\n beforeEach(async () => {\n // Create unique temp directory for each test\n testDir = path.join(\n process.cwd(),\n '.test-tmp',\n `project-${Date.now()}-${Math.random().toString(36).substring(2, 9)}`,\n )\n await fs.mkdir(testDir, { recursive: true })\n })\n\n afterEach(async () => {\n // Clean up test directory\n try {\n await fs.rm(testDir, { force: true, recursive: true })\n } catch {\n // Ignore cleanup errors\n }\n })\n\n describe('detectPayloadProject', () => {\n it('should detect project with payload in dependencies', async () => {\n const packageJson = {\n name: 'test-project',\n dependencies: {\n next: '^15.0.0',\n payload: '^3.54.0',\n },\n version: '1.0.0',\n }\n\n await fs.writeFile(\n path.join(testDir, 'package.json'),\n JSON.stringify(packageJson, null, 2),\n 'utf-8',\n )\n\n const result = await detectPayloadProject(testDir)\n\n expect(result.hasPayload).toBe(true)\n expect(result.payloadVersion).toBe('^3.54.0')\n expect(result.path).toBe(testDir)\n })\n\n it('should detect project with payload in devDependencies', async () => {\n const packageJson = {\n name: 'test-project',\n devDependencies: {\n payload: '3.50.0',\n },\n version: '1.0.0',\n }\n\n await fs.writeFile(\n path.join(testDir, 'package.json'),\n JSON.stringify(packageJson, null, 2),\n 'utf-8',\n )\n\n const result = await detectPayloadProject(testDir)\n\n expect(result.hasPayload).toBe(true)\n expect(result.payloadVersion).toBe('3.50.0')\n })\n\n it('should return false if no payload dependency', async () => {\n const packageJson = {\n name: 'test-project',\n dependencies: {\n next: '^15.0.0',\n react: '^19.0.0',\n },\n version: '1.0.0',\n }\n\n await fs.writeFile(\n path.join(testDir, 'package.json'),\n JSON.stringify(packageJson, null, 2),\n 'utf-8',\n )\n\n const result = await detectPayloadProject(testDir)\n\n expect(result.hasPayload).toBe(false)\n expect(result.payloadVersion).toBeUndefined()\n })\n\n it('should return false if no package.json exists', async () => {\n const result = await detectPayloadProject(testDir)\n\n expect(result.hasPayload).toBe(false)\n expect(result.payloadVersion).toBeUndefined()\n })\n\n it('should detect pnpm as package manager', async () => {\n const packageJson = {\n name: 'test-project',\n dependencies: { payload: '^3.0.0' },\n }\n\n await fs.writeFile(\n path.join(testDir, 'package.json'),\n JSON.stringify(packageJson, null, 2),\n 'utf-8',\n )\n await fs.writeFile(path.join(testDir, 'pnpm-lock.yaml'), '', 'utf-8')\n\n const result = await detectPayloadProject(testDir)\n\n expect(result.packageManager).toBe('pnpm')\n })\n\n it('should detect yarn as package manager', async () => {\n const packageJson = {\n name: 'test-project',\n dependencies: { payload: '^3.0.0' },\n }\n\n await fs.writeFile(\n path.join(testDir, 'package.json'),\n JSON.stringify(packageJson, null, 2),\n 'utf-8',\n )\n await fs.writeFile(path.join(testDir, 'yarn.lock'), '', 'utf-8')\n\n const result = await detectPayloadProject(testDir)\n\n expect(result.packageManager).toBe('yarn')\n })\n\n it('should default to npm as package manager', async () => {\n const packageJson = {\n name: 'test-project',\n dependencies: { payload: '^3.0.0' },\n }\n\n await fs.writeFile(\n path.join(testDir, 'package.json'),\n JSON.stringify(packageJson, null, 2),\n 'utf-8',\n )\n\n const result = await detectPayloadProject(testDir)\n\n expect(result.packageManager).toBe('npm')\n })\n\n it('should handle invalid package.json', async () => {\n await fs.writeFile(path.join(testDir, 'package.json'), 'invalid json{', 'utf-8')\n\n await expect(detectPayloadProject(testDir)).rejects.toThrow('Failed to read package.json')\n })\n })\n\n describe('validatePayloadVersion', () => {\n it('should accept version 3.x.x', () => {\n expect(validatePayloadVersion('3.54.0')).toBe(true)\n expect(validatePayloadVersion('3.0.0')).toBe(true)\n expect(validatePayloadVersion('3.100.999')).toBe(true)\n })\n\n it('should accept version with caret', () => {\n expect(validatePayloadVersion('^3.54.0')).toBe(true)\n expect(validatePayloadVersion('^3.0.0')).toBe(true)\n })\n\n it('should accept version with tilde', () => {\n expect(validatePayloadVersion('~3.54.0')).toBe(true)\n expect(validatePayloadVersion('~3.0.0')).toBe(true)\n })\n\n it('should reject version 2.x.x', () => {\n expect(validatePayloadVersion('2.54.0')).toBe(false)\n expect(validatePayloadVersion('^2.0.0')).toBe(false)\n })\n\n it('should reject version 4.x.x', () => {\n expect(validatePayloadVersion('4.0.0')).toBe(false)\n expect(validatePayloadVersion('^4.0.0')).toBe(false)\n })\n\n it('should reject invalid version strings', () => {\n expect(validatePayloadVersion('invalid')).toBe(false)\n expect(validatePayloadVersion('x.y.z')).toBe(false)\n expect(validatePayloadVersion('')).toBe(false)\n })\n\n it('should handle version ranges', () => {\n expect(validatePayloadVersion('>=3.0.0')).toBe(true)\n expect(validatePayloadVersion('>=3.0.0 <4.0.0')).toBe(true)\n })\n })\n\n describe('scaffoldProject', () => {\n it('should create project directory if it does not exist', async () => {\n const { scaffoldProject } = await import('./project.js')\n const newDir = path.join(testDir, 'new-project')\n\n // Note: This will fail in test because template files don't exist in dist during test\n // We're testing the directory creation part\n try {\n await scaffoldProject(newDir, 'test-project')\n } catch {\n // Expected to fail when trying to read templates\n // But directory should still be created\n }\n\n const exists = await fs\n .access(newDir)\n .then(() => true)\n .catch(() => false)\n expect(exists).toBe(true)\n })\n\n it('should replace workspace versions with actual npm versions', async () => {\n const projectDir = path.join(testDir, 'workspace-test')\n await fs.mkdir(projectDir, { recursive: true })\n\n // Create a mock package.json with workspace versions\n const mockPackageJson = {\n name: 'template-name',\n dependencies: {\n '@payloadcms/db-mongodb': 'workspace:^',\n '@payloadcms/richtext-lexical': 'workspace:*',\n next: '^15.0.0',\n payload: 'workspace:*',\n },\n devDependencies: {\n '@payloadcms/graphql': 'workspace:*',\n typescript: '^5.0.0',\n },\n version: '1.0.0',\n }\n\n await fs.writeFile(\n path.join(projectDir, 'package.json'),\n JSON.stringify(mockPackageJson, null, 2),\n )\n\n // Mock fetch to return a version\n const mockFetch = vi.fn().mockResolvedValue({\n json: () => Promise.resolve({ latest: '3.0.0' }),\n ok: true,\n })\n global.fetch = mockFetch as never\n\n // Mock downloadTemplateFromGitHub to do nothing (already have package.json)\n const downloadMock = vi.fn().mockResolvedValue(undefined)\n vi.doMock('./download-template.js', () => ({\n downloadTemplateFromGitHub: downloadMock,\n }))\n\n // Mock applyLambdaModifications to do nothing\n const lambdaMock = vi.fn().mockResolvedValue(undefined)\n vi.doMock('./lambda-config.js', () => ({\n applyLambdaModifications: lambdaMock,\n }))\n\n // Re-import to get mocked version\n vi.resetModules()\n const { scaffoldProject } = await import('./project.js')\n\n await scaffoldProject(projectDir, 'my-project')\n\n // Read the updated package.json\n const updatedPackageJson = JSON.parse(\n await fs.readFile(path.join(projectDir, 'package.json'), 'utf-8'),\n )\n\n // Verify name was updated\n expect(updatedPackageJson.name).toBe('my-project')\n\n // Verify workspace versions were replaced\n expect(updatedPackageJson.dependencies.payload).toBe('3.0.0')\n expect(updatedPackageJson.dependencies['@payloadcms/db-mongodb']).toBe('3.0.0')\n expect(updatedPackageJson.dependencies['@payloadcms/richtext-lexical']).toBe('3.0.0')\n\n // Verify non-payload packages unchanged\n expect(updatedPackageJson.dependencies.next).toBe('^15.0.0')\n\n // Verify devDependencies\n expect(updatedPackageJson.devDependencies['@payloadcms/graphql']).toBe('3.0.0')\n expect(updatedPackageJson.devDependencies.typescript).toBe('^5.0.0')\n\n // Verify npm registry was called\n expect(mockFetch).toHaveBeenCalledWith(\n 'https://registry.npmjs.org/-/package/payload/dist-tags',\n )\n })\n })\n})\n"],"names":["fs","path","afterEach","beforeEach","describe","expect","it","vi","detectPayloadProject","validatePayloadVersion","testDir","join","process","cwd","Date","now","Math","random","toString","substring","mkdir","recursive","rm","force","packageJson","name","dependencies","next","payload","version","writeFile","JSON","stringify","result","hasPayload","toBe","payloadVersion","devDependencies","react","toBeUndefined","packageManager","rejects","toThrow","scaffoldProject","newDir","exists","access","then","catch","projectDir","mockPackageJson","typescript","mockFetch","fn","mockResolvedValue","json","Promise","resolve","latest","ok","global","fetch","downloadMock","undefined","doMock","downloadTemplateFromGitHub","lambdaMock","applyLambdaModifications","resetModules","updatedPackageJson","parse","readFile","toHaveBeenCalledWith"],"mappings":"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"}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Results from uploading assets
|
|
3
|
+
*/
|
|
4
|
+
export interface UploadResults {
|
|
5
|
+
/** Number of static assets that failed to upload */
|
|
6
|
+
assetsFailed: number;
|
|
7
|
+
/** Number of static assets successfully uploaded */
|
|
8
|
+
assetsUploaded: number;
|
|
9
|
+
/** Whether Lambda code was uploaded */
|
|
10
|
+
lambdaUploaded: boolean;
|
|
11
|
+
/** Total bytes uploaded */
|
|
12
|
+
totalBytesUploaded: number;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* Upload a file to S3 using a signed URL
|
|
16
|
+
*
|
|
17
|
+
* Retries up to 3 times with exponential backoff
|
|
18
|
+
*
|
|
19
|
+
* @param filePath - Absolute path to file to upload
|
|
20
|
+
* @param signedUrl - Signed S3 upload URL
|
|
21
|
+
* @param contentType - MIME type (optional)
|
|
22
|
+
* @throws Error if upload fails after retries
|
|
23
|
+
*/
|
|
24
|
+
export declare function uploadFile(filePath: string, signedUrl: string, contentType?: string): Promise<void>;
|
|
25
|
+
/**
|
|
26
|
+
* Upload Lambda code zip to S3
|
|
27
|
+
*
|
|
28
|
+
* @param zipPath - Path to lambda.zip
|
|
29
|
+
* @param signedUrl - Signed S3 upload URL
|
|
30
|
+
*/
|
|
31
|
+
export declare function uploadLambdaZip(zipPath: string, signedUrl: string): Promise<void>;
|
|
32
|
+
/**
|
|
33
|
+
* Upload static assets to S3 in parallel
|
|
34
|
+
*
|
|
35
|
+
* Uploads up to 5 files concurrently
|
|
36
|
+
*
|
|
37
|
+
* @param projectPath - Path to project root
|
|
38
|
+
* @param assetUrls - Map of asset paths to signed URLs
|
|
39
|
+
* @param onProgress - Optional callback for progress updates (uploaded, total)
|
|
40
|
+
* @returns Upload results with counts
|
|
41
|
+
*/
|
|
42
|
+
export declare function uploadStaticAssets(projectPath: string, assetUrls: Record<string, string>, onProgress?: (uploaded: number, total: number) => void): Promise<UploadResults>;
|
|
43
|
+
//# sourceMappingURL=s3-upload.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"s3-upload.d.ts","sourceRoot":"","sources":["../../src/utils/s3-upload.ts"],"names":[],"mappings":"AAKA;;GAEG;AACH,MAAM,WAAW,aAAa;IAC5B,oDAAoD;IACpD,YAAY,EAAE,MAAM,CAAA;IACpB,oDAAoD;IACpD,cAAc,EAAE,MAAM,CAAA;IACtB,uCAAuC;IACvC,cAAc,EAAE,OAAO,CAAA;IACvB,2BAA2B;IAC3B,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAsBD;;;;;;;;;GASG;AACH,wBAAsB,UAAU,CAC9B,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,MAAM,EACjB,WAAW,CAAC,EAAE,MAAM,GACnB,OAAO,CAAC,IAAI,CAAC,CA+Cf;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,OAAO,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAEvF;AAED;;;;;;;;;GASG;AACH,wBAAsB,kBAAkB,CACtC,WAAW,EAAE,MAAM,EACnB,SAAS,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,EACjC,UAAU,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,KAAK,IAAI,GACrD,OAAO,CAAC,aAAa,CAAC,CAiDxB"}
|