@airdraft/cli 0.1.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/CHANGELOG.md +5 -0
- package/dist/bin.d.ts +3 -0
- package/dist/bin.d.ts.map +1 -0
- package/dist/bin.js +225 -0
- package/dist/bin.js.map +1 -0
- package/dist/commands.d.ts +136 -0
- package/dist/commands.d.ts.map +1 -0
- package/dist/commands.js +614 -0
- package/dist/commands.js.map +1 -0
- package/dist/github.d.ts +75 -0
- package/dist/github.d.ts.map +1 -0
- package/dist/github.js +234 -0
- package/dist/github.js.map +1 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/package.json +54 -0
package/dist/commands.js
ADDED
|
@@ -0,0 +1,614 @@
|
|
|
1
|
+
import { readFile, writeFile, access } from 'node:fs/promises';
|
|
2
|
+
import { join, resolve } from 'node:path';
|
|
3
|
+
import { randomBytes } from 'node:crypto';
|
|
4
|
+
import { createInterface } from 'node:readline';
|
|
5
|
+
import { checkFormatCompatibility } from '@airdraft/core';
|
|
6
|
+
// ---------------------------------------------------------------------------
|
|
7
|
+
// File templates — per mode
|
|
8
|
+
// ---------------------------------------------------------------------------
|
|
9
|
+
const ROUTE_HANDLER_TEMPLATE = `import { createCmsHandler } from '@airdraft/next'
|
|
10
|
+
import airdraft from '../../../airdraft.config'
|
|
11
|
+
|
|
12
|
+
export const { GET, POST, PUT, DELETE } = createCmsHandler(airdraft)
|
|
13
|
+
`;
|
|
14
|
+
/** Mode 3 — own GitHub App: all five GITCMS_ vars */
|
|
15
|
+
function mode3ConfigTemplate(vars) {
|
|
16
|
+
return `import { defineConfig } from '@airdraft/core'
|
|
17
|
+
import { GitHubAdapter } from '@airdraft/core'
|
|
18
|
+
|
|
19
|
+
const adapter = new GitHubAdapter({
|
|
20
|
+
appId: process.env.GITCMS_APP_ID!,
|
|
21
|
+
privateKey: process.env.GITCMS_PRIVATE_KEY!,
|
|
22
|
+
installationId: process.env.GITCMS_INSTALLATION_ID!,
|
|
23
|
+
repo: process.env.GITCMS_REPO!,
|
|
24
|
+
branch: process.env.GITCMS_BRANCH ?? 'main',
|
|
25
|
+
})
|
|
26
|
+
|
|
27
|
+
export default defineConfig({
|
|
28
|
+
adapter,
|
|
29
|
+
collections: {
|
|
30
|
+
posts: {
|
|
31
|
+
path: 'content/posts/{slug}.mdx',
|
|
32
|
+
format: 'mdx',
|
|
33
|
+
publish: true,
|
|
34
|
+
slugSource: 'title',
|
|
35
|
+
fields: {
|
|
36
|
+
title: { type: 'text', required: true },
|
|
37
|
+
excerpt: { type: 'text' },
|
|
38
|
+
body: { type: 'rich-text' },
|
|
39
|
+
},
|
|
40
|
+
},
|
|
41
|
+
},
|
|
42
|
+
})
|
|
43
|
+
`;
|
|
44
|
+
}
|
|
45
|
+
function mode3EnvTemplate(vars) {
|
|
46
|
+
// Wrap PEM in double-quotes and escape embedded newlines for .env files
|
|
47
|
+
const pemEscaped = vars.privateKey.trim().replace(/\n/g, '\\n');
|
|
48
|
+
return `# Airdraft — GitHub App credentials (Mode 3: own App)
|
|
49
|
+
GITCMS_APP_ID=${vars.appId}
|
|
50
|
+
GITCMS_PRIVATE_KEY="${pemEscaped}"
|
|
51
|
+
GITCMS_INSTALLATION_ID=${vars.installationId}
|
|
52
|
+
GITCMS_REPO=${vars.repo}
|
|
53
|
+
GITCMS_BRANCH=${vars.branch}
|
|
54
|
+
AIRDRAFT_REVALIDATE_SECRET=${randomBytes(32).toString('hex')}
|
|
55
|
+
`;
|
|
56
|
+
}
|
|
57
|
+
/** Mode 2 — Airdraft's GitHub App: project key + repo info only */
|
|
58
|
+
function mode2ConfigTemplate(vars) {
|
|
59
|
+
return `import { defineConfig } from '@airdraft/core'
|
|
60
|
+
import { GitHubAdapter } from '@airdraft/core'
|
|
61
|
+
import { createAirdraftTokenProvider } from '@airdraft/next'
|
|
62
|
+
|
|
63
|
+
const adapter = new GitHubAdapter({
|
|
64
|
+
tokenProvider: createAirdraftTokenProvider({
|
|
65
|
+
projectKey: process.env.AIRDRAFT_PROJECT_KEY!,
|
|
66
|
+
}),
|
|
67
|
+
repo: process.env.GITCMS_REPO!,
|
|
68
|
+
branch: process.env.GITCMS_BRANCH ?? 'main',
|
|
69
|
+
})
|
|
70
|
+
|
|
71
|
+
export default defineConfig({
|
|
72
|
+
adapter,
|
|
73
|
+
collections: {
|
|
74
|
+
posts: {
|
|
75
|
+
path: 'content/posts/{slug}.mdx',
|
|
76
|
+
format: 'mdx',
|
|
77
|
+
publish: true,
|
|
78
|
+
slugSource: 'title',
|
|
79
|
+
fields: {
|
|
80
|
+
title: { type: 'text', required: true },
|
|
81
|
+
excerpt: { type: 'text' },
|
|
82
|
+
body: { type: 'rich-text' },
|
|
83
|
+
},
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
})
|
|
87
|
+
`;
|
|
88
|
+
}
|
|
89
|
+
function mode2EnvTemplate(vars) {
|
|
90
|
+
return `# Airdraft — Mode 2 (using Airdraft's GitHub App)
|
|
91
|
+
AIRDRAFT_PROJECT_KEY=${vars.projectKey}
|
|
92
|
+
GITCMS_REPO=${vars.repo}
|
|
93
|
+
GITCMS_BRANCH=${vars.branch}
|
|
94
|
+
AIRDRAFT_REVALIDATE_SECRET=${randomBytes(32).toString('hex')}
|
|
95
|
+
`;
|
|
96
|
+
}
|
|
97
|
+
// ---------------------------------------------------------------------------
|
|
98
|
+
// Interactive prompt helpers (commands.ts internal — bin.ts has its own)
|
|
99
|
+
// ---------------------------------------------------------------------------
|
|
100
|
+
function cliPrompt(question) {
|
|
101
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
102
|
+
return new Promise((resolve) => {
|
|
103
|
+
rl.question(question, (answer) => {
|
|
104
|
+
rl.close();
|
|
105
|
+
resolve(answer.trim());
|
|
106
|
+
});
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
async function cliSelect(question, choices) {
|
|
110
|
+
const labels = choices.map((c, i) => ` ${i + 1}) ${c.label}`);
|
|
111
|
+
process.stdout.write(`\n${question}\n${labels.join('\n')}\n\n`);
|
|
112
|
+
while (true) {
|
|
113
|
+
const raw = await cliPrompt(' Enter number: ');
|
|
114
|
+
const n = parseInt(raw, 10);
|
|
115
|
+
if (n >= 1 && n <= choices.length)
|
|
116
|
+
return choices[n - 1].value;
|
|
117
|
+
process.stdout.write(` Please enter a number between 1 and ${choices.length}.\n`);
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
// ---------------------------------------------------------------------------
|
|
121
|
+
// File write helper
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
async function writeProjectFile(filePath, content, force, log) {
|
|
124
|
+
if (!force) {
|
|
125
|
+
const exists = await access(filePath).then(() => true).catch(() => false);
|
|
126
|
+
if (exists) {
|
|
127
|
+
log(` skip ${filePath} (already exists; use --force to overwrite)`);
|
|
128
|
+
return;
|
|
129
|
+
}
|
|
130
|
+
}
|
|
131
|
+
const { mkdir } = await import('node:fs/promises');
|
|
132
|
+
await mkdir(resolve(filePath, '..'), { recursive: true });
|
|
133
|
+
await writeFile(filePath, content, 'utf8');
|
|
134
|
+
log(` write ${filePath}`);
|
|
135
|
+
}
|
|
136
|
+
// ---------------------------------------------------------------------------
|
|
137
|
+
// initProject — entry point
|
|
138
|
+
// ---------------------------------------------------------------------------
|
|
139
|
+
export async function initProject(opts = {}) {
|
|
140
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
141
|
+
const log = opts.log ?? console.log;
|
|
142
|
+
const force = opts.force ?? false;
|
|
143
|
+
const credentials = opts.credentials ?? {};
|
|
144
|
+
// Mode selection
|
|
145
|
+
let mode = opts.mode;
|
|
146
|
+
if (!mode) {
|
|
147
|
+
mode = await cliSelect('How do you want to connect your GitHub repository?', [
|
|
148
|
+
{
|
|
149
|
+
label: 'Use Airdraft\'s GitHub App (Mode 2 — recommended, Airdraft Cloud account required)',
|
|
150
|
+
value: 'cloud-app',
|
|
151
|
+
},
|
|
152
|
+
{
|
|
153
|
+
label: 'Register your own GitHub App (Mode 3 — automatic via browser, no cloud account needed)',
|
|
154
|
+
value: 'own-app-auto',
|
|
155
|
+
},
|
|
156
|
+
{
|
|
157
|
+
label: 'Enter GitHub App credentials manually (Mode 3 — for CI/headless environments)',
|
|
158
|
+
value: 'own-app-manual',
|
|
159
|
+
},
|
|
160
|
+
]);
|
|
161
|
+
}
|
|
162
|
+
log('');
|
|
163
|
+
switch (mode) {
|
|
164
|
+
case 'cloud-app':
|
|
165
|
+
return initMode2(cwd, force, credentials, log);
|
|
166
|
+
case 'own-app-auto':
|
|
167
|
+
return initMode3Auto(cwd, force, log);
|
|
168
|
+
case 'own-app-manual':
|
|
169
|
+
return initMode3Manual(cwd, force, credentials, log);
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// ---------------------------------------------------------------------------
|
|
173
|
+
// Mode 2 — Airdraft's GitHub App
|
|
174
|
+
// ---------------------------------------------------------------------------
|
|
175
|
+
async function initMode2(cwd, force, credentials, log) {
|
|
176
|
+
log('Mode 2: Airdraft\'s GitHub App');
|
|
177
|
+
log('─────────────────────────────────────────────');
|
|
178
|
+
log('');
|
|
179
|
+
log('You need an Airdraft Cloud account with a project created.');
|
|
180
|
+
log('If you haven\'t done this yet:');
|
|
181
|
+
log(' 1. Sign up at https://app.airdraft.space');
|
|
182
|
+
log(' 2. Create a project and connect your GitHub repository from the dashboard');
|
|
183
|
+
log(' 3. Copy your project key from the project settings page');
|
|
184
|
+
log('');
|
|
185
|
+
let projectKey = credentials.projectKey ?? '';
|
|
186
|
+
while (!projectKey.startsWith('ntk_')) {
|
|
187
|
+
if (projectKey)
|
|
188
|
+
log(' Project keys begin with "ntk_". Please check the dashboard and try again.');
|
|
189
|
+
projectKey = await cliPrompt(' Airdraft project key (ntk_...): ');
|
|
190
|
+
}
|
|
191
|
+
let repo = credentials.repo ?? '';
|
|
192
|
+
while (!repo.includes('/')) {
|
|
193
|
+
if (repo)
|
|
194
|
+
log(' Please enter the repo in owner/repo format, e.g. "myorg/mysite".');
|
|
195
|
+
repo = await cliPrompt(' GitHub repo (owner/repo): ');
|
|
196
|
+
}
|
|
197
|
+
const branch = credentials.branch ?? ((await cliPrompt(' Default branch [main]: ')) || 'main');
|
|
198
|
+
log('');
|
|
199
|
+
await writeProjectFile(join(cwd, 'airdraft.config.ts'), mode2ConfigTemplate({ repo, branch }), force, log);
|
|
200
|
+
await writeProjectFile(join(cwd, 'app/api/cms/[...route]/route.ts'), ROUTE_HANDLER_TEMPLATE, force, log);
|
|
201
|
+
await writeProjectFile(join(cwd, '.env.local'), mode2EnvTemplate({ projectKey, repo, branch }), force, log);
|
|
202
|
+
log('');
|
|
203
|
+
log('✓ Airdraft initialized (Mode 2 — Airdraft App)');
|
|
204
|
+
log('');
|
|
205
|
+
log('Next steps:');
|
|
206
|
+
log(' 1. Run: npm install @airdraft/core @airdraft/next');
|
|
207
|
+
log(' 2. Keep AIRDRAFT_PROJECT_KEY secure — it grants write access to your repository');
|
|
208
|
+
log(' 3. Visit /api/cms/schema to verify the setup');
|
|
209
|
+
}
|
|
210
|
+
// ---------------------------------------------------------------------------
|
|
211
|
+
// Mode 3 automatic — GitHub App Manifest flow
|
|
212
|
+
// ---------------------------------------------------------------------------
|
|
213
|
+
async function initMode3Auto(cwd, force, log) {
|
|
214
|
+
log('Mode 3: Own GitHub App (automatic setup)');
|
|
215
|
+
log('─────────────────────────────────────────────');
|
|
216
|
+
log('');
|
|
217
|
+
log('This will create a private GitHub App in your account or organisation.');
|
|
218
|
+
log('You\'ll need to click "Create GitHub App" once in the browser — that\'s it.');
|
|
219
|
+
log('');
|
|
220
|
+
const owner = await cliPrompt(' GitHub org or username (e.g. "myorg"): ');
|
|
221
|
+
if (!owner)
|
|
222
|
+
throw new Error('Owner is required.');
|
|
223
|
+
const defaultAppName = `airdraft-${owner.toLowerCase().replace(/[^a-z0-9]/g, '-')}`;
|
|
224
|
+
const appNameRaw = await cliPrompt(` App name [${defaultAppName}]: `);
|
|
225
|
+
const appName = appNameRaw || defaultAppName;
|
|
226
|
+
let repo = await cliPrompt(' GitHub repo to connect (owner/repo): ');
|
|
227
|
+
while (!repo.includes('/')) {
|
|
228
|
+
log(' Please enter the repo in owner/repo format, e.g. "myorg/mysite".');
|
|
229
|
+
repo = await cliPrompt(' GitHub repo to connect (owner/repo): ');
|
|
230
|
+
}
|
|
231
|
+
const branchRaw = await cliPrompt(' Default branch [main]: ');
|
|
232
|
+
const branch = branchRaw || 'main';
|
|
233
|
+
log('');
|
|
234
|
+
// Run App Manifest + Installation flows
|
|
235
|
+
const { findFreePort, createCallbackServer, runAppManifestFlow, waitForGitHubInstall } = await import('./github.js');
|
|
236
|
+
const port = await findFreePort();
|
|
237
|
+
const server = await createCallbackServer(port);
|
|
238
|
+
let appId;
|
|
239
|
+
let appSlug;
|
|
240
|
+
let privateKey;
|
|
241
|
+
let installationId;
|
|
242
|
+
try {
|
|
243
|
+
log('Step 1/2: Create GitHub App');
|
|
244
|
+
const manifest = await runAppManifestFlow({ owner, appName, port, log });
|
|
245
|
+
appId = manifest.appId;
|
|
246
|
+
appSlug = manifest.appSlug;
|
|
247
|
+
privateKey = manifest.privateKey;
|
|
248
|
+
log(` ✓ GitHub App created (id: ${appId}, slug: ${appSlug})`);
|
|
249
|
+
log('');
|
|
250
|
+
log('Step 2/2: Install the App on your repository');
|
|
251
|
+
installationId = await waitForGitHubInstall({ appSlug, server, log });
|
|
252
|
+
log(` ✓ App installed (installation id: ${installationId})`);
|
|
253
|
+
}
|
|
254
|
+
finally {
|
|
255
|
+
await server.close();
|
|
256
|
+
}
|
|
257
|
+
log('');
|
|
258
|
+
await writeProjectFile(join(cwd, 'airdraft.config.ts'), mode3ConfigTemplate({ appId: String(appId), privateKey, installationId: String(installationId), repo, branch }), force, log);
|
|
259
|
+
await writeProjectFile(join(cwd, 'app/api/cms/[...route]/route.ts'), ROUTE_HANDLER_TEMPLATE, force, log);
|
|
260
|
+
await writeProjectFile(join(cwd, '.env.local'), mode3EnvTemplate({
|
|
261
|
+
appId: String(appId),
|
|
262
|
+
privateKey,
|
|
263
|
+
installationId: String(installationId),
|
|
264
|
+
repo,
|
|
265
|
+
branch,
|
|
266
|
+
}), force, log);
|
|
267
|
+
log('');
|
|
268
|
+
log('✓ Airdraft initialized (Mode 3 — own App)');
|
|
269
|
+
log('');
|
|
270
|
+
log('Next steps:');
|
|
271
|
+
log(' 1. Run: npm install @airdraft/core @airdraft/next');
|
|
272
|
+
log(' 2. Keep GITCMS_PRIVATE_KEY secret — it grants write access to your repository');
|
|
273
|
+
log(' 3. Visit /api/cms/schema to verify the setup');
|
|
274
|
+
}
|
|
275
|
+
// ---------------------------------------------------------------------------
|
|
276
|
+
// Mode 3 manual — prompt for all credentials
|
|
277
|
+
// ---------------------------------------------------------------------------
|
|
278
|
+
async function initMode3Manual(cwd, force, credentials, log) {
|
|
279
|
+
log('Mode 3: Own GitHub App (manual credential entry)');
|
|
280
|
+
log('─────────────────────────────────────────────');
|
|
281
|
+
log('');
|
|
282
|
+
log('You will need:');
|
|
283
|
+
log(' • GitHub App ID (from the App\'s "General" settings page)');
|
|
284
|
+
log(' • GitHub App private key (PEM — download from App settings → "Private keys")');
|
|
285
|
+
log(' • Installation ID (numeric ID shown after installing the App on your repo)');
|
|
286
|
+
log('');
|
|
287
|
+
const appId = credentials.appId ?? await cliPrompt(' GitHub App ID: ');
|
|
288
|
+
if (!appId || isNaN(Number(appId)))
|
|
289
|
+
throw new Error('App ID must be a number.');
|
|
290
|
+
let privateKey = credentials.privateKey ?? '';
|
|
291
|
+
if (!privateKey) {
|
|
292
|
+
log(' GitHub App private key — paste the full PEM below.');
|
|
293
|
+
log(' Start with "-----BEGIN RSA PRIVATE KEY-----" and paste all lines.');
|
|
294
|
+
log(' Enter a blank line followed by "END" when done.');
|
|
295
|
+
privateKey = await readMultilinePem();
|
|
296
|
+
}
|
|
297
|
+
const installationId = credentials.installationId ?? await cliPrompt(' Installation ID: ');
|
|
298
|
+
if (!installationId || isNaN(Number(installationId)))
|
|
299
|
+
throw new Error('Installation ID must be a number.');
|
|
300
|
+
let repo = credentials.repo ?? '';
|
|
301
|
+
while (!repo.includes('/')) {
|
|
302
|
+
if (repo)
|
|
303
|
+
log(' Please enter the repo in owner/repo format, e.g. "myorg/mysite".');
|
|
304
|
+
repo = await cliPrompt(' GitHub repo (owner/repo): ');
|
|
305
|
+
}
|
|
306
|
+
const branch = credentials.branch ?? ((await cliPrompt(' Default branch [main]: ')) || 'main');
|
|
307
|
+
log('');
|
|
308
|
+
await writeProjectFile(join(cwd, 'airdraft.config.ts'), mode3ConfigTemplate({ appId, privateKey, installationId, repo, branch }), force, log);
|
|
309
|
+
await writeProjectFile(join(cwd, 'app/api/cms/[...route]/route.ts'), ROUTE_HANDLER_TEMPLATE, force, log);
|
|
310
|
+
await writeProjectFile(join(cwd, '.env.local'), mode3EnvTemplate({ appId, privateKey, installationId, repo, branch }), force, log);
|
|
311
|
+
log('');
|
|
312
|
+
log('✓ Airdraft initialized (Mode 3 — own App, manual)');
|
|
313
|
+
log('');
|
|
314
|
+
log('Next steps:');
|
|
315
|
+
log(' 1. Run: npm install @airdraft/core @airdraft/next');
|
|
316
|
+
log(' 2. Keep .env.local out of version control');
|
|
317
|
+
log(' 3. Visit /api/cms/schema to verify the setup');
|
|
318
|
+
}
|
|
319
|
+
/**
|
|
320
|
+
* Reads a multi-line PEM from stdin.
|
|
321
|
+
* User terminates input by entering a blank line followed by "END".
|
|
322
|
+
*/
|
|
323
|
+
function readMultilinePem() {
|
|
324
|
+
return new Promise((resolve) => {
|
|
325
|
+
const rl = createInterface({ input: process.stdin, output: process.stdout });
|
|
326
|
+
const lines = [];
|
|
327
|
+
rl.on('line', (line) => {
|
|
328
|
+
if (line.trim() === 'END' && lines.length > 0) {
|
|
329
|
+
rl.close();
|
|
330
|
+
resolve(lines.join('\n'));
|
|
331
|
+
}
|
|
332
|
+
else {
|
|
333
|
+
lines.push(line);
|
|
334
|
+
}
|
|
335
|
+
});
|
|
336
|
+
});
|
|
337
|
+
}
|
|
338
|
+
export async function validateConfig(opts = {}) {
|
|
339
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
340
|
+
const configPath = opts.configPath ?? join(cwd, 'airdraft.config.json');
|
|
341
|
+
const log = opts.log ?? console.log;
|
|
342
|
+
const errorLog = opts.error ?? console.error;
|
|
343
|
+
const errors = [];
|
|
344
|
+
const warnings = [];
|
|
345
|
+
// Read config file
|
|
346
|
+
let raw;
|
|
347
|
+
try {
|
|
348
|
+
raw = await readFile(configPath, 'utf8');
|
|
349
|
+
}
|
|
350
|
+
catch {
|
|
351
|
+
errors.push(`Cannot read config file: ${configPath}`);
|
|
352
|
+
return { valid: false, errors, warnings };
|
|
353
|
+
}
|
|
354
|
+
// Parse JSON
|
|
355
|
+
let config;
|
|
356
|
+
try {
|
|
357
|
+
config = JSON.parse(raw);
|
|
358
|
+
}
|
|
359
|
+
catch {
|
|
360
|
+
errors.push(`Invalid JSON in config file: ${configPath}`);
|
|
361
|
+
return { valid: false, errors, warnings };
|
|
362
|
+
}
|
|
363
|
+
// Validate collections
|
|
364
|
+
if (!config.collections || typeof config.collections !== 'object') {
|
|
365
|
+
errors.push('"collections" must be an object');
|
|
366
|
+
return { valid: false, errors, warnings };
|
|
367
|
+
}
|
|
368
|
+
for (const [name, col] of Object.entries(config.collections)) {
|
|
369
|
+
if (!col.path || !col.path.includes('{slug}')) {
|
|
370
|
+
errors.push(`Collection "${name}": path must include {slug} placeholder`);
|
|
371
|
+
}
|
|
372
|
+
if (!['mdx', 'json', 'yaml'].includes(col.format)) {
|
|
373
|
+
errors.push(`Collection "${name}": format must be "mdx", "json", or "yaml"`);
|
|
374
|
+
}
|
|
375
|
+
if (!col.fields || typeof col.fields !== 'object') {
|
|
376
|
+
errors.push(`Collection "${name}": fields must be an object`);
|
|
377
|
+
continue;
|
|
378
|
+
}
|
|
379
|
+
// Build FieldConfig map for compat check
|
|
380
|
+
const fieldConfigs = Object.fromEntries(Object.entries(col.fields).map(([k, v]) => [k, v]));
|
|
381
|
+
const compatError = checkFormatCompatibility(col.format, fieldConfigs);
|
|
382
|
+
if (compatError) {
|
|
383
|
+
errors.push(`Collection "${name}": ${compatError}`);
|
|
384
|
+
}
|
|
385
|
+
if (col.publish) {
|
|
386
|
+
if (fieldConfigs['published']) {
|
|
387
|
+
warnings.push(`Collection "${name}": field "published" is reserved by the publish system`);
|
|
388
|
+
}
|
|
389
|
+
if (fieldConfigs['publishedAt']) {
|
|
390
|
+
warnings.push(`Collection "${name}": field "publishedAt" is reserved by the publish system`);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
393
|
+
}
|
|
394
|
+
const valid = errors.length === 0;
|
|
395
|
+
for (const w of warnings)
|
|
396
|
+
log(` warn ${w}`);
|
|
397
|
+
for (const e of errors)
|
|
398
|
+
errorLog(` error ${e}`);
|
|
399
|
+
if (valid)
|
|
400
|
+
log(' ✓ Config is valid');
|
|
401
|
+
return { valid, errors, warnings };
|
|
402
|
+
}
|
|
403
|
+
// ---------------------------------------------------------------------------
|
|
404
|
+
// Schema printer
|
|
405
|
+
// ---------------------------------------------------------------------------
|
|
406
|
+
export function printSchema(schema) {
|
|
407
|
+
const lines = ['Collections:'];
|
|
408
|
+
for (const [name, col] of Object.entries(schema.collections)) {
|
|
409
|
+
lines.push(` ${name} (${col.format}) → ${col.path}`);
|
|
410
|
+
for (const [field, cfg] of Object.entries(col.fields)) {
|
|
411
|
+
const req = cfg.required ? ' *' : '';
|
|
412
|
+
lines.push(` ${field}: ${cfg.type}${req}`);
|
|
413
|
+
}
|
|
414
|
+
}
|
|
415
|
+
return lines.join('\n');
|
|
416
|
+
}
|
|
417
|
+
// ---------------------------------------------------------------------------
|
|
418
|
+
// generate-secret (C7)
|
|
419
|
+
// ---------------------------------------------------------------------------
|
|
420
|
+
/**
|
|
421
|
+
* Generates a cryptographically random 64-character hex secret suitable for
|
|
422
|
+
* use as `AIRDRAFT_JWT_SECRET`.
|
|
423
|
+
*
|
|
424
|
+
* Usage:
|
|
425
|
+
* npx airdraft generate-secret
|
|
426
|
+
*/
|
|
427
|
+
export function generateSecret() {
|
|
428
|
+
return randomBytes(32).toString('hex');
|
|
429
|
+
}
|
|
430
|
+
const FIELD_TYPE_MAP = {
|
|
431
|
+
string: 'string',
|
|
432
|
+
text: 'string',
|
|
433
|
+
'rich-text': 'string',
|
|
434
|
+
select: 'string',
|
|
435
|
+
relation: 'string',
|
|
436
|
+
image: 'string',
|
|
437
|
+
number: 'number',
|
|
438
|
+
boolean: 'boolean',
|
|
439
|
+
date: 'string',
|
|
440
|
+
datetime: 'string',
|
|
441
|
+
list: 'string[]',
|
|
442
|
+
multiselect: 'string[]',
|
|
443
|
+
relations: 'string[]',
|
|
444
|
+
object: 'Record<string, unknown>',
|
|
445
|
+
};
|
|
446
|
+
function singularPascalCase(str) {
|
|
447
|
+
const singular = str
|
|
448
|
+
.replace(/ies$/, 'y') // categories → category
|
|
449
|
+
.replace(/ses$/, 's') // statuses → status
|
|
450
|
+
.replace(/(?<!s)s$/, ''); // posts → post, authors → author
|
|
451
|
+
return singular
|
|
452
|
+
.replace(/[-_](.)/g, (_, c) => c.toUpperCase())
|
|
453
|
+
.replace(/^(.)/, (_, c) => c.toUpperCase());
|
|
454
|
+
}
|
|
455
|
+
async function fetchSchema(source, apiKey) {
|
|
456
|
+
if (source.startsWith('http://') || source.startsWith('https://')) {
|
|
457
|
+
const res = await fetch(source, {
|
|
458
|
+
headers: apiKey ? { 'x-api-key': apiKey } : {},
|
|
459
|
+
});
|
|
460
|
+
if (!res.ok)
|
|
461
|
+
throw new Error(`GET ${source} → ${res.status} ${res.statusText}`);
|
|
462
|
+
const json = await res.json();
|
|
463
|
+
// API envelope: { data: { collections: {...} } }
|
|
464
|
+
return ('data' in json && json.data ? json.data : json);
|
|
465
|
+
}
|
|
466
|
+
const raw = await readFile(source, 'utf-8');
|
|
467
|
+
return JSON.parse(raw);
|
|
468
|
+
}
|
|
469
|
+
function renderTypes(schema, source) {
|
|
470
|
+
const lines = [
|
|
471
|
+
'// AUTO-GENERATED — do not edit by hand.',
|
|
472
|
+
'// Re-generate with: npx airdraft generate-types',
|
|
473
|
+
'//',
|
|
474
|
+
`// Source: ${source}`,
|
|
475
|
+
'',
|
|
476
|
+
];
|
|
477
|
+
const names = Object.keys(schema.collections);
|
|
478
|
+
for (const [colName, col] of Object.entries(schema.collections)) {
|
|
479
|
+
const pascal = singularPascalCase(colName);
|
|
480
|
+
const dataInterface = `${pascal}Data`;
|
|
481
|
+
lines.push(`export interface ${dataInterface} {`);
|
|
482
|
+
for (const [fieldName, field] of Object.entries(col.fields)) {
|
|
483
|
+
const tsType = FIELD_TYPE_MAP[field.type] ?? 'unknown';
|
|
484
|
+
const opt = field.required ? '' : '?';
|
|
485
|
+
lines.push(` ${fieldName}${opt}: ${tsType}`);
|
|
486
|
+
// image fields: server appends `{name}_url` (CDN URL) and `{name}_media` (full object)
|
|
487
|
+
if (field.type === 'image') {
|
|
488
|
+
lines.push(` ${fieldName}_url?: string`);
|
|
489
|
+
lines.push(` ${fieldName}_media?: { key: string; url?: string; name?: string; mimeType?: string; size?: number }`);
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
if (col.publish) {
|
|
493
|
+
lines.push(' published?: boolean');
|
|
494
|
+
lines.push(' publishedAt?: string | null');
|
|
495
|
+
}
|
|
496
|
+
lines.push('}');
|
|
497
|
+
lines.push('');
|
|
498
|
+
lines.push(`/** A \`${colName}\` entry with its \`data\` field typed as {@link ${dataInterface}}. */`);
|
|
499
|
+
lines.push(`export interface ${pascal}Entry {`);
|
|
500
|
+
lines.push(' slug: string');
|
|
501
|
+
lines.push(' meta: { sha: string }');
|
|
502
|
+
lines.push(` data: ${dataInterface}`);
|
|
503
|
+
lines.push('}');
|
|
504
|
+
lines.push('');
|
|
505
|
+
}
|
|
506
|
+
lines.push('/** Union of all typed entry interfaces. */');
|
|
507
|
+
lines.push(`export type AnyEntry = ${names.map(singularPascalCase).map((n) => `${n}Entry`).join(' | ')}`);
|
|
508
|
+
lines.push('');
|
|
509
|
+
lines.push('/** Literal union of all collection names defined in the schema. */');
|
|
510
|
+
lines.push(`export type CollectionName = ${names.map((n) => `'${n}'`).join(' | ')}`);
|
|
511
|
+
lines.push('');
|
|
512
|
+
return lines.join('\n');
|
|
513
|
+
}
|
|
514
|
+
/**
|
|
515
|
+
* Reads an Airdraft schema (from a local JSON file or a live API endpoint) and
|
|
516
|
+
* writes typed TypeScript interfaces to the output file.
|
|
517
|
+
*
|
|
518
|
+
* Works with:
|
|
519
|
+
* - Local file: `airdraft.schema.json` in the project root
|
|
520
|
+
* - Local dev server: `http://localhost:3000/api/cms/schema`
|
|
521
|
+
* - Airdraft Cloud: `https://your-project.airdraft.cloud/api/cms/schema`
|
|
522
|
+
*/
|
|
523
|
+
export async function generateTypes(opts = {}) {
|
|
524
|
+
const cwd = opts.cwd ?? process.cwd();
|
|
525
|
+
const log = opts.log ?? console.log;
|
|
526
|
+
const source = opts.source ?? join(cwd, 'airdraft.schema.json');
|
|
527
|
+
const outPath = opts.out ?? join(cwd, 'lib', 'cms-types.ts');
|
|
528
|
+
const schema = await fetchSchema(source, opts.apiKey);
|
|
529
|
+
const output = renderTypes(schema, opts.source ?? 'airdraft.schema.json');
|
|
530
|
+
const { mkdir } = await import('node:fs/promises');
|
|
531
|
+
await mkdir(resolve(outPath, '..'), { recursive: true });
|
|
532
|
+
await writeFile(outPath, output, 'utf-8');
|
|
533
|
+
log(`✓ Generated ${outPath}`);
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* Opens a browser for CLI authentication against Airdraft Cloud.
|
|
537
|
+
*
|
|
538
|
+
* Flow:
|
|
539
|
+
* 1. Start a local one-shot HTTP server on a free port.
|
|
540
|
+
* 2. Open `${cloudUrl}/auth/cli/auth?callback=http://localhost:{port}/` in the browser.
|
|
541
|
+
* 3. Cloud dashboard signs a short-lived JWT and redirects back with `?token=…`.
|
|
542
|
+
* 4. Store the token in `~/.config/airdraft/credentials.json`.
|
|
543
|
+
*/
|
|
544
|
+
export async function loginCloud(opts = {}) {
|
|
545
|
+
const { createServer } = await import('node:http');
|
|
546
|
+
const { homedir } = await import('node:os');
|
|
547
|
+
const { join: pathJoin, resolve: pathResolve } = await import('node:path');
|
|
548
|
+
const { mkdir, writeFile: writeFileNode } = await import('node:fs/promises');
|
|
549
|
+
const { findFreePort, openBrowser } = await import('./github.js');
|
|
550
|
+
const log = opts.log ?? console.log;
|
|
551
|
+
const cloudUrl = (opts.cloudUrl ?? 'https://app.airdraft.space').replace(/\/$/, '');
|
|
552
|
+
const port = await findFreePort();
|
|
553
|
+
const callbackBase = `http://localhost:${port}/`;
|
|
554
|
+
const loginUrl = `${cloudUrl}/auth/cli/auth?callback=${encodeURIComponent(callbackBase)}`;
|
|
555
|
+
log('');
|
|
556
|
+
log('Airdraft Cloud login');
|
|
557
|
+
log('─────────────────────────────────────────────');
|
|
558
|
+
log('');
|
|
559
|
+
log(`Opening: ${loginUrl}`);
|
|
560
|
+
log('If the browser does not open automatically, paste the URL above.');
|
|
561
|
+
log('');
|
|
562
|
+
const token = await new Promise((resolve, reject) => {
|
|
563
|
+
const server = createServer((req, res) => {
|
|
564
|
+
try {
|
|
565
|
+
const url = new URL(req.url ?? '/', callbackBase);
|
|
566
|
+
const t = url.searchParams.get('token');
|
|
567
|
+
res.writeHead(200, { 'Content-Type': 'text/html' });
|
|
568
|
+
res.end('<html><body><p>Authentication complete — you may close this tab.</p></body></html>');
|
|
569
|
+
server.close();
|
|
570
|
+
if (t) {
|
|
571
|
+
resolve(t);
|
|
572
|
+
}
|
|
573
|
+
else {
|
|
574
|
+
reject(new Error('No token in callback URL'));
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
catch (err) {
|
|
578
|
+
server.close();
|
|
579
|
+
reject(err);
|
|
580
|
+
}
|
|
581
|
+
});
|
|
582
|
+
server.listen(port, '127.0.0.1', () => {
|
|
583
|
+
openBrowser(loginUrl).catch(() => undefined);
|
|
584
|
+
});
|
|
585
|
+
server.on('error', reject);
|
|
586
|
+
// 5-minute timeout
|
|
587
|
+
setTimeout(() => {
|
|
588
|
+
server.close();
|
|
589
|
+
reject(new Error('Login timed out (5 minutes). Please try again.'));
|
|
590
|
+
}, 300_000);
|
|
591
|
+
});
|
|
592
|
+
// Persist token
|
|
593
|
+
const credDir = pathJoin(homedir(), '.config', 'airdraft');
|
|
594
|
+
const credPath = pathJoin(credDir, 'credentials.json');
|
|
595
|
+
await mkdir(credDir, { recursive: true });
|
|
596
|
+
await writeFileNode(credPath, JSON.stringify({ token, cloudUrl, savedAt: new Date().toISOString() }, null, 2), 'utf8');
|
|
597
|
+
log(`✓ Authenticated. Credentials saved to ${credPath}`);
|
|
598
|
+
log('');
|
|
599
|
+
log('You can now use airdraft CLI commands that require cloud access.');
|
|
600
|
+
}
|
|
601
|
+
export async function createUser(opts) {
|
|
602
|
+
const { UserStore } = await import('@airdraft/plugin-auth');
|
|
603
|
+
const log = opts.log ?? console.log;
|
|
604
|
+
const storePath = join(opts.cwd ?? process.cwd(), '.airdraft', 'users.json');
|
|
605
|
+
const store = new UserStore(storePath);
|
|
606
|
+
const user = await store.create(opts.email, opts.password, opts.role, opts.name);
|
|
607
|
+
log(`\n✓ User created`);
|
|
608
|
+
log(` id: ${user.id}`);
|
|
609
|
+
log(` email: ${user.email}`);
|
|
610
|
+
if (user.name)
|
|
611
|
+
log(` name: ${user.name}`);
|
|
612
|
+
log(` role: ${user.role}`);
|
|
613
|
+
}
|
|
614
|
+
//# sourceMappingURL=commands.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"commands.js","sourceRoot":"","sources":["../src/commands.ts"],"names":[],"mappings":"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"}
|