@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.
@@ -0,0 +1,75 @@
1
+ /**
2
+ * @airdraft/cli — GitHub App integration helpers
3
+ *
4
+ * Provides utilities for the two GitHub App setup paths:
5
+ * - Mode 2 (Airdraft App): guided flow — user creates project on dashboard, CLI writes .env.local
6
+ * - Mode 3 (own App):
7
+ * auto — GitHub App Manifest flow (browser + local server, zero manual credential handling)
8
+ * manual — interactive prompts for all 5 vars
9
+ */
10
+ /**
11
+ * Opens `url` in the default browser. Best-effort; never throws.
12
+ * Logs the URL to stdout so users can open it manually if the browser doesn't launch.
13
+ */
14
+ export declare function openBrowser(url: string): Promise<void>;
15
+ /** Finds an available TCP port on 127.0.0.1. */
16
+ export declare function findFreePort(): Promise<number>;
17
+ /** A lightweight local HTTP server used to receive GitHub redirects. */
18
+ export interface CallbackServer {
19
+ readonly port: number;
20
+ /**
21
+ * Pre-register an HTML page to be served when the browser GETs `pathname`.
22
+ * Typically used for the auto-submit manifest form that bootstraps the flow.
23
+ */
24
+ serve(pathname: string, html: string): void;
25
+ /**
26
+ * Wait for the next browser redirect to `pathname`.
27
+ * Serves `responseHtml` as the 200 response, then resolves with the URL's query params.
28
+ * Rejects after `timeoutMs` (default 5 minutes).
29
+ */
30
+ waitFor(pathname: string, responseHtml: string, timeoutMs?: number): Promise<URLSearchParams>;
31
+ /** Shut down the server. */
32
+ close(): Promise<void>;
33
+ }
34
+ export declare function createCallbackServer(port: number): Promise<CallbackServer>;
35
+ export interface AppManifestResult {
36
+ appId: number;
37
+ /** The GitHub App slug, e.g. "my-org-airdraft" */
38
+ appSlug: string;
39
+ /** RSA PEM private key */
40
+ privateKey: string;
41
+ webhookSecret: string;
42
+ clientId: string;
43
+ clientSecret: string;
44
+ }
45
+ /**
46
+ * Runs the GitHub App Manifest creation flow.
47
+ *
48
+ * 1. Starts local server
49
+ * 2. Serves auto-submit HTML form → browser POSTs manifest to GitHub
50
+ * 3. User confirms on GitHub
51
+ * 4. GitHub redirects to local `/manifest-callback?code=xxx`
52
+ * 5. CLI exchanges code for app credentials
53
+ *
54
+ * @param opts.owner GitHub org name or personal account login
55
+ * @param opts.appName Desired GitHub App name (must be unique on GitHub)
56
+ * @param opts.port Local server port (from `findFreePort()`)
57
+ */
58
+ export declare function runAppManifestFlow(opts: {
59
+ owner: string;
60
+ appName: string;
61
+ port: number;
62
+ log: (msg: string) => void;
63
+ }): Promise<AppManifestResult>;
64
+ /**
65
+ * Opens the GitHub App installation page and waits for the user to install it.
66
+ * Returns the `installation_id`.
67
+ *
68
+ * Must be called with the same `server` used in `runAppManifestFlow`.
69
+ */
70
+ export declare function waitForGitHubInstall(opts: {
71
+ appSlug: string;
72
+ server: CallbackServer;
73
+ log: (msg: string) => void;
74
+ }): Promise<number>;
75
+ //# sourceMappingURL=github.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.d.ts","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAaH;;;GAGG;AACH,wBAAsB,WAAW,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAW5D;AAMD,gDAAgD;AAChD,wBAAgB,YAAY,IAAI,OAAO,CAAC,MAAM,CAAC,CAY9C;AAMD,wEAAwE;AACxE,MAAM,WAAW,cAAc;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB;;;OAGG;IACH,KAAK,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C;;;;OAIG;IACH,OAAO,CAAC,QAAQ,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,eAAe,CAAC,CAAA;IAC7F,4BAA4B;IAC5B,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAA;CACvB;AAED,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,CAkE1E;AAkBD,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,MAAM,CAAA;IACb,kDAAkD;IAClD,OAAO,EAAE,MAAM,CAAA;IACf,0BAA0B;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,aAAa,EAAE,MAAM,CAAA;IACrB,QAAQ,EAAE,MAAM,CAAA;IAChB,YAAY,EAAE,MAAM,CAAA;CACrB;AAED;;;;;;;;;;;;GAYG;AACH,wBAAsB,kBAAkB,CAAC,IAAI,EAAE;IAC7C,KAAK,EAAE,MAAM,CAAA;IACb,OAAO,EAAE,MAAM,CAAA;IACf,IAAI,EAAE,MAAM,CAAA;IACZ,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAC3B,GAAG,OAAO,CAAC,iBAAiB,CAAC,CAsG7B;AAED;;;;;GAKG;AACH,wBAAsB,oBAAoB,CAAC,IAAI,EAAE;IAC/C,OAAO,EAAE,MAAM,CAAA;IACf,MAAM,EAAE,cAAc,CAAA;IACtB,GAAG,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,IAAI,CAAA;CAC3B,GAAG,OAAO,CAAC,MAAM,CAAC,CAuBlB"}
package/dist/github.js ADDED
@@ -0,0 +1,234 @@
1
+ /**
2
+ * @airdraft/cli — GitHub App integration helpers
3
+ *
4
+ * Provides utilities for the two GitHub App setup paths:
5
+ * - Mode 2 (Airdraft App): guided flow — user creates project on dashboard, CLI writes .env.local
6
+ * - Mode 3 (own App):
7
+ * auto — GitHub App Manifest flow (browser + local server, zero manual credential handling)
8
+ * manual — interactive prompts for all 5 vars
9
+ */
10
+ import { createServer } from 'node:http';
11
+ import { exec } from 'node:child_process';
12
+ import { promisify } from 'node:util';
13
+ const execAsync = promisify(exec);
14
+ // ---------------------------------------------------------------------------
15
+ // Browser opener
16
+ // ---------------------------------------------------------------------------
17
+ /**
18
+ * Opens `url` in the default browser. Best-effort; never throws.
19
+ * Logs the URL to stdout so users can open it manually if the browser doesn't launch.
20
+ */
21
+ export async function openBrowser(url) {
22
+ const platform = process.platform;
23
+ const cmd = platform === 'darwin' ? `open "${url}"` :
24
+ platform === 'win32' ? `start "" "${url}"` :
25
+ `xdg-open "${url}"`;
26
+ try {
27
+ await execAsync(cmd);
28
+ }
29
+ catch {
30
+ // Silently swallow — caller should display URL as fallback
31
+ }
32
+ }
33
+ // ---------------------------------------------------------------------------
34
+ // Free-port finder
35
+ // ---------------------------------------------------------------------------
36
+ /** Finds an available TCP port on 127.0.0.1. */
37
+ export function findFreePort() {
38
+ return new Promise((resolve, reject) => {
39
+ const server = createServer();
40
+ server.listen(0, '127.0.0.1', () => {
41
+ const addr = server.address();
42
+ server.close(() => {
43
+ if (addr && typeof addr === 'object')
44
+ resolve(addr.port);
45
+ else
46
+ reject(new Error('Could not determine free port'));
47
+ });
48
+ });
49
+ server.on('error', reject);
50
+ });
51
+ }
52
+ export function createCallbackServer(port) {
53
+ return new Promise((resolveCreate, rejectCreate) => {
54
+ const staticRoutes = new Map();
55
+ const pendingWaiters = new Map();
56
+ const server = createServer((req, res) => {
57
+ const url = new URL(req.url ?? '/', `http://127.0.0.1:${port}`);
58
+ const pathname = url.pathname;
59
+ // Check pending waiter first
60
+ const waiter = pendingWaiters.get(pathname);
61
+ if (waiter) {
62
+ pendingWaiters.delete(pathname);
63
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
64
+ res.end(waiter.html);
65
+ waiter.resolve(url.searchParams);
66
+ return;
67
+ }
68
+ // Check static route
69
+ const staticHtml = staticRoutes.get(pathname);
70
+ if (staticHtml) {
71
+ res.writeHead(200, { 'Content-Type': 'text/html; charset=utf-8' });
72
+ res.end(staticHtml);
73
+ return;
74
+ }
75
+ res.writeHead(404);
76
+ res.end('Not found');
77
+ });
78
+ server.on('error', rejectCreate);
79
+ server.listen(port, '127.0.0.1', () => {
80
+ const handle = {
81
+ port,
82
+ serve(pathname, html) {
83
+ staticRoutes.set(pathname, html);
84
+ },
85
+ waitFor(pathname, responseHtml, timeoutMs = 5 * 60 * 1000) {
86
+ return new Promise((resolve, reject) => {
87
+ const timer = setTimeout(() => {
88
+ pendingWaiters.delete(pathname);
89
+ reject(new Error(`Timed out waiting for callback on ${pathname}`));
90
+ }, timeoutMs);
91
+ pendingWaiters.set(pathname, {
92
+ html: responseHtml,
93
+ resolve: (params) => {
94
+ clearTimeout(timer);
95
+ resolve(params);
96
+ },
97
+ });
98
+ });
99
+ },
100
+ close() {
101
+ return new Promise((res, rej) => server.close((err) => (err ? rej(err) : res())));
102
+ },
103
+ };
104
+ resolveCreate(handle);
105
+ });
106
+ });
107
+ }
108
+ // ---------------------------------------------------------------------------
109
+ // HTML helpers
110
+ // ---------------------------------------------------------------------------
111
+ function successHtml(title, body) {
112
+ return `<!DOCTYPE html><html><head><meta charset="utf-8"><title>${title}</title>
113
+ <style>body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#f9fafb}
114
+ .card{background:#fff;border:1px solid #e5e7eb;border-radius:12px;padding:2rem 2.5rem;max-width:420px;text-align:center;box-shadow:0 1px 8px rgba(0,0,0,.06)}
115
+ h1{font-size:1.25rem;margin:0 0 .5rem}p{color:#6b7280;margin:.5rem 0 0}</style>
116
+ </head><body><div class="card"><h1>${title}</h1><p>${body}</p></div></body></html>`;
117
+ }
118
+ /**
119
+ * Runs the GitHub App Manifest creation flow.
120
+ *
121
+ * 1. Starts local server
122
+ * 2. Serves auto-submit HTML form → browser POSTs manifest to GitHub
123
+ * 3. User confirms on GitHub
124
+ * 4. GitHub redirects to local `/manifest-callback?code=xxx`
125
+ * 5. CLI exchanges code for app credentials
126
+ *
127
+ * @param opts.owner GitHub org name or personal account login
128
+ * @param opts.appName Desired GitHub App name (must be unique on GitHub)
129
+ * @param opts.port Local server port (from `findFreePort()`)
130
+ */
131
+ export async function runAppManifestFlow(opts) {
132
+ const { owner, appName, port, log } = opts;
133
+ const server = await createCallbackServer(port);
134
+ let result;
135
+ try {
136
+ // Build manifest JSON
137
+ const manifest = JSON.stringify({
138
+ name: appName,
139
+ url: 'https://airdraft.space',
140
+ description: 'Git-native headless CMS — read and write content files in your repository',
141
+ redirect_url: `http://127.0.0.1:${port}/manifest-callback`,
142
+ callback_urls: [`http://127.0.0.1:${port}/install-callback`],
143
+ setup_url: `http://127.0.0.1:${port}/install-callback`,
144
+ redirect_on_update: false,
145
+ hook_attributes: { active: false },
146
+ public: false,
147
+ default_permissions: {
148
+ contents: 'write',
149
+ metadata: 'read',
150
+ },
151
+ default_events: [],
152
+ });
153
+ // Is owner an org or a personal account? We'll offer both paths.
154
+ // GitHub's App creation URL for personal: https://github.com/settings/apps/new
155
+ // For an org: https://github.com/organizations/<org>/settings/apps/new
156
+ // We'll try org path; GitHub will redirect appropriately.
157
+ const githubCreateUrl = `https://github.com/organizations/${encodeURIComponent(owner)}/settings/apps/new`;
158
+ // Serve the auto-submit form
159
+ const formHtml = `<!DOCTYPE html><html><head><meta charset="utf-8"><title>Creating GitHub App...</title>
160
+ <style>body{font-family:system-ui,sans-serif;display:flex;align-items:center;justify-content:center;min-height:100vh;margin:0;background:#f9fafb}</style>
161
+ </head><body>
162
+ <p>Redirecting to GitHub to create your App…</p>
163
+ <form id="f" action="${githubCreateUrl}" method="POST">
164
+ <input type="hidden" name="manifest" value="${manifest.replace(/"/g, '&quot;')}" />
165
+ </form>
166
+ <script>document.getElementById('f').submit()</script>
167
+ </body></html>`;
168
+ server.serve('/github-app-setup', formHtml);
169
+ // Wait for manifest callback (before opening browser — register first)
170
+ const manifestCallbackPromise = server.waitFor('/manifest-callback', successHtml('✓ GitHub App created', 'You can close this tab. Return to your terminal to continue.'), 10 * 60 * 1000 // 10 min timeout
171
+ );
172
+ // Open browser to the auto-submit form page
173
+ const setupUrl = `http://127.0.0.1:${port}/github-app-setup`;
174
+ log(`\n Opening browser → ${setupUrl}`);
175
+ log(' If the browser does not open automatically, visit the URL above.');
176
+ await openBrowser(setupUrl);
177
+ log(' Waiting for GitHub App creation… (this may take up to a minute)');
178
+ const params = await manifestCallbackPromise;
179
+ const code = params.get('code');
180
+ if (!code)
181
+ throw new Error('GitHub did not return a code in the callback');
182
+ // Exchange code for app credentials
183
+ log(' Exchanging code for app credentials…');
184
+ const convRes = await fetch(`https://api.github.com/app-manifests/${code}/conversions`, {
185
+ method: 'POST',
186
+ headers: {
187
+ Accept: 'application/vnd.github+json',
188
+ 'X-GitHub-Api-Version': '2022-11-28',
189
+ },
190
+ });
191
+ if (!convRes.ok) {
192
+ throw new Error(`GitHub App conversion API returned ${convRes.status}`);
193
+ }
194
+ const conv = await convRes.json();
195
+ result = {
196
+ appId: conv.id,
197
+ appSlug: conv.slug,
198
+ privateKey: conv.pem,
199
+ webhookSecret: conv.webhook_secret,
200
+ clientId: conv.client_id,
201
+ clientSecret: conv.client_secret,
202
+ };
203
+ }
204
+ catch (err) {
205
+ // Don't close the server here — caller must close it after the install step
206
+ throw err;
207
+ }
208
+ // Server is intentionally left open for the installation step.
209
+ // Caller must call server.close() after waitForGitHubInstall.
210
+ return result;
211
+ }
212
+ /**
213
+ * Opens the GitHub App installation page and waits for the user to install it.
214
+ * Returns the `installation_id`.
215
+ *
216
+ * Must be called with the same `server` used in `runAppManifestFlow`.
217
+ */
218
+ export async function waitForGitHubInstall(opts) {
219
+ const { appSlug, server, log } = opts;
220
+ const installUrl = `https://github.com/apps/${encodeURIComponent(appSlug)}/installations/new`;
221
+ log(`\n Opening browser → ${installUrl}`);
222
+ log(' If the browser does not open automatically, visit the URL above.');
223
+ await openBrowser(installUrl);
224
+ log(' Waiting for GitHub App installation…');
225
+ const params = await server.waitFor('/install-callback', successHtml('✓ GitHub App installed', 'You can close this tab. Return to your terminal — setup is almost done.'), 10 * 60 * 1000);
226
+ const rawId = params.get('installation_id');
227
+ if (!rawId)
228
+ throw new Error('GitHub did not return installation_id in callback');
229
+ const id = parseInt(rawId, 10);
230
+ if (isNaN(id))
231
+ throw new Error(`Invalid installation_id: ${rawId}`);
232
+ return id;
233
+ }
234
+ //# sourceMappingURL=github.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github.js","sourceRoot":"","sources":["../src/github.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,WAAW,CAAA;AAExC,OAAO,EAAE,IAAI,EAAE,MAAM,oBAAoB,CAAA;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAA;AAErC,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAA;AAEjC,8EAA8E;AAC9E,iBAAiB;AACjB,8EAA8E;AAE9E;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,GAAW;IAC3C,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IACjC,MAAM,GAAG,GACP,QAAQ,KAAK,QAAQ,CAAC,CAAC,CAAC,SAAS,GAAG,GAAG,CAAC,CAAC;QACzC,QAAQ,KAAK,OAAO,CAAE,CAAC,CAAC,aAAa,GAAG,GAAG,CAAC,CAAC;YAC7C,aAAa,GAAG,GAAG,CAAA;IACrB,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,GAAG,CAAC,CAAA;IACtB,CAAC;IAAC,MAAM,CAAC;QACP,2DAA2D;IAC7D,CAAC;AACH,CAAC;AAED,8EAA8E;AAC9E,mBAAmB;AACnB,8EAA8E;AAE9E,gDAAgD;AAChD,MAAM,UAAU,YAAY;IAC1B,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;QACrC,MAAM,MAAM,GAAG,YAAY,EAAE,CAAA;QAC7B,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,WAAW,EAAE,GAAG,EAAE;YACjC,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,EAAE,CAAA;YAC7B,MAAM,CAAC,KAAK,CAAC,GAAG,EAAE;gBAChB,IAAI,IAAI,IAAI,OAAO,IAAI,KAAK,QAAQ;oBAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;;oBACnD,MAAM,CAAC,IAAI,KAAK,CAAC,+BAA+B,CAAC,CAAC,CAAA;YACzD,CAAC,CAAC,CAAA;QACJ,CAAC,CAAC,CAAA;QACF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,MAAM,CAAC,CAAA;IAC5B,CAAC,CAAC,CAAA;AACJ,CAAC;AAwBD,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,IAAI,OAAO,CAAC,CAAC,aAAa,EAAE,YAAY,EAAE,EAAE;QACjD,MAAM,YAAY,GAAG,IAAI,GAAG,EAAkB,CAAA;QAC9C,MAAM,cAAc,GAAG,IAAI,GAAG,EAAmE,CAAA;QAEjG,MAAM,MAAM,GAAW,YAAY,CAAC,CAAC,GAAoB,EAAE,GAAmB,EAAE,EAAE;YAChF,MAAM,GAAG,GAAG,IAAI,GAAG,CAAC,GAAG,CAAC,GAAG,IAAI,GAAG,EAAE,oBAAoB,IAAI,EAAE,CAAC,CAAA;YAC/D,MAAM,QAAQ,GAAG,GAAG,CAAC,QAAQ,CAAA;YAE7B,6BAA6B;YAC7B,MAAM,MAAM,GAAG,cAAc,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC3C,IAAI,MAAM,EAAE,CAAC;gBACX,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;gBAC/B,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAA;gBAClE,GAAG,CAAC,GAAG,CAAC,MAAM,CAAC,IAAI,CAAC,CAAA;gBACpB,MAAM,CAAC,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAA;gBAChC,OAAM;YACR,CAAC;YAED,qBAAqB;YACrB,MAAM,UAAU,GAAG,YAAY,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;YAC7C,IAAI,UAAU,EAAE,CAAC;gBACf,GAAG,CAAC,SAAS,CAAC,GAAG,EAAE,EAAE,cAAc,EAAE,0BAA0B,EAAE,CAAC,CAAA;gBAClE,GAAG,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;gBACnB,OAAM;YACR,CAAC;YAED,GAAG,CAAC,SAAS,CAAC,GAAG,CAAC,CAAA;YAClB,GAAG,CAAC,GAAG,CAAC,WAAW,CAAC,CAAA;QACtB,CAAC,CAAC,CAAA;QAEF,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,YAAY,CAAC,CAAA;QAEhC,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,WAAW,EAAE,GAAG,EAAE;YACpC,MAAM,MAAM,GAAmB;gBAC7B,IAAI;gBAEJ,KAAK,CAAC,QAAQ,EAAE,IAAI;oBAClB,YAAY,CAAC,GAAG,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAA;gBAClC,CAAC;gBAED,OAAO,CAAC,QAAQ,EAAE,YAAY,EAAE,SAAS,GAAG,CAAC,GAAG,EAAE,GAAG,IAAI;oBACvD,OAAO,IAAI,OAAO,CAAkB,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;wBACtD,MAAM,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE;4BAC5B,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAA;4BAC/B,MAAM,CAAC,IAAI,KAAK,CAAC,qCAAqC,QAAQ,EAAE,CAAC,CAAC,CAAA;wBACpE,CAAC,EAAE,SAAS,CAAC,CAAA;wBAEb,cAAc,CAAC,GAAG,CAAC,QAAQ,EAAE;4BAC3B,IAAI,EAAE,YAAY;4BAClB,OAAO,EAAE,CAAC,MAAM,EAAE,EAAE;gCAClB,YAAY,CAAC,KAAK,CAAC,CAAA;gCACnB,OAAO,CAAC,MAAM,CAAC,CAAA;4BACjB,CAAC;yBACF,CAAC,CAAA;oBACJ,CAAC,CAAC,CAAA;gBACJ,CAAC;gBAED,KAAK;oBACH,OAAO,IAAI,OAAO,CAAO,CAAC,GAAG,EAAE,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,CAAA;gBACzF,CAAC;aACF,CAAA;YAED,aAAa,CAAC,MAAM,CAAC,CAAA;QACvB,CAAC,CAAC,CAAA;IACJ,CAAC,CAAC,CAAA;AACJ,CAAC;AAED,8EAA8E;AAC9E,eAAe;AACf,8EAA8E;AAE9E,SAAS,WAAW,CAAC,KAAa,EAAE,IAAY;IAC9C,OAAO,2DAA2D,KAAK;;;;qCAIpC,KAAK,WAAW,IAAI,0BAA0B,CAAA;AACnF,CAAC;AAiBD;;;;;;;;;;;;GAYG;AACH,MAAM,CAAC,KAAK,UAAU,kBAAkB,CAAC,IAKxC;IACC,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;IAE1C,MAAM,MAAM,GAAG,MAAM,oBAAoB,CAAC,IAAI,CAAC,CAAA;IAE/C,IAAI,MAAyB,CAAA;IAC7B,IAAI,CAAC;QACH,sBAAsB;QACtB,MAAM,QAAQ,GAAG,IAAI,CAAC,SAAS,CAAC;YAC9B,IAAI,EAAE,OAAO;YACb,GAAG,EAAE,wBAAwB;YAC7B,WAAW,EAAE,2EAA2E;YACxF,YAAY,EAAE,oBAAoB,IAAI,oBAAoB;YAC1D,aAAa,EAAE,CAAC,oBAAoB,IAAI,mBAAmB,CAAC;YAC5D,SAAS,EAAE,oBAAoB,IAAI,mBAAmB;YACtD,kBAAkB,EAAE,KAAK;YACzB,eAAe,EAAE,EAAE,MAAM,EAAE,KAAK,EAAE;YAClC,MAAM,EAAE,KAAK;YACb,mBAAmB,EAAE;gBACnB,QAAQ,EAAE,OAAO;gBACjB,QAAQ,EAAE,MAAM;aACjB;YACD,cAAc,EAAE,EAAE;SACnB,CAAC,CAAA;QAEF,iEAAiE;QACjE,+EAA+E;QAC/E,uEAAuE;QACvE,0DAA0D;QAC1D,MAAM,eAAe,GAAG,oCAAoC,kBAAkB,CAAC,KAAK,CAAC,oBAAoB,CAAA;QAEzG,6BAA6B;QAC7B,MAAM,QAAQ,GAAG;;;;uBAIE,eAAe;8CACQ,QAAQ,CAAC,OAAO,CAAC,IAAI,EAAE,QAAQ,CAAC;;;eAG/D,CAAA;QAEX,MAAM,CAAC,KAAK,CAAC,mBAAmB,EAAE,QAAQ,CAAC,CAAA;QAE3C,uEAAuE;QACvE,MAAM,uBAAuB,GAAG,MAAM,CAAC,OAAO,CAC5C,oBAAoB,EACpB,WAAW,CACT,sBAAsB,EACtB,8DAA8D,CAC/D,EACD,EAAE,GAAG,EAAE,GAAG,IAAI,CAAC,iBAAiB;SACjC,CAAA;QAED,4CAA4C;QAC5C,MAAM,QAAQ,GAAG,oBAAoB,IAAI,mBAAmB,CAAA;QAC5D,GAAG,CAAC,yBAAyB,QAAQ,EAAE,CAAC,CAAA;QACxC,GAAG,CAAC,oEAAoE,CAAC,CAAA;QACzE,MAAM,WAAW,CAAC,QAAQ,CAAC,CAAA;QAE3B,GAAG,CAAC,mEAAmE,CAAC,CAAA;QACxE,MAAM,MAAM,GAAG,MAAM,uBAAuB,CAAA;QAC5C,MAAM,IAAI,GAAG,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAA;QAC/B,IAAI,CAAC,IAAI;YAAE,MAAM,IAAI,KAAK,CAAC,8CAA8C,CAAC,CAAA;QAE1E,oCAAoC;QACpC,GAAG,CAAC,wCAAwC,CAAC,CAAA;QAC7C,MAAM,OAAO,GAAG,MAAM,KAAK,CAAC,wCAAwC,IAAI,cAAc,EAAE;YACtF,MAAM,EAAE,MAAM;YACd,OAAO,EAAE;gBACP,MAAM,EAAE,6BAA6B;gBACrC,sBAAsB,EAAE,YAAY;aACrC;SACF,CAAC,CAAA;QACF,IAAI,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC;YAChB,MAAM,IAAI,KAAK,CAAC,sCAAsC,OAAO,CAAC,MAAM,EAAE,CAAC,CAAA;QACzE,CAAC;QACD,MAAM,IAAI,GAAG,MAAM,OAAO,CAAC,IAAI,EAO9B,CAAA;QAED,MAAM,GAAG;YACP,KAAK,EAAE,IAAI,CAAC,EAAE;YACd,OAAO,EAAE,IAAI,CAAC,IAAI;YAClB,UAAU,EAAE,IAAI,CAAC,GAAG;YACpB,aAAa,EAAE,IAAI,CAAC,cAAc;YAClC,QAAQ,EAAE,IAAI,CAAC,SAAS;YACxB,YAAY,EAAE,IAAI,CAAC,aAAa;SACjC,CAAA;IACH,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,4EAA4E;QAC5E,MAAM,GAAG,CAAA;IACX,CAAC;IAED,+DAA+D;IAC/D,8DAA8D;IAC9D,OAAO,MAAM,CAAA;AACf,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,IAI1C;IACC,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,GAAG,EAAE,GAAG,IAAI,CAAA;IAErC,MAAM,UAAU,GAAG,2BAA2B,kBAAkB,CAAC,OAAO,CAAC,oBAAoB,CAAA;IAC7F,GAAG,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAA;IAC1C,GAAG,CAAC,oEAAoE,CAAC,CAAA;IACzE,MAAM,WAAW,CAAC,UAAU,CAAC,CAAA;IAE7B,GAAG,CAAC,wCAAwC,CAAC,CAAA;IAC7C,MAAM,MAAM,GAAG,MAAM,MAAM,CAAC,OAAO,CACjC,mBAAmB,EACnB,WAAW,CACT,wBAAwB,EACxB,yEAAyE,CAC1E,EACD,EAAE,GAAG,EAAE,GAAG,IAAI,CACf,CAAA;IAED,MAAM,KAAK,GAAG,MAAM,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAA;IAC3C,IAAI,CAAC,KAAK;QAAE,MAAM,IAAI,KAAK,CAAC,mDAAmD,CAAC,CAAA;IAChF,MAAM,EAAE,GAAG,QAAQ,CAAC,KAAK,EAAE,EAAE,CAAC,CAAA;IAC9B,IAAI,KAAK,CAAC,EAAE,CAAC;QAAE,MAAM,IAAI,KAAK,CAAC,4BAA4B,KAAK,EAAE,CAAC,CAAA;IACnE,OAAO,EAAE,CAAA;AACX,CAAC"}
@@ -0,0 +1,3 @@
1
+ export { initProject, validateConfig, printSchema, generateTypes } from './commands.js';
2
+ export type { InitOptions, InitMode, InitCredentials, ValidateOptions, ValidateResult, AirdraftConfigFile, GenerateTypesOptions } from './commands.js';
3
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA;AACvF,YAAY,EAAE,WAAW,EAAE,QAAQ,EAAE,eAAe,EAAE,eAAe,EAAE,cAAc,EAAE,kBAAkB,EAAE,oBAAoB,EAAE,MAAM,eAAe,CAAA"}
package/dist/index.js ADDED
@@ -0,0 +1,3 @@
1
+ // @airdraft/cli — programmatic surface
2
+ export { initProject, validateConfig, printSchema, generateTypes } from './commands.js';
3
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,uCAAuC;AACvC,OAAO,EAAE,WAAW,EAAE,cAAc,EAAE,WAAW,EAAE,aAAa,EAAE,MAAM,eAAe,CAAA"}
package/package.json ADDED
@@ -0,0 +1,54 @@
1
+ {
2
+ "name": "@airdraft/cli",
3
+ "version": "0.1.0",
4
+ "description": "Airdraft CLI — init, validate, migrate",
5
+ "type": "module",
6
+ "main": "./dist/index.js",
7
+ "types": "./dist/index.d.ts",
8
+ "bin": {
9
+ "airdraft": "./dist/bin.js"
10
+ },
11
+ "exports": {
12
+ ".": {
13
+ "import": "./dist/index.js",
14
+ "types": "./dist/index.d.ts"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist",
19
+ "README.md",
20
+ "CHANGELOG.md"
21
+ ],
22
+ "scripts": {
23
+ "build": "tsc",
24
+ "dev": "tsx watch src/bin.ts",
25
+ "clean": "rm -rf dist",
26
+ "test": "vitest run",
27
+ "test:watch": "vitest",
28
+ "typecheck": "tsc --noEmit",
29
+ "prepublishOnly": "npm run build",
30
+ "release": "standard-version",
31
+ "release:patch": "standard-version --release-as patch",
32
+ "release:minor": "standard-version --release-as minor",
33
+ "release:major": "standard-version --release-as major"
34
+ },
35
+ "publishConfig": {
36
+ "access": "public"
37
+ },
38
+ "license": "MIT",
39
+ "devDependencies": {
40
+ "@types/node": "^20.0.0",
41
+ "standard-version": "^9.5.0",
42
+ "tsx": "^4.7.0",
43
+ "typescript": "^5.4.0",
44
+ "vitest": "^1.5.0"
45
+ },
46
+ "dependencies": {
47
+ "@airdraft/core": "*",
48
+ "@airdraft/plugin-auth": "*",
49
+ "commander": "^14.0.3"
50
+ },
51
+ "engines": {
52
+ "node": ">=18.0.0"
53
+ }
54
+ }