@payloadcms/figma 0.1.0-alpha.3 → 0.1.0-alpha.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/api/check-project-subdomain-availability.d.ts +12 -0
- package/dist/api/check-project-subdomain-availability.js +32 -0
- package/dist/api/control-plane-error.d.ts +6 -0
- package/dist/api/control-plane-error.js +8 -0
- package/dist/api/control-plane-fetch.d.ts +7 -0
- package/dist/api/control-plane-fetch.js +37 -0
- package/dist/api/control-plane.d.ts +0 -8
- package/dist/api/control-plane.js +1 -47
- package/dist/api/create-project.d.ts +18 -0
- package/dist/api/create-project.js +37 -0
- package/dist/api/list-project-workspaces.d.ts +8 -0
- package/dist/api/list-project-workspaces.js +28 -0
- package/dist/api/project-resource-type.d.ts +1 -0
- package/dist/api/project-resource-type.js +1 -0
- package/dist/auth/headless-oauth-flow.d.ts +23 -0
- package/dist/auth/headless-oauth-flow.js +69 -0
- package/dist/auth/oauth-flow.d.ts +2 -0
- package/dist/auth/oauth-flow.js +13 -8
- package/dist/auth/token-store.d.ts +4 -1
- package/dist/auth/token-store.js +14 -0
- package/dist/auth/types.d.ts +12 -0
- package/dist/cli.d.ts +10 -1
- package/dist/cli.js +39 -4
- package/dist/commands/bootstrap.js +2 -1
- package/dist/commands/deploy.d.ts +10 -0
- package/dist/commands/deploy.js +39 -11
- package/dist/commands/detect-project-resource-type.d.ts +3 -0
- package/dist/commands/detect-project-resource-type.js +28 -0
- package/dist/commands/init.d.ts +2 -2
- package/dist/commands/init.js +163 -78
- package/dist/commands/login.d.ts +11 -1
- package/dist/commands/login.js +66 -4
- package/dist/commands/prompt-to-create-project/format-project-subdomain.d.ts +1 -0
- package/dist/commands/prompt-to-create-project/format-project-subdomain.js +3 -0
- package/dist/commands/prompt-to-create-project/format-unavailable-subdomain-reason.d.ts +1 -0
- package/dist/commands/prompt-to-create-project/format-unavailable-subdomain-reason.js +7 -0
- package/dist/commands/prompt-to-create-project/get-default-project-name.d.ts +1 -0
- package/dist/commands/prompt-to-create-project/get-default-project-name.js +13 -0
- package/dist/commands/prompt-to-create-project/prompt-for-available-subdomain.d.ts +7 -0
- package/dist/commands/prompt-to-create-project/prompt-for-available-subdomain.js +32 -0
- package/dist/commands/prompt-to-create-project/resolve-project-region.d.ts +8 -0
- package/dist/commands/prompt-to-create-project/resolve-project-region.js +27 -0
- package/dist/commands/prompt-to-create-project/resolve-project-subdomain.d.ts +9 -0
- package/dist/commands/prompt-to-create-project/resolve-project-subdomain.js +54 -0
- package/dist/commands/prompt-to-create-project/resolve-text-input.d.ts +9 -0
- package/dist/commands/prompt-to-create-project/resolve-text-input.js +23 -0
- package/dist/commands/prompt-to-create-project/resolve-workspace-plan-key.d.ts +12 -0
- package/dist/commands/prompt-to-create-project/resolve-workspace-plan-key.js +36 -0
- package/dist/commands/prompt-to-create-project/validate-subdomain.d.ts +1 -0
- package/dist/commands/prompt-to-create-project/validate-subdomain.js +9 -0
- package/dist/commands/prompt-to-create-project.d.ts +24 -0
- package/dist/commands/prompt-to-create-project.js +69 -0
- package/dist/commands/setup-agent.d.ts +12 -0
- package/dist/commands/setup-agent.js +123 -0
- package/dist/commands/write-project-configuration.d.ts +12 -0
- package/dist/commands/write-project-configuration.js +16 -0
- package/dist/db-content-api/index.js +21 -16
- package/dist/db-content-api/utilities/data/injectGlobalType.d.ts +6 -0
- package/dist/db-content-api/utilities/data/injectGlobalType.js +11 -0
- package/dist/db-content-api/utilities/data/stringifyNumericIds.d.ts +1 -0
- package/dist/db-content-api/utilities/data/stringifyNumericIds.js +19 -0
- package/dist/db-content-api/utilities/isRecord.d.ts +9 -0
- package/dist/db-content-api/utilities/isRecord.js +19 -0
- package/dist/db-content-api/utilities/where.js +6 -4
- package/dist/lib/write-agent-config.d.ts +12 -0
- package/dist/lib/write-agent-config.js +52 -0
- package/dist/skills/deploy-to-figma/SKILL.md +234 -0
- package/dist/skills/deploy-to-figma/references/cli-reference.md +146 -0
- package/dist/types.d.ts +9 -0
- package/dist/utils/lambda-config.js +4 -14
- package/dist/utils/messages.js +22 -3
- package/dist/utils/payload-generate.d.ts +10 -0
- package/dist/utils/payload-generate.js +59 -0
- package/dist/utils/pnpm-builds.d.ts +14 -0
- package/dist/utils/pnpm-builds.js +125 -0
- package/package.json +2 -1
- package/dist/lib/download-skill.d.ts +0 -12
- package/dist/lib/download-skill.js +0 -77
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
import spawn from 'cross-spawn';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
// buildFigmaConfig throws without a resolvable environmentId/contentSystemId,
|
|
4
|
+
// which an unauthenticated init lacks. It reads these env vars before the
|
|
5
|
+
// bootstrap cache, so injecting them avoids the throw. Always inject the
|
|
6
|
+
// placeholder (not the real env) for deterministic behavior; the generated
|
|
7
|
+
// artifacts are ID-independent, so the value never affects output.
|
|
8
|
+
const GENERATE_PLACEHOLDER = 'figma-generate-placeholder';
|
|
9
|
+
/** Runs `payload <subcommand>` via the project's local binary. Never throws. */ function runPayloadGenerate(projectPath, subcommand) {
|
|
10
|
+
const bin = path.join(projectPath, 'node_modules', '.bin', 'payload');
|
|
11
|
+
return new Promise((resolve)=>{
|
|
12
|
+
const child = spawn(bin, [
|
|
13
|
+
subcommand
|
|
14
|
+
], {
|
|
15
|
+
cwd: projectPath,
|
|
16
|
+
env: {
|
|
17
|
+
...process.env,
|
|
18
|
+
FIGMA_CONTENT_API_CONTENT_SYSTEM_ID: GENERATE_PLACEHOLDER,
|
|
19
|
+
FIGMA_EID: GENERATE_PLACEHOLDER
|
|
20
|
+
},
|
|
21
|
+
stdio: 'pipe'
|
|
22
|
+
});
|
|
23
|
+
// Drain both pipes. An unread stdout buffer fills and blocks the child,
|
|
24
|
+
// hanging init; stdout also carries diagnostics on some failures.
|
|
25
|
+
let stderr = '';
|
|
26
|
+
let stdout = '';
|
|
27
|
+
child.stderr?.on('data', (data)=>{
|
|
28
|
+
stderr += data.toString();
|
|
29
|
+
});
|
|
30
|
+
child.stdout?.on('data', (data)=>{
|
|
31
|
+
stdout += data.toString();
|
|
32
|
+
});
|
|
33
|
+
child.on('close', (code)=>{
|
|
34
|
+
if (code === 0) {
|
|
35
|
+
resolve({
|
|
36
|
+
ok: true
|
|
37
|
+
});
|
|
38
|
+
} else {
|
|
39
|
+
const output = stderr.trim() || stdout.trim();
|
|
40
|
+
resolve({
|
|
41
|
+
error: output || `payload ${subcommand} exited with code ${code}`,
|
|
42
|
+
ok: false
|
|
43
|
+
});
|
|
44
|
+
}
|
|
45
|
+
});
|
|
46
|
+
child.on('error', (error)=>{
|
|
47
|
+
resolve({
|
|
48
|
+
error: error.message,
|
|
49
|
+
ok: false
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
});
|
|
53
|
+
}
|
|
54
|
+
/** Never throws. */ export function generateImportMap(projectPath) {
|
|
55
|
+
return runPayloadGenerate(projectPath, 'generate:importmap');
|
|
56
|
+
}
|
|
57
|
+
/** Never throws. */ export function generateTypes(projectPath) {
|
|
58
|
+
return runPayloadGenerate(projectPath, 'generate:types');
|
|
59
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Write init's pnpm-workspace.yaml: hoisted node linker (the Lambda runtime needs a
|
|
3
|
+
* flat node_modules) plus build approvals, migrating off the now-ignored package.json
|
|
4
|
+
* `pnpm.onlyBuiltDependencies`. Written for every project so an npx/npm scaffold still
|
|
5
|
+
* installs cleanly when the user later switches to pnpm.
|
|
6
|
+
*/
|
|
7
|
+
export declare function ensurePnpmWorkspace(projectPath: string): Promise<void>;
|
|
8
|
+
/**
|
|
9
|
+
* Set each build `true` under `allowBuilds` and drop it from any `ignoredBuiltDependencies`
|
|
10
|
+
* denylist. Pure and idempotent. pnpm v11 reads approvals only from pnpm-workspace.yaml.
|
|
11
|
+
*/
|
|
12
|
+
export declare function upsertBuildApprovals(content: string, builds: string[]): string;
|
|
13
|
+
/** Set a top-level `key: value` scalar, replacing any existing one. Pure and idempotent. */
|
|
14
|
+
export declare function upsertTopLevelScalar(content: string, key: string, value: string): string;
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
import fs from 'fs/promises';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
/** Fallback builds when package.json declares none. */ const DEFAULT_BUILDS = [
|
|
4
|
+
'sharp',
|
|
5
|
+
'esbuild',
|
|
6
|
+
'unrs-resolver'
|
|
7
|
+
];
|
|
8
|
+
/**
|
|
9
|
+
* Write init's pnpm-workspace.yaml: hoisted node linker (the Lambda runtime needs a
|
|
10
|
+
* flat node_modules) plus build approvals, migrating off the now-ignored package.json
|
|
11
|
+
* `pnpm.onlyBuiltDependencies`. Written for every project so an npx/npm scaffold still
|
|
12
|
+
* installs cleanly when the user later switches to pnpm.
|
|
13
|
+
*/ export async function ensurePnpmWorkspace(projectPath) {
|
|
14
|
+
const packageJsonPath = path.join(projectPath, 'package.json');
|
|
15
|
+
const packageJson = JSON.parse(await fs.readFile(packageJsonPath, 'utf-8'));
|
|
16
|
+
const pnpmField = packageJson.pnpm;
|
|
17
|
+
const configured = pnpmField?.onlyBuiltDependencies;
|
|
18
|
+
const builds = configured && configured.length > 0 ? configured : DEFAULT_BUILDS;
|
|
19
|
+
const workspacePath = path.join(projectPath, 'pnpm-workspace.yaml');
|
|
20
|
+
let yaml = '';
|
|
21
|
+
try {
|
|
22
|
+
yaml = await fs.readFile(workspacePath, 'utf-8');
|
|
23
|
+
} catch (error) {
|
|
24
|
+
// Rethrow on a present-but-unreadable file; the write below would clobber it.
|
|
25
|
+
if (error.code !== 'ENOENT') {
|
|
26
|
+
throw error;
|
|
27
|
+
}
|
|
28
|
+
}
|
|
29
|
+
yaml = upsertTopLevelScalar(yaml, 'nodeLinker', 'hoisted');
|
|
30
|
+
yaml = upsertBuildApprovals(yaml, builds);
|
|
31
|
+
await fs.writeFile(workspacePath, yaml, 'utf-8');
|
|
32
|
+
if (pnpmField) {
|
|
33
|
+
delete pnpmField.onlyBuiltDependencies;
|
|
34
|
+
if (Object.keys(pnpmField).length === 0) {
|
|
35
|
+
delete packageJson.pnpm;
|
|
36
|
+
}
|
|
37
|
+
await fs.writeFile(packageJsonPath, JSON.stringify(packageJson, null, 2) + '\n', 'utf-8');
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Set each build `true` under `allowBuilds` and drop it from any `ignoredBuiltDependencies`
|
|
42
|
+
* denylist. Pure and idempotent. pnpm v11 reads approvals only from pnpm-workspace.yaml.
|
|
43
|
+
*/ export function upsertBuildApprovals(content, builds) {
|
|
44
|
+
const blocks = toTopLevelBlocks(content);
|
|
45
|
+
const ignored = blocks.find((block)=>block.key === 'ignoredBuiltDependencies');
|
|
46
|
+
if (ignored) {
|
|
47
|
+
ignored.lines = ignored.lines.filter((line, index)=>{
|
|
48
|
+
if (index === 0) {
|
|
49
|
+
return true;
|
|
50
|
+
}
|
|
51
|
+
const name = /^\s*-\s*'?([^'\s]+)'?\s*$/.exec(line)?.[1];
|
|
52
|
+
return !(name && builds.includes(name));
|
|
53
|
+
});
|
|
54
|
+
}
|
|
55
|
+
const allow = blocks.find((block)=>block.key === 'allowBuilds');
|
|
56
|
+
if (allow) {
|
|
57
|
+
for (const name of builds){
|
|
58
|
+
const pattern = new RegExp(`^\\s+'?${escapeRegExp(name)}'?:`);
|
|
59
|
+
const index = allow.lines.findIndex((line)=>pattern.test(line));
|
|
60
|
+
if (index >= 0) {
|
|
61
|
+
allow.lines[index] = ` ${name}: true`;
|
|
62
|
+
} else {
|
|
63
|
+
allow.lines.push(` ${name}: true`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
} else {
|
|
67
|
+
blocks.push({
|
|
68
|
+
key: 'allowBuilds',
|
|
69
|
+
lines: [
|
|
70
|
+
'allowBuilds:',
|
|
71
|
+
...builds.map((name)=>` ${name}: true`)
|
|
72
|
+
]
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
const output = blocks.flatMap((block)=>block.lines).join('\n');
|
|
76
|
+
return output.endsWith('\n') ? output : `${output}\n`;
|
|
77
|
+
}
|
|
78
|
+
/** Set a top-level `key: value` scalar, replacing any existing one. Pure and idempotent. */ export function upsertTopLevelScalar(content, key, value) {
|
|
79
|
+
const blocks = toTopLevelBlocks(content);
|
|
80
|
+
const line = `${key}: ${value}`;
|
|
81
|
+
const existing = blocks.find((block)=>block.key === key);
|
|
82
|
+
if (existing) {
|
|
83
|
+
existing.lines = [
|
|
84
|
+
line
|
|
85
|
+
];
|
|
86
|
+
} else {
|
|
87
|
+
blocks.push({
|
|
88
|
+
key,
|
|
89
|
+
lines: [
|
|
90
|
+
line
|
|
91
|
+
]
|
|
92
|
+
});
|
|
93
|
+
}
|
|
94
|
+
const output = blocks.flatMap((block)=>block.lines).join('\n');
|
|
95
|
+
return output.endsWith('\n') ? output : `${output}\n`;
|
|
96
|
+
}
|
|
97
|
+
function toTopLevelBlocks(content) {
|
|
98
|
+
const lines = content.length ? content.replace(/\n$/, '').split('\n') : [];
|
|
99
|
+
const blocks = [];
|
|
100
|
+
for (const line of lines){
|
|
101
|
+
const key = /^[^\s#]/.test(line) ? /^([^:]+):/.exec(line)?.[1] : undefined;
|
|
102
|
+
const current = blocks[blocks.length - 1];
|
|
103
|
+
if (key !== undefined) {
|
|
104
|
+
blocks.push({
|
|
105
|
+
key,
|
|
106
|
+
lines: [
|
|
107
|
+
line
|
|
108
|
+
]
|
|
109
|
+
});
|
|
110
|
+
} else if (current) {
|
|
111
|
+
current.lines.push(line);
|
|
112
|
+
} else {
|
|
113
|
+
blocks.push({
|
|
114
|
+
key: null,
|
|
115
|
+
lines: [
|
|
116
|
+
line
|
|
117
|
+
]
|
|
118
|
+
});
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
return blocks;
|
|
122
|
+
}
|
|
123
|
+
function escapeRegExp(value) {
|
|
124
|
+
return value.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
125
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@payloadcms/figma",
|
|
3
|
-
"version": "0.1.0-alpha.
|
|
3
|
+
"version": "0.1.0-alpha.4",
|
|
4
4
|
"license": "SEE LICENSE IN LICENSE.md",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"exports": {
|
|
@@ -41,6 +41,7 @@
|
|
|
41
41
|
"open": "^10.2.0",
|
|
42
42
|
"openapi-fetch": "0.15.0",
|
|
43
43
|
"picocolors": "1.1.1",
|
|
44
|
+
"skills": "1.4.4",
|
|
44
45
|
"tar": "^7.5.13",
|
|
45
46
|
"terminal-link": "^5.0.0",
|
|
46
47
|
"ts-morph": "^21.0.1",
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
export type DownloadSkillResult = {
|
|
2
|
-
detail?: string;
|
|
3
|
-
ok: false;
|
|
4
|
-
reason: 'already-installed' | 'empty-extract' | 'error' | 'fetch-failed';
|
|
5
|
-
} | {
|
|
6
|
-
ok: true;
|
|
7
|
-
};
|
|
8
|
-
export declare function downloadSkill(args: {
|
|
9
|
-
branch?: string;
|
|
10
|
-
debug?: boolean;
|
|
11
|
-
projectDir: string;
|
|
12
|
-
}): Promise<DownloadSkillResult>;
|
|
@@ -1,77 +0,0 @@
|
|
|
1
|
-
import fs from 'fs/promises';
|
|
2
|
-
import { Readable } from 'node:stream';
|
|
3
|
-
import { pipeline } from 'node:stream/promises';
|
|
4
|
-
import path from 'path';
|
|
5
|
-
import { x } from 'tar';
|
|
6
|
-
export async function downloadSkill(args) {
|
|
7
|
-
const { branch = 'main', debug, projectDir } = args;
|
|
8
|
-
const destDir = path.join(projectDir, '.claude', 'skills', 'payload');
|
|
9
|
-
if (await pathExists(path.join(destDir, 'SKILL.md'))) {
|
|
10
|
-
return {
|
|
11
|
-
ok: false,
|
|
12
|
-
reason: 'already-installed'
|
|
13
|
-
};
|
|
14
|
-
}
|
|
15
|
-
const url = `https://codeload.github.com/payloadcms/payload/tar.gz/${branch}`;
|
|
16
|
-
const filter = `payload-${branch.replace(/^v/, '').replaceAll('/', '-')}/tools/claude-plugin/skills/payload/`;
|
|
17
|
-
if (debug) {
|
|
18
|
-
// eslint-disable-next-line no-console
|
|
19
|
-
console.log(`[download-skill] url=${url} dest=${destDir}`);
|
|
20
|
-
}
|
|
21
|
-
try {
|
|
22
|
-
const res = await fetch(url);
|
|
23
|
-
if (!res.ok) {
|
|
24
|
-
return {
|
|
25
|
-
detail: `${res.status} ${res.statusText}`,
|
|
26
|
-
ok: false,
|
|
27
|
-
reason: 'fetch-failed'
|
|
28
|
-
};
|
|
29
|
-
}
|
|
30
|
-
if (!res.body) {
|
|
31
|
-
return {
|
|
32
|
-
detail: 'empty response body',
|
|
33
|
-
ok: false,
|
|
34
|
-
reason: 'fetch-failed'
|
|
35
|
-
};
|
|
36
|
-
}
|
|
37
|
-
await fs.mkdir(destDir, {
|
|
38
|
-
recursive: true
|
|
39
|
-
});
|
|
40
|
-
await pipeline(Readable.from(res.body), x({
|
|
41
|
-
cwd: destDir,
|
|
42
|
-
filter: (p)=>p.includes(filter),
|
|
43
|
-
strip: filter.split('/').length - 1
|
|
44
|
-
}));
|
|
45
|
-
if (!await pathExists(path.join(destDir, 'SKILL.md'))) {
|
|
46
|
-
await fs.rm(destDir, {
|
|
47
|
-
force: true,
|
|
48
|
-
recursive: true
|
|
49
|
-
});
|
|
50
|
-
return {
|
|
51
|
-
ok: false,
|
|
52
|
-
reason: 'empty-extract'
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
return {
|
|
56
|
-
ok: true
|
|
57
|
-
};
|
|
58
|
-
} catch (err) {
|
|
59
|
-
await fs.rm(destDir, {
|
|
60
|
-
force: true,
|
|
61
|
-
recursive: true
|
|
62
|
-
}).catch(()=>{});
|
|
63
|
-
return {
|
|
64
|
-
detail: err instanceof Error ? err.message : String(err),
|
|
65
|
-
ok: false,
|
|
66
|
-
reason: 'error'
|
|
67
|
-
};
|
|
68
|
-
}
|
|
69
|
-
}
|
|
70
|
-
async function pathExists(p) {
|
|
71
|
-
try {
|
|
72
|
-
await fs.access(p);
|
|
73
|
-
return true;
|
|
74
|
-
} catch {
|
|
75
|
-
return false;
|
|
76
|
-
}
|
|
77
|
-
}
|