@ericminassian/plat 0.0.0-stage → 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.
Files changed (156) hide show
  1. package/dist/api-types.d.ts +7 -0
  2. package/dist/api-types.js +3 -0
  3. package/dist/api-types.js.map +1 -0
  4. package/dist/api.d.ts +123 -0
  5. package/dist/api.js +271 -0
  6. package/dist/api.js.map +1 -0
  7. package/dist/bin.d.ts +2 -0
  8. package/dist/bin.js +4 -0
  9. package/dist/bin.js.map +1 -0
  10. package/dist/build.d.ts +45 -0
  11. package/dist/build.js +188 -0
  12. package/dist/build.js.map +1 -0
  13. package/dist/commands/account.d.ts +2 -0
  14. package/dist/commands/account.js +45 -0
  15. package/dist/commands/account.js.map +1 -0
  16. package/dist/commands/apps.d.ts +2 -0
  17. package/dist/commands/apps.js +75 -0
  18. package/dist/commands/apps.js.map +1 -0
  19. package/dist/commands/common.d.ts +19 -0
  20. package/dist/commands/common.js +43 -0
  21. package/dist/commands/common.js.map +1 -0
  22. package/dist/commands/lifecycle.d.ts +3 -0
  23. package/dist/commands/lifecycle.js +105 -0
  24. package/dist/commands/lifecycle.js.map +1 -0
  25. package/dist/commands/manage.d.ts +2 -0
  26. package/dist/commands/manage.js +103 -0
  27. package/dist/commands/manage.js.map +1 -0
  28. package/dist/commands/observe.d.ts +8 -0
  29. package/dist/commands/observe.js +195 -0
  30. package/dist/commands/observe.js.map +1 -0
  31. package/dist/credentials.d.ts +13 -0
  32. package/dist/credentials.js +42 -0
  33. package/dist/credentials.js.map +1 -0
  34. package/dist/deploy.d.ts +23 -0
  35. package/dist/deploy.js +100 -0
  36. package/dist/deploy.js.map +1 -0
  37. package/dist/dev/crons.d.ts +16 -0
  38. package/dist/dev/crons.js +47 -0
  39. package/dist/dev/crons.js.map +1 -0
  40. package/dist/dev/entries.d.ts +6 -0
  41. package/dist/dev/entries.js +21 -0
  42. package/dist/dev/entries.js.map +1 -0
  43. package/dist/dev/index.d.ts +33 -0
  44. package/dist/dev/index.js +262 -0
  45. package/dist/dev/index.js.map +1 -0
  46. package/dist/dev/local-stage.d.ts +46 -0
  47. package/dist/dev/local-stage.js +116 -0
  48. package/dist/dev/local-stage.js.map +1 -0
  49. package/dist/dev/pretty.d.ts +16 -0
  50. package/dist/dev/pretty.js +91 -0
  51. package/dist/dev/pretty.js.map +1 -0
  52. package/dist/dev/proc.d.ts +7 -0
  53. package/dist/dev/proc.js +16 -0
  54. package/dist/dev/proc.js.map +1 -0
  55. package/dist/dev/router.d.ts +67 -0
  56. package/dist/dev/router.js +184 -0
  57. package/dist/dev/router.js.map +1 -0
  58. package/dist/dev/server-entry.d.ts +1 -0
  59. package/dist/dev/server-entry.js +28 -0
  60. package/dist/dev/server-entry.js.map +1 -0
  61. package/dist/dev/test.d.ts +10 -0
  62. package/dist/dev/test.js +62 -0
  63. package/dist/dev/test.js.map +1 -0
  64. package/dist/dev/worker-host.d.ts +1 -0
  65. package/dist/dev/worker-host.js +67 -0
  66. package/dist/dev/worker-host.js.map +1 -0
  67. package/dist/dev/worker.d.ts +57 -0
  68. package/dist/dev/worker.js +216 -0
  69. package/dist/dev/worker.js.map +1 -0
  70. package/dist/github.d.ts +39 -0
  71. package/dist/github.js +108 -0
  72. package/dist/github.js.map +1 -0
  73. package/dist/index.d.ts +14 -0
  74. package/dist/index.js +15 -0
  75. package/dist/index.js.map +1 -0
  76. package/dist/init.d.ts +23 -0
  77. package/dist/init.js +102 -0
  78. package/dist/init.js.map +1 -0
  79. package/dist/main.d.ts +3 -0
  80. package/dist/main.js +24 -0
  81. package/dist/main.js.map +1 -0
  82. package/dist/project.d.ts +22 -0
  83. package/dist/project.js +81 -0
  84. package/dist/project.js.map +1 -0
  85. package/dist/util/net.d.ts +4 -0
  86. package/dist/util/net.js +33 -0
  87. package/dist/util/net.js.map +1 -0
  88. package/dist/util/output.d.ts +42 -0
  89. package/dist/util/output.js +105 -0
  90. package/dist/util/output.js.map +1 -0
  91. package/dist/util/prompt.d.ts +3 -0
  92. package/dist/util/prompt.js +22 -0
  93. package/dist/util/prompt.js.map +1 -0
  94. package/dist/util/time.d.ts +11 -0
  95. package/dist/util/time.js +29 -0
  96. package/dist/util/time.js.map +1 -0
  97. package/dist/util/zip.d.ts +10 -0
  98. package/dist/util/zip.js +45 -0
  99. package/dist/util/zip.js.map +1 -0
  100. package/package.json +50 -3
  101. package/src/api-types.ts +8 -0
  102. package/src/api.ts +341 -0
  103. package/src/bin.ts +4 -0
  104. package/src/build.ts +255 -0
  105. package/src/commands/account.ts +62 -0
  106. package/src/commands/apps.ts +102 -0
  107. package/src/commands/common.ts +51 -0
  108. package/src/commands/lifecycle.ts +139 -0
  109. package/src/commands/manage.ts +169 -0
  110. package/src/commands/observe.ts +276 -0
  111. package/src/credentials.ts +50 -0
  112. package/src/deploy.ts +138 -0
  113. package/src/dev/crons.ts +70 -0
  114. package/src/dev/entries.ts +23 -0
  115. package/src/dev/index.ts +281 -0
  116. package/src/dev/local-stage.ts +176 -0
  117. package/src/dev/pretty.ts +90 -0
  118. package/src/dev/proc.ts +15 -0
  119. package/src/dev/router.ts +246 -0
  120. package/src/dev/server-entry.ts +21 -0
  121. package/src/dev/test.ts +68 -0
  122. package/src/dev/worker-host.ts +62 -0
  123. package/src/dev/worker.ts +332 -0
  124. package/src/github.ts +121 -0
  125. package/src/index.ts +20 -0
  126. package/src/init.ts +123 -0
  127. package/src/main.ts +28 -0
  128. package/src/project.ts +89 -0
  129. package/src/util/net.ts +33 -0
  130. package/src/util/output.ts +117 -0
  131. package/src/util/prompt.ts +20 -0
  132. package/src/util/time.ts +32 -0
  133. package/src/util/zip.ts +46 -0
  134. package/template/.github/workflows/platform.yml +24 -0
  135. package/template/AGENTS.md +134 -0
  136. package/template/CLAUDE.md +1 -0
  137. package/template/README.md +13 -0
  138. package/template/_gitignore +8 -0
  139. package/template/package.json +31 -0
  140. package/template/platform.json +18 -0
  141. package/template/src/server.ts +100 -0
  142. package/template/src/types.ts +21 -0
  143. package/template/src/worker.ts +32 -0
  144. package/template/test/server.test.ts +120 -0
  145. package/template/test/todos.integration.test.ts +30 -0
  146. package/template/tsconfig.json +18 -0
  147. package/template/vitest.config.ts +9 -0
  148. package/template/vitest.integration.config.ts +10 -0
  149. package/template/web/index.html +12 -0
  150. package/template/web/src/App.tsx +102 -0
  151. package/template/web/src/api.ts +11 -0
  152. package/template/web/src/main.tsx +10 -0
  153. package/template/web/src/styles.css +102 -0
  154. package/template/web/tsconfig.json +18 -0
  155. package/template/web/vite.config.ts +19 -0
  156. package/README.md +0 -3
package/dist/build.js ADDED
@@ -0,0 +1,188 @@
1
+ import { spawn } from 'node:child_process';
2
+ import { existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
3
+ import { delimiter, join, resolve } from 'node:path';
4
+ import { build as esbuild } from 'esbuild';
5
+ import { cliVersion, loadProject } from './project.js';
6
+ import { CliError, EXIT, step } from './util/output.js';
7
+ import { dirExists, zipDirectory } from './util/zip.js';
8
+ export const SDK_SERVER = '@ericminassian/platform/server';
9
+ export const SDK_WORKER = '@ericminassian/platform/worker';
10
+ /**
11
+ * Builds an app into deployable artifacts:
12
+ * - `server.zip` → `index.mjs` (+ map): the app's fetch handler wrapped by the SDK server
13
+ * - `worker.zip` → `index.mjs` (+ map): `export const handler` for the worker Lambda
14
+ * - `static.zip` → the built frontend
15
+ * - `manifest.json` → `{ manifest, resolved, build }`
16
+ */
17
+ export async function buildApp(opts) {
18
+ const project = loadProject(opts.cwd);
19
+ const { root, manifest, raw } = project;
20
+ const outDir = resolve(opts.outDir ?? join(root, '.plat', 'build'));
21
+ const want = (part) => !opts.only || opts.only.includes(part);
22
+ const log = opts.quiet ? () => { } : step;
23
+ validateForBuild(root, manifest);
24
+ rmSync(outDir, { recursive: true, force: true });
25
+ mkdirSync(outDir, { recursive: true });
26
+ const files = {};
27
+ const plugins = opts.resolveOverrides ? [overridePlugin(opts.resolveOverrides)] : [];
28
+ const minify = opts.minify ?? true;
29
+ if (manifest.web?.server && want('server')) {
30
+ log('bundling server');
31
+ const entry = resolve(root, manifest.web.server);
32
+ const dir = await bundle({
33
+ root,
34
+ outDir: join(outDir, 'server'),
35
+ contents: `import handler from ${JSON.stringify(entry)};\nimport { startServer } from ${JSON.stringify(SDK_SERVER)};\nawait startServer(handler);\n`,
36
+ plugins,
37
+ minify,
38
+ });
39
+ files['server.zip'] = writeZip(outDir, 'server.zip', zipDirectory(dir));
40
+ }
41
+ if (manifest.worker && want('worker')) {
42
+ log('bundling worker');
43
+ const dir = await bundleWorker(root, manifest, join(outDir, 'worker'), { plugins, minify });
44
+ files['worker.zip'] = writeZip(outDir, 'worker.zip', zipDirectory(dir));
45
+ }
46
+ if (manifest.web?.static && want('static')) {
47
+ if (manifest.web.build && !opts.skipWebBuild) {
48
+ log(`building frontend: ${manifest.web.build}`);
49
+ await runCommand(manifest.web.build, root);
50
+ }
51
+ const staticDir = resolve(root, manifest.web.static);
52
+ if (!dirExists(staticDir)) {
53
+ throw new CliError(`web.static directory ${manifest.web.static} does not exist`, {
54
+ hint: manifest.web.build
55
+ ? 'check that web.build writes to web.static'
56
+ : 'add a web.build command or build the frontend first',
57
+ exitCode: EXIT.usage,
58
+ });
59
+ }
60
+ if (!existsSync(join(staticDir, 'index.html')) && manifest.web.spa) {
61
+ throw new CliError(`${manifest.web.static}/index.html is missing but web.spa is true`, {
62
+ exitCode: EXIT.usage,
63
+ });
64
+ }
65
+ files['static.zip'] = writeZip(outDir, 'static.zip', zipDirectory(staticDir));
66
+ }
67
+ const manifestPath = join(outDir, 'manifest.json');
68
+ writeFileSync(manifestPath, `${JSON.stringify({
69
+ manifest: raw,
70
+ resolved: manifest,
71
+ build: {
72
+ cli: cliVersion(),
73
+ builtAt: new Date().toISOString(),
74
+ files: Object.keys(files),
75
+ },
76
+ }, null, 2)}\n`);
77
+ files['manifest.json'] = manifestPath;
78
+ return { manifest, files };
79
+ }
80
+ /** Bundle just the worker into `outDir/index.mjs` (used by build and `plat dev`). */
81
+ export async function bundleWorker(root, manifest, outDir, opts = {}) {
82
+ if (!manifest.worker)
83
+ throw new Error('manifest has no worker');
84
+ const entry = resolve(root, manifest.worker.entry);
85
+ return bundle({
86
+ root,
87
+ outDir,
88
+ contents: `import def from ${JSON.stringify(entry)};\nimport { createWorkerHandler } from ${JSON.stringify(SDK_WORKER)};\nexport const handler = createWorkerHandler(def);\n`,
89
+ plugins: opts.plugins ?? [],
90
+ minify: opts.minify ?? true,
91
+ });
92
+ }
93
+ /** Zip of a bundled directory, for UpdateFunctionCode. */
94
+ export function zipBundle(dir) {
95
+ return zipDirectory(dir);
96
+ }
97
+ export function validateForBuild(root, manifest) {
98
+ const problems = [];
99
+ if (manifest.auth.enabled && !manifest.web?.server)
100
+ problems.push('auth needs web.server (sign-in routes run in the server)');
101
+ if (manifest.web?.server && !existsSync(resolve(root, manifest.web.server))) {
102
+ problems.push(`web.server entry ${manifest.web.server} does not exist`);
103
+ }
104
+ if (manifest.worker && !existsSync(resolve(root, manifest.worker.entry))) {
105
+ problems.push(`worker entry ${manifest.worker.entry} does not exist (needed for ${describeWorkerNeeds(manifest)})`);
106
+ }
107
+ if (problems.length)
108
+ throw new CliError(`can't build ${manifest.name}:\n - ${problems.join('\n - ')}`, {
109
+ exitCode: EXIT.usage,
110
+ });
111
+ }
112
+ function describeWorkerNeeds(m) {
113
+ const parts = [
114
+ ...Object.keys(m.queues).map((q) => `queue ${q}`),
115
+ ...m.events.map((e) => `event ${e}`),
116
+ ...Object.keys(m.crons).map((c) => `cron ${c}`),
117
+ ];
118
+ return parts.join(', ') || 'worker';
119
+ }
120
+ async function bundle(o) {
121
+ mkdirSync(o.outDir, { recursive: true });
122
+ try {
123
+ await esbuild({
124
+ stdin: { contents: o.contents, resolveDir: o.root, sourcefile: 'platform-entry.ts', loader: 'ts' },
125
+ outfile: join(o.outDir, 'index.mjs'),
126
+ bundle: true,
127
+ platform: 'node',
128
+ format: 'esm',
129
+ target: 'node24',
130
+ minify: o.minify,
131
+ sourcemap: 'external',
132
+ sourcesContent: false,
133
+ legalComments: 'none',
134
+ logLevel: 'silent',
135
+ // ESM bundles of CJS dependencies still call require(). process.getBuiltinModule
136
+ // (not a static `import 'node:module'`) keeps the bundle loadable in runtimes
137
+ // without node:module, such as the AWS Emulator's Lambda sandbox.
138
+ banner: {
139
+ js: "const require = globalThis.process?.getBuiltinModule?.('module')?.createRequire(import.meta.url);",
140
+ },
141
+ plugins: o.plugins,
142
+ absWorkingDir: o.root,
143
+ });
144
+ }
145
+ catch (err) {
146
+ const errors = err.errors;
147
+ const detail = errors
148
+ ?.map((e) => (e.location ? `${e.location.file}:${e.location.line}: ${e.text}` : e.text))
149
+ .join('\n - ');
150
+ throw new CliError(`bundling failed${detail ? `:\n - ${detail}` : `: ${err.message}`}`);
151
+ }
152
+ return o.outDir;
153
+ }
154
+ function overridePlugin(map) {
155
+ const keys = Object.keys(map);
156
+ const filter = new RegExp(`^(${keys.map((k) => k.replace(/[.*+?^${}()|[\]\\/]/g, '\\$&')).join('|')})$`);
157
+ return {
158
+ name: 'plat-resolve-overrides',
159
+ setup(b) {
160
+ b.onResolve({ filter }, (args) => ({ path: map[args.path] }));
161
+ },
162
+ };
163
+ }
164
+ function writeZip(outDir, name, data) {
165
+ const p = join(outDir, name);
166
+ writeFileSync(p, data);
167
+ return p;
168
+ }
169
+ /** Run a manifest shell command with the app's `node_modules/.bin` on PATH. */
170
+ export function runCommand(command, cwd, env = process.env) {
171
+ return new Promise((resolvePromise, reject) => {
172
+ const child = spawn(command, {
173
+ cwd,
174
+ shell: true,
175
+ stdio: ['ignore', 'inherit', 'inherit'],
176
+ env: withLocalBin(cwd, env),
177
+ });
178
+ child.once('exit', (code) => code === 0 ? resolvePromise() : reject(new CliError(`\`${command}\` exited with code ${code}`)));
179
+ child.once('error', reject);
180
+ });
181
+ }
182
+ export function withLocalBin(cwd, env = process.env) {
183
+ return { ...env, PATH: [join(cwd, 'node_modules', '.bin'), env.PATH ?? ''].join(delimiter) };
184
+ }
185
+ export function readBuildManifest(outDir) {
186
+ return JSON.parse(readFileSync(join(outDir, 'manifest.json'), 'utf8'));
187
+ }
188
+ //# sourceMappingURL=build.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"build.js","sourceRoot":"","sources":["../src/build.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import { type Command } from 'commander';
2
+ export declare function registerAccount(program: Command): void;
@@ -0,0 +1,45 @@
1
+ import { spawnSync } from 'node:child_process';
2
+ import { Option } from 'commander';
3
+ import pc from 'picocolors';
4
+ import { ApiClient, apiBaseUrl } from '../api.js';
5
+ import { clearCredentials, credentialsPath, loadCredentials, saveCredentials } from '../credentials.js';
6
+ import { CliError, EXIT, result, success } from '../util/output.js';
7
+ import { action, apiFor, withCommon } from './common.js';
8
+ export function registerAccount(program) {
9
+ withCommon(program
10
+ .command('login')
11
+ .description('sign in to the platform with your GitHub identity (uses `gh auth token`)')
12
+ .addOption(new Option('--github-token <token>', 'GitHub token to use instead of `gh auth token`').env('PLAT_GITHUB_TOKEN'))).action(action(async (opts) => {
13
+ const baseUrl = opts.apiUrl ?? apiBaseUrl();
14
+ const githubToken = opts.githubToken ?? ghToken();
15
+ const api = new ApiClient({ baseUrl, auth: 'none' });
16
+ const res = await api.login({ githubToken });
17
+ saveCredentials({ apiUrl: baseUrl, token: res.token, github: res.github, expiresAt: res.expiresAt });
18
+ result({ github: res.github, role: res.role, expiresAt: res.expiresAt, apiUrl: baseUrl }, (r) => {
19
+ success(`signed in as ${pc.bold(r.github)} (${r.role}) until ${r.expiresAt}`);
20
+ return undefined;
21
+ });
22
+ }));
23
+ withCommon(program.command('logout').description('forget the stored platform login')).action(action(async () => {
24
+ const removed = clearCredentials();
25
+ result({ loggedOut: removed, path: credentialsPath() }, (r) => r.loggedOut ? 'logged out' : 'not logged in');
26
+ }));
27
+ withCommon(program.command('whoami').description('show the signed-in platform member')).action(action(async (opts) => {
28
+ const me = await apiFor(opts).me();
29
+ const stored = loadCredentials();
30
+ result({ ...me, expiresAt: stored?.expiresAt }, (r) => `${pc.bold(r.github)} (${r.role})`);
31
+ }));
32
+ }
33
+ function ghToken() {
34
+ const env = process.env.GH_TOKEN || process.env.GITHUB_TOKEN;
35
+ const r = spawnSync('gh', ['auth', 'token'], { encoding: 'utf8' });
36
+ const token = r.status === 0 ? r.stdout.trim() : env;
37
+ if (!token) {
38
+ throw new CliError('could not get a GitHub token', {
39
+ hint: 'install the GitHub CLI and run `gh auth login`, or pass --github-token',
40
+ exitCode: EXIT.auth,
41
+ });
42
+ }
43
+ return token;
44
+ }
45
+ //# sourceMappingURL=account.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"account.js","sourceRoot":"","sources":["../../src/commands/account.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerApps(program: Command): void;
@@ -0,0 +1,75 @@
1
+ import { validateAppName } from '@ericminassian/platform-core';
2
+ import pc from 'picocolors';
3
+ import { CliError, EXIT, result, table } from '../util/output.js';
4
+ import { confirmByTyping } from '../util/prompt.js';
5
+ import { shortTime } from '../util/time.js';
6
+ import { action, apiFor, withCommon } from './common.js';
7
+ export function registerApps(program) {
8
+ const apps = program
9
+ .command('apps')
10
+ .description('register and inspect apps (repos are created by you, not the CLI)');
11
+ withCommon(apps
12
+ .command('create <name>')
13
+ .description('register an app with the platform')
14
+ .requiredOption('--repo <owner/name>', 'GitHub repository whose CI may deploy this app')
15
+ .option('--description <text>', 'one-line description')).action(action(async (name, opts) => {
16
+ const err = validateAppName(name);
17
+ if (err)
18
+ throw new CliError(err, { exitCode: EXIT.usage });
19
+ if (!/^[A-Za-z0-9_.-]+\/[A-Za-z0-9_.-]+$/.test(opts.repo)) {
20
+ throw new CliError(`--repo must look like owner/name, got "${opts.repo}"`, { exitCode: EXIT.usage });
21
+ }
22
+ const app = await apiFor(opts).createApp({
23
+ name,
24
+ repo: opts.repo,
25
+ ...(opts.description ? { description: opts.description } : {}),
26
+ });
27
+ result(app, (a) => [
28
+ `${pc.green('✓')} registered ${pc.bold(a.name)} (deploys from ${a.repo})`,
29
+ '',
30
+ ' next:',
31
+ ' 1. push the repo with the platform workflow (.github/workflows/platform.yml)',
32
+ ` 2. merging to main deploys https://${a.name}.<domain>; PRs get previews`,
33
+ ].join('\n'));
34
+ }));
35
+ withCommon(apps.command('list').description('list apps you can see')).action(action(async (opts) => {
36
+ const list = await apiFor(opts).listApps();
37
+ result(list, (l) => table(l.map((s) => ({
38
+ app: s.app.name,
39
+ repo: s.app.repo,
40
+ stages: s.stages.map((st) => st.stage).join(','),
41
+ up: s.health?.up === null || s.health === null
42
+ ? '-'
43
+ : s.health.up
44
+ ? pc.green('up')
45
+ : pc.red('down'),
46
+ 'req/min': s.health?.reqPerMin ?? '-',
47
+ p95: s.health?.p95 != null ? `${s.health.p95}ms` : '-',
48
+ 'cost MTD': s.costMonthToDateUsd != null ? `$${s.costMonthToDateUsd.toFixed(2)}` : '-',
49
+ }))));
50
+ }));
51
+ withCommon(apps.command('show <name>').description('app details, stages and health')).action(action(async (name, opts) => {
52
+ const s = await apiFor(opts).getApp(name);
53
+ result(s, (v) => [
54
+ `${pc.bold(v.app.name)} ${pc.dim(v.app.description ?? '')}`,
55
+ `repo: ${v.app.repo} owners: ${v.app.owners.join(', ')} created: ${shortTime(v.app.createdAt)}`,
56
+ '',
57
+ table(v.stages.map((st) => ({
58
+ stage: st.stage,
59
+ status: st.status,
60
+ url: st.url,
61
+ deployment: st.currentDeployment ?? '',
62
+ updated: shortTime(st.updatedAt),
63
+ }))),
64
+ ].join('\n'));
65
+ }));
66
+ withCommon(apps
67
+ .command('delete <name>')
68
+ .description('unregister an app (destroy its stages first)')
69
+ .option('--yes', 'skip the confirmation prompt')).action(action(async (name, opts) => {
70
+ await confirmByTyping(`unregister ${name}?`, name, opts.yes);
71
+ await apiFor(opts).deleteApp(name);
72
+ result({ app: name, deleted: true }, () => `${pc.green('✓')} unregistered ${name}`);
73
+ }));
74
+ }
75
+ //# sourceMappingURL=apps.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"apps.js","sourceRoot":"","sources":["../../src/commands/apps.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import { type Command } from 'commander';
2
+ import { ApiClient } from '../api.ts';
3
+ export interface CommonOpts {
4
+ json?: boolean;
5
+ apiUrl?: string;
6
+ app?: string;
7
+ stage?: string;
8
+ }
9
+ /** `--json` and `--api-url` on every command. */
10
+ export declare function withCommon(cmd: Command): Command;
11
+ /** `--app` (defaults to platform.json) and `--stage` (defaults to prod). */
12
+ export declare function withTarget(cmd: Command, stageDefault?: string | false): Command;
13
+ export declare function apiFor(opts: CommonOpts): ApiClient;
14
+ export declare function appFor(opts: CommonOpts): string;
15
+ /**
16
+ * Wraps a command action: applies `--json`, turns errors into a concise
17
+ * message + hint and a meaningful exit code.
18
+ */
19
+ export declare function action<A extends unknown[]>(fn: (...args: A) => Promise<void> | void): (...args: A) => Promise<void>;
@@ -0,0 +1,43 @@
1
+ import { Option } from 'commander';
2
+ import { ApiClient } from '../api.js';
3
+ import { resolveAppName } from '../project.js';
4
+ import { reportError, setJsonMode } from '../util/output.js';
5
+ /** `--json` and `--api-url` on every command. */
6
+ export function withCommon(cmd) {
7
+ return cmd
8
+ .option('--json', 'machine-readable JSON output on stdout')
9
+ .addOption(new Option('--api-url <url>', 'platform API base URL').env('PLATFORM_API_URL'));
10
+ }
11
+ /** `--app` (defaults to platform.json) and `--stage` (defaults to prod). */
12
+ export function withTarget(cmd, stageDefault = 'prod') {
13
+ cmd.option('--app <name>', 'app name (default: from platform.json)');
14
+ if (stageDefault)
15
+ cmd.option('--stage <stage>', 'stage', stageDefault);
16
+ else
17
+ cmd.option('--stage <stage>', 'stage');
18
+ return withCommon(cmd);
19
+ }
20
+ export function apiFor(opts) {
21
+ return new ApiClient(opts.apiUrl ? { baseUrl: opts.apiUrl } : {});
22
+ }
23
+ export function appFor(opts) {
24
+ return resolveAppName(opts.app);
25
+ }
26
+ /**
27
+ * Wraps a command action: applies `--json`, turns errors into a concise
28
+ * message + hint and a meaningful exit code.
29
+ */
30
+ export function action(fn) {
31
+ return async (...args) => {
32
+ const cmd = args[args.length - 1];
33
+ const opts = (typeof cmd?.optsWithGlobals === 'function' ? cmd.optsWithGlobals() : {});
34
+ setJsonMode(!!opts.json);
35
+ try {
36
+ await fn(...args);
37
+ }
38
+ catch (err) {
39
+ process.exitCode = reportError(err);
40
+ }
41
+ };
42
+ }
43
+ //# sourceMappingURL=common.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"common.js","sourceRoot":"","sources":["../../src/commands/common.ts"],"names":[],"mappings":"AAAA,OAAO,EAAgB,MAAM,EAAE,MAAM,WAAW,CAAC;AACjD,OAAO,EAAE,SAAS,EAAE,MAAM,WAAW,CAAC;AACtC,OAAO,EAAE,cAAc,EAAE,MAAM,eAAe,CAAC;AAC/C,OAAO,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAS7D,iDAAiD;AACjD,MAAM,UAAU,UAAU,CAAC,GAAY;IACrC,OAAO,GAAG;SACP,MAAM,CAAC,QAAQ,EAAE,wCAAwC,CAAC;SAC1D,SAAS,CAAC,IAAI,MAAM,CAAC,iBAAiB,EAAE,uBAAuB,CAAC,CAAC,GAAG,CAAC,kBAAkB,CAAC,CAAC,CAAC;AAC/F,CAAC;AAED,4EAA4E;AAC5E,MAAM,UAAU,UAAU,CAAC,GAAY,EAAE,YAAY,GAAmB,MAAM;IAC5E,GAAG,CAAC,MAAM,CAAC,cAAc,EAAE,wCAAwC,CAAC,CAAC;IACrE,IAAI,YAAY;QAAE,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;;QAClE,GAAG,CAAC,MAAM,CAAC,iBAAiB,EAAE,OAAO,CAAC,CAAC;IAC5C,OAAO,UAAU,CAAC,GAAG,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAgB;IACrC,OAAO,IAAI,SAAS,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,OAAO,EAAE,IAAI,CAAC,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC;AACpE,CAAC;AAED,MAAM,UAAU,MAAM,CAAC,IAAgB;IACrC,OAAO,cAAc,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;AAClC,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,MAAM,CAAsB,EAAwC;IAClF,OAAO,KAAK,EAAE,GAAG,IAAO,EAAE,EAAE;QAC1B,MAAM,GAAG,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAY,CAAC;QAC7C,MAAM,IAAI,GAAG,CAAC,OAAO,GAAG,EAAE,eAAe,KAAK,UAAU,CAAC,CAAC,CAAC,GAAG,CAAC,eAAe,EAAE,CAAC,CAAC,CAAC,EAAE,CAAe,CAAC;QACrG,WAAW,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACzB,IAAI,CAAC;YACH,MAAM,EAAE,CAAC,GAAG,IAAI,CAAC,CAAC;QACpB,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,OAAO,CAAC,QAAQ,GAAG,WAAW,CAAC,GAAG,CAAC,CAAC;QACtC,CAAC;IACH,CAAC,CAAC;AACJ,CAAC"}
@@ -0,0 +1,3 @@
1
+ import { type Command } from 'commander';
2
+ export declare function registerLifecycle(program: Command): void;
3
+ export declare function parsePort(v: string): number;
@@ -0,0 +1,105 @@
1
+ import { relative } from 'node:path';
2
+ import { PLATFORM_DEFAULTS } from '@ericminassian/platform-core';
3
+ import { Option } from 'commander';
4
+ import pc from 'picocolors';
5
+ import { initApp } from '../init.js';
6
+ import { CliError, EXIT, result, success } from '../util/output.js';
7
+ import { action, apiFor, withCommon } from './common.js';
8
+ export function registerLifecycle(program) {
9
+ withCommon(program
10
+ .command('init [dir]')
11
+ .description('scaffold a new app from the template (local files only; create the GitHub repo yourself)')
12
+ .option('--name <app>', 'app name (default: directory name)')
13
+ .option('--force', 'write into a non-empty directory')).action(action(async (dir, opts) => {
14
+ const target = dir ?? opts.name ?? '.';
15
+ const r = initApp({
16
+ dir: target,
17
+ ...(opts.name ? { name: opts.name } : {}),
18
+ ...(opts.force ? { force: true } : {}),
19
+ });
20
+ const rel = relative(process.cwd(), r.dir) || '.';
21
+ result(r, (v) => [
22
+ `${pc.green('✓')} created ${pc.bold(v.name)} in ${rel} (${v.files.length} files)`,
23
+ '',
24
+ ' next:',
25
+ rel === '.' ? '' : ` cd ${rel}`,
26
+ ' pnpm install',
27
+ ' pnpm dev # local, on the AWS Emulator',
28
+ ` gh repo create <owner>/${v.name} --private --source . --push`,
29
+ ` plat apps create ${v.name} --repo <owner>/${v.name}`,
30
+ ]
31
+ .filter(Boolean)
32
+ .join('\n'));
33
+ }));
34
+ withCommon(program
35
+ .command('build')
36
+ .description('bundle the app into deployable artifacts (.plat/build)')
37
+ .option('--out <dir>', 'output directory')
38
+ .option('--no-minify', 'skip minification')).action(action(async (opts) => {
39
+ const { buildApp } = await import('../build.js');
40
+ const r = await buildApp({
41
+ cwd: process.cwd(),
42
+ ...(opts.out ? { outDir: opts.out } : {}),
43
+ minify: opts.minify,
44
+ });
45
+ result({ app: r.manifest.name, files: r.files }, (v) => {
46
+ success(`built ${v.app}`);
47
+ return Object.entries(v.files)
48
+ .map(([k, p]) => ` ${k.padEnd(14)} ${relative(process.cwd(), p)}`)
49
+ .join('\n');
50
+ });
51
+ }));
52
+ withCommon(program
53
+ .command('deploy')
54
+ .description('build and deploy (CI derives the stage: PR → pr-<n>, main → prod)')
55
+ .option('--stage <stage>', 'target stage (required outside CI)')
56
+ .option('--no-wait', "don't wait for the deployment to finish")).action(action(async (opts) => {
57
+ const { deploy } = await import('../deploy.js');
58
+ const r = await deploy(apiFor(opts), {
59
+ cwd: process.cwd(),
60
+ ...(opts.stage ? { stage: opts.stage } : {}),
61
+ wait: opts.wait,
62
+ });
63
+ result({ deployment: r.deployment, url: r.url }, (v) => (v.url ? v.url : undefined));
64
+ }));
65
+ const dev = withCommon(program
66
+ .command('dev')
67
+ .description('run the app locally against the AWS Emulator')
68
+ .addOption(new Option('--port <port>', 'local router port')
69
+ .default(String(PLATFORM_DEFAULTS.localPort))
70
+ .env('PLAT_DEV_PORT'))
71
+ .option('--spans', 'also print trace spans (db, queue, fetch calls)')).action(action(async (opts) => {
72
+ const { runDev } = await import('../dev/index.js');
73
+ await runDev({
74
+ cwd: process.cwd(),
75
+ port: parsePort(opts.port),
76
+ ...(opts.spans ? { spans: true } : {}),
77
+ });
78
+ }));
79
+ withCommon(dev
80
+ .command('run-cron <name>')
81
+ .description('fire a cron now in a running `plat dev` (same --port as `plat dev`)')).action(action(async (name, _opts, cmd) => {
82
+ // `--port` belongs to `plat dev` (the parent); commander parses it there.
83
+ const port = cmd.parent?.opts()?.port ?? String(PLATFORM_DEFAULTS.localPort);
84
+ const { runCronOnDev } = await import('../dev/index.js');
85
+ await runCronOnDev(name, parsePort(port));
86
+ result({ cron: name, triggered: true }, () => `${pc.green('✓')} ran ${name}`);
87
+ }));
88
+ withCommon(program
89
+ .command('test')
90
+ .description('run integration tests against a throwaway AWS Emulator with this app provisioned')
91
+ .argument('[vitestArgs...]', 'extra arguments for vitest')
92
+ .allowUnknownOption()).action(action(async (vitestArgs) => {
93
+ const { runTests } = await import('../dev/test.js');
94
+ const code = await runTests({ cwd: process.cwd(), args: vitestArgs ?? [] });
95
+ if (code !== 0)
96
+ throw new CliError(`tests failed (vitest exit ${code})`, { exitCode: code });
97
+ }));
98
+ }
99
+ export function parsePort(v) {
100
+ const n = Number(v);
101
+ if (!Number.isInteger(n) || n <= 0 || n > 65535)
102
+ throw new CliError(`invalid port ${v}`, { exitCode: EXIT.usage });
103
+ return n;
104
+ }
105
+ //# sourceMappingURL=lifecycle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"lifecycle.js","sourceRoot":"","sources":["../../src/commands/lifecycle.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ import type { Command } from 'commander';
2
+ export declare function registerManage(program: Command): void;