@ericminassian/plat 0.0.0-stage → 0.2.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 (160) 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 +48 -0
  11. package/dist/build.js +185 -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 +106 -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 +30 -0
  77. package/dist/init.js +114 -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 +21 -0
  83. package/dist/project.js +138 -0
  84. package/dist/project.js.map +1 -0
  85. package/dist/util/esbuild.d.ts +2 -0
  86. package/dist/util/esbuild.js +9 -0
  87. package/dist/util/esbuild.js.map +1 -0
  88. package/dist/util/net.d.ts +4 -0
  89. package/dist/util/net.js +33 -0
  90. package/dist/util/net.js.map +1 -0
  91. package/dist/util/output.d.ts +42 -0
  92. package/dist/util/output.js +105 -0
  93. package/dist/util/output.js.map +1 -0
  94. package/dist/util/prompt.d.ts +3 -0
  95. package/dist/util/prompt.js +22 -0
  96. package/dist/util/prompt.js.map +1 -0
  97. package/dist/util/time.d.ts +11 -0
  98. package/dist/util/time.js +29 -0
  99. package/dist/util/time.js.map +1 -0
  100. package/dist/util/zip.d.ts +10 -0
  101. package/dist/util/zip.js +45 -0
  102. package/dist/util/zip.js.map +1 -0
  103. package/package.json +50 -3
  104. package/src/api-types.ts +8 -0
  105. package/src/api.ts +341 -0
  106. package/src/bin.ts +4 -0
  107. package/src/build.ts +252 -0
  108. package/src/commands/account.ts +62 -0
  109. package/src/commands/apps.ts +102 -0
  110. package/src/commands/common.ts +51 -0
  111. package/src/commands/lifecycle.ts +140 -0
  112. package/src/commands/manage.ts +169 -0
  113. package/src/commands/observe.ts +276 -0
  114. package/src/credentials.ts +50 -0
  115. package/src/deploy.ts +138 -0
  116. package/src/dev/crons.ts +70 -0
  117. package/src/dev/entries.ts +23 -0
  118. package/src/dev/index.ts +281 -0
  119. package/src/dev/local-stage.ts +176 -0
  120. package/src/dev/pretty.ts +90 -0
  121. package/src/dev/proc.ts +15 -0
  122. package/src/dev/router.ts +246 -0
  123. package/src/dev/server-entry.ts +21 -0
  124. package/src/dev/test.ts +68 -0
  125. package/src/dev/worker-host.ts +62 -0
  126. package/src/dev/worker.ts +332 -0
  127. package/src/github.ts +121 -0
  128. package/src/index.ts +20 -0
  129. package/src/init.ts +136 -0
  130. package/src/main.ts +28 -0
  131. package/src/project.ts +143 -0
  132. package/src/util/esbuild.ts +10 -0
  133. package/src/util/net.ts +33 -0
  134. package/src/util/output.ts +117 -0
  135. package/src/util/prompt.ts +20 -0
  136. package/src/util/time.ts +32 -0
  137. package/src/util/zip.ts +46 -0
  138. package/template/.github/workflows/platform.yml +24 -0
  139. package/template/AGENTS.md +139 -0
  140. package/template/CLAUDE.md +1 -0
  141. package/template/README.md +13 -0
  142. package/template/_gitignore +8 -0
  143. package/template/package.json +31 -0
  144. package/template/plat.config.ts +31 -0
  145. package/template/src/server.ts +100 -0
  146. package/template/src/types.ts +21 -0
  147. package/template/src/worker.ts +32 -0
  148. package/template/test/server.test.ts +120 -0
  149. package/template/test/todos.integration.test.ts +30 -0
  150. package/template/tsconfig.json +18 -0
  151. package/template/vitest.config.ts +9 -0
  152. package/template/vitest.integration.config.ts +10 -0
  153. package/template/web/index.html +12 -0
  154. package/template/web/src/App.tsx +102 -0
  155. package/template/web/src/api.ts +11 -0
  156. package/template/web/src/main.tsx +10 -0
  157. package/template/web/src/styles.css +102 -0
  158. package/template/web/tsconfig.json +18 -0
  159. package/template/web/vite.config.ts +19 -0
  160. package/README.md +0 -3
@@ -0,0 +1,103 @@
1
+ import { ENV_NAME_PATTERN, PROD_STAGE } from '@ericminassian/platform-core';
2
+ import pc from 'picocolors';
3
+ import { CliError, EXIT, result, table } from '../util/output.js';
4
+ import { confirmByTyping, prompt } from '../util/prompt.js';
5
+ import { shortTime } from '../util/time.js';
6
+ import { action, apiFor, appFor, withTarget } from './common.js';
7
+ import { readStdin } from './observe.js';
8
+ export function registerManage(program) {
9
+ // ------------------------------------------------------------ secrets
10
+ const secrets = program.command('secrets').description('app secrets (values never shown)');
11
+ withTarget(secrets.command('list').description('secret names for a stage (and shared ones)')).action(action(async (opts) => {
12
+ const list = await apiFor(opts).listSecrets(await appFor(opts), { stage: opts.stage });
13
+ result(list, (l) => table(l.map((s) => ({
14
+ name: s.name,
15
+ scope: s.scope,
16
+ stage: s.stage ?? '',
17
+ updated: s.updatedAt ? shortTime(s.updatedAt) : '',
18
+ }))));
19
+ }));
20
+ withTarget(secrets
21
+ .command('set <name> [value]')
22
+ .description('set a secret (value from the argument or stdin)')
23
+ .option('--shared', 'app-wide: every stage without its own value uses it')).action(action(async (name, value, opts) => {
24
+ checkSecretName(name);
25
+ const v = value ?? (process.stdin.isTTY ? await prompt(`value for ${name}: `) : readStdin());
26
+ if (!v)
27
+ throw new CliError('empty secret value', { exitCode: EXIT.usage });
28
+ const info = await apiFor(opts).setSecret(await appFor(opts), name, opts.shared ? { value: v, shared: true } : { value: v, stage: opts.stage });
29
+ result(info, () => `${pc.green('✓')} set ${name} (${opts.shared ? 'shared' : opts.stage}); new value applies within ~5 minutes`);
30
+ }));
31
+ withTarget(secrets
32
+ .command('rm <name>')
33
+ .description('delete a secret')
34
+ .option('--shared', 'delete the app-wide value')).action(action(async (name, opts) => {
35
+ checkSecretName(name);
36
+ await apiFor(opts).deleteSecret(await appFor(opts), name, opts.shared ? { shared: true } : { stage: opts.stage });
37
+ result({ deleted: name }, () => `${pc.green('✓')} deleted ${name}`);
38
+ }));
39
+ // ------------------------------------------------------------ deployments & stages
40
+ withTarget(program.command('deployments').description('recent deployments'), false).action(action(async (opts) => {
41
+ const list = await apiFor(opts).listDeployments(await appFor(opts), opts.stage);
42
+ result(list, (l) => table(l.map((d) => ({
43
+ id: d.id,
44
+ stage: d.stage,
45
+ status: d.status === 'succeeded'
46
+ ? pc.green(d.status)
47
+ : d.status === 'failed'
48
+ ? pc.red(d.status)
49
+ : d.status,
50
+ commit: d.commit?.slice(0, 7) ?? '',
51
+ message: (d.message ?? '').slice(0, 50),
52
+ by: d.actor,
53
+ at: shortTime(d.createdAt),
54
+ }))));
55
+ }));
56
+ withTarget(program.command('stages').description('stages of an app'), false).action(action(async (opts) => {
57
+ const list = await apiFor(opts).listStages(await appFor(opts));
58
+ result(list, (l) => table(l.map((s) => ({
59
+ stage: s.stage,
60
+ status: s.status,
61
+ url: s.url,
62
+ deployment: s.currentDeployment ?? '',
63
+ updated: shortTime(s.updatedAt),
64
+ }))));
65
+ }));
66
+ withTarget(program
67
+ .command('rollback')
68
+ .description('point a stage back at its previous deployment (instant)')
69
+ .option('--to <deploymentId>', 'a specific earlier deployment')).action(action(async (opts) => {
70
+ const r = await apiFor(opts).rollback(await appFor(opts), opts.stage, opts.to);
71
+ result(r, () => `${pc.green('✓')} rolled back ${opts.stage}`);
72
+ }));
73
+ withTarget(program
74
+ .command('destroy')
75
+ .description('delete a stage and its resources')
76
+ .option('--yes', 'skip the confirmation prompt')
77
+ .option('--force', 'required to destroy prod'), false).action(action(async (opts) => {
78
+ if (!opts.stage)
79
+ throw new CliError('--stage is required', { exitCode: EXIT.usage });
80
+ if (opts.stage === PROD_STAGE && !opts.force) {
81
+ throw new CliError('refusing to destroy prod', {
82
+ hint: 'pass --force if you really mean it',
83
+ exitCode: EXIT.usage,
84
+ });
85
+ }
86
+ const app = await appFor(opts);
87
+ await confirmByTyping(`destroy ${app}/${opts.stage}?`, opts.stage, opts.yes);
88
+ await apiFor(opts).destroyStage(app, opts.stage);
89
+ result({ app, stage: opts.stage, destroyed: true }, () => `${pc.green('✓')} destroying ${app}/${opts.stage}`);
90
+ }));
91
+ // ------------------------------------------------------------ crons
92
+ const cron = program.command('cron').description('scheduled jobs');
93
+ withTarget(cron.command('run <name>').description('run a cron now on a deployed stage')).action(action(async (name, opts) => {
94
+ await apiFor(opts).runCron(await appFor(opts), name, opts.stage);
95
+ result({ cron: name, stage: opts.stage, triggered: true }, () => `${pc.green('✓')} triggered ${name} on ${opts.stage}`);
96
+ }));
97
+ }
98
+ function checkSecretName(name) {
99
+ if (!ENV_NAME_PATTERN.test(name)) {
100
+ throw new CliError(`secret names are UPPER_SNAKE_CASE, got "${name}"`, { exitCode: EXIT.usage });
101
+ }
102
+ }
103
+ //# sourceMappingURL=manage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manage.js","sourceRoot":"","sources":["../../src/commands/manage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ import type { LogLine, TelemetryEvent } from '@ericminassian/platform-core';
2
+ import type { Command } from 'commander';
3
+ export declare function registerObserve(program: Command): void;
4
+ /** `["userId=1", "kind=a"]` → `"userId=1&kind=a"` (URL-encoded pairs, as the API expects). */
5
+ export declare function parsePartition(pairs: string[]): string;
6
+ export declare function formatLogLine(l: LogLine): string;
7
+ export declare function formatTrace(events: TelemetryEvent[]): string;
8
+ export declare function readStdin(): string;
@@ -0,0 +1,195 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import pc from 'picocolors';
3
+ import { formatEvent } from '../dev/pretty.js';
4
+ import { CliError, EXIT, isJsonMode, result, sparkline, table } from '../util/output.js';
5
+ import { shortTime, sinceRange } from '../util/time.js';
6
+ import { action, apiFor, appFor, withTarget } from './common.js';
7
+ export function registerObserve(program) {
8
+ withTarget(program
9
+ .command('logs')
10
+ .description('search recent logs (web + worker); --follow streams live')
11
+ .option('--since <duration>', 'how far back', '1h')
12
+ .option('--filter <text>', 'only lines containing this text / CloudWatch filter pattern')
13
+ .option('--limit <n>', 'max lines', '200')
14
+ .option('-f, --follow', 'stream new lines (live tail)')
15
+ .option('--runtime', "include the Lambda runtime's own records (hidden by default)")).action(action(async (opts) => {
16
+ const keep = (l) => opts.runtime || l.level !== 'system';
17
+ const api = apiFor(opts);
18
+ const app = await appFor(opts);
19
+ if (opts.follow) {
20
+ const ac = new AbortController();
21
+ process.once('SIGINT', () => ac.abort());
22
+ try {
23
+ for await (const line of api.tailLogs(app, { stage: opts.stage, ...(opts.filter ? { filter: opts.filter } : {}) }, ac.signal)) {
24
+ if (!keep(line))
25
+ continue;
26
+ process.stdout.write(`${isJsonMode() ? JSON.stringify(line) : formatLogLine(line)}\n`);
27
+ }
28
+ }
29
+ catch (err) {
30
+ if (err.name !== 'AbortError')
31
+ throw err;
32
+ }
33
+ return;
34
+ }
35
+ const { from, to } = sinceRange(opts.since);
36
+ const res = await api.logs(app, {
37
+ stage: opts.stage,
38
+ from,
39
+ to,
40
+ limit: Number(opts.limit),
41
+ ...(opts.filter ? { filter: opts.filter } : {}),
42
+ });
43
+ const shown = { ...res, lines: res.lines.filter(keep) };
44
+ result(shown, (r) => r.lines.length ? r.lines.map(formatLogLine).join('\n') : pc.dim('(no log lines)'));
45
+ }));
46
+ withTarget(program
47
+ .command('metrics')
48
+ .description('requests, errors, latency and jobs for a stage')
49
+ .option('--since <duration>', 'time range', '6h')).action(action(async (opts) => {
50
+ const api = apiFor(opts);
51
+ const app = await appFor(opts);
52
+ const range = sinceRange(opts.since);
53
+ const [metrics, routes, jobs] = await Promise.all([
54
+ api.metrics(app, { stage: opts.stage, ...range }),
55
+ api.routes(app, { stage: opts.stage, from: range.from, to: range.to }).catch(() => []),
56
+ api
57
+ .jobs(app, { stage: opts.stage, from: range.from, to: range.to })
58
+ .catch(() => ({ jobs: [], queues: [] })),
59
+ ]);
60
+ result({ metrics, routes, ...jobs }, (v) => {
61
+ const pts = v.metrics.points;
62
+ const total = pts.reduce((a, p) => a + p.req, 0);
63
+ const errors = pts.reduce((a, p) => a + p.s5xx, 0);
64
+ const p95s = pts.map((p) => p.p95).filter((x) => x !== null);
65
+ const lines = [
66
+ `${pc.bold(app)} ${pc.dim(`${opts.stage} · last ${opts.since} · ${v.metrics.res} buckets`)}`,
67
+ '',
68
+ ` requests ${String(total).padStart(8)} ${sparkline(pts.map((p) => p.req))}`,
69
+ ` 5xx ${String(errors).padStart(8)} ${pc.red(sparkline(pts.map((p) => p.s5xx)))}`,
70
+ ` p95 (ms) ${String(p95s.length ? Math.max(...p95s) : '-').padStart(8)} ${sparkline(pts.map((p) => p.p95))}`,
71
+ ` cold ${String(pts.reduce((a, p) => a + p.cold, 0)).padStart(8)} ${sparkline(pts.map((p) => p.cold))}`,
72
+ ];
73
+ if (v.routes.length) {
74
+ lines.push('', pc.bold('routes'), table(v.routes.map((r) => ({
75
+ method: r.method,
76
+ route: r.route,
77
+ req: r.req,
78
+ '5xx': r.s5xx,
79
+ '4xx': r.s4xx,
80
+ p50: r.p50 ?? '-',
81
+ p95: r.p95 ?? '-',
82
+ }))));
83
+ }
84
+ if (v.jobs.length) {
85
+ lines.push('', pc.bold('jobs'), table(v.jobs.map((j) => ({
86
+ job: `${j.kind}:${j.name}`,
87
+ ok: j.ok,
88
+ error: j.error,
89
+ p95: j.p95 ?? '-',
90
+ last: j.lastRun ? shortTime(j.lastRun) : '-',
91
+ }))));
92
+ }
93
+ if (v.queues.length) {
94
+ lines.push('', pc.bold('queues'), table(v.queues.map((q) => ({
95
+ queue: q.name,
96
+ visible: q.visible,
97
+ inFlight: q.inFlight,
98
+ dlq: q.deadLetter,
99
+ oldest: q.oldestAgeSeconds ?? '-',
100
+ }))));
101
+ }
102
+ return lines.join('\n');
103
+ });
104
+ }));
105
+ withTarget(program.command('errors').description('grouped errors for a stage')).action(action(async (opts) => {
106
+ const groups = await apiFor(opts).errors(await appFor(opts), { stage: opts.stage });
107
+ result(groups, (g) => table(g.map((e) => ({
108
+ id: e.fingerprint,
109
+ status: e.status === 'open' ? pc.red('open') : e.status,
110
+ count: e.count,
111
+ error: `${e.name}: ${e.message}`.slice(0, 80),
112
+ where: e.sample.route ?? e.sample.job ?? '',
113
+ last: shortTime(e.lastSeen),
114
+ trace: e.sample.trace ?? '',
115
+ }))));
116
+ }));
117
+ withTarget(program
118
+ .command('traces <traceId>')
119
+ .description('every event of one request/job across web, queues and worker')).action(action(async (traceId, opts) => {
120
+ const t = await apiFor(opts).trace(await appFor(opts), traceId, { stage: opts.stage });
121
+ result(t, (v) => formatTrace(v.events));
122
+ }));
123
+ withTarget(program
124
+ .command('data [collection]')
125
+ .description('browse database collections or file stores')
126
+ .option('--partition <k=v...>', 'partition key values (repeatable)')
127
+ .option('--store <name>', 'list files in a storage store instead')
128
+ .option('--prefix <prefix>', 'file key prefix (with --store)')
129
+ .option('--cursor <cursor>', 'continue from a previous page')
130
+ .option('--limit <n>', 'page size', '50')).action(action(async (collection, opts) => {
131
+ const api = apiFor(opts);
132
+ const app = await appFor(opts);
133
+ if (opts.store) {
134
+ const r = await api.files(app, {
135
+ stage: opts.stage,
136
+ store: opts.store,
137
+ ...(opts.prefix ? { prefix: opts.prefix } : {}),
138
+ ...(opts.cursor ? { cursor: opts.cursor } : {}),
139
+ });
140
+ result(r, (v) => `${table(v.objects.map((o) => ({ key: o.key, size: o.size, modified: o.lastModified ?? '' })))}${v.cursor ? `\n${pc.dim(`more: --cursor ${v.cursor}`)}` : ''}`);
141
+ return;
142
+ }
143
+ if (!collection) {
144
+ const cols = await api.collections(app, { stage: opts.stage });
145
+ result(cols, (c) => (c.length ? c.join('\n') : pc.dim('(no collections yet)')));
146
+ return;
147
+ }
148
+ const page = await api.items(app, {
149
+ stage: opts.stage,
150
+ collection,
151
+ limit: Number(opts.limit),
152
+ ...(opts.partition ? { partition: parsePartition(opts.partition) } : {}),
153
+ ...(opts.cursor ? { cursor: opts.cursor } : {}),
154
+ });
155
+ result(page, (v) => `${v.items.map((i) => JSON.stringify(i)).join('\n') || pc.dim('(no items)')}${v.cursor ? `\n${pc.dim(`more: --cursor ${v.cursor}`)}` : ''}`);
156
+ }));
157
+ }
158
+ /** `["userId=1", "kind=a"]` → `"userId=1&kind=a"` (URL-encoded pairs, as the API expects). */
159
+ export function parsePartition(pairs) {
160
+ const params = new URLSearchParams();
161
+ for (const p of pairs) {
162
+ const i = p.indexOf('=');
163
+ if (i <= 0)
164
+ throw new CliError(`--partition expects key=value, got "${p}"`, { exitCode: EXIT.usage });
165
+ params.append(p.slice(0, i), p.slice(i + 1));
166
+ }
167
+ return params.toString();
168
+ }
169
+ export function formatLogLine(l) {
170
+ const ts = pc.dim(shortTime(l.ts));
171
+ const stream = l.stream === 'web' ? pc.green('web ') : pc.yellow('worker');
172
+ const body = l.event ? (formatEvent(l.event, { spans: true }) ?? l.message) : l.message;
173
+ return `${ts} ${stream} ${body}`;
174
+ }
175
+ export function formatTrace(events) {
176
+ if (events.length === 0)
177
+ return pc.dim('(no events for this trace)');
178
+ const sorted = [...events].sort((a, b) => a.ts - b.ts);
179
+ const t0 = sorted[0].ts;
180
+ return sorted
181
+ .map((e) => {
182
+ const offset = `+${String(e.ts - t0).padStart(5)}ms`;
183
+ return `${pc.dim(offset)} ${formatEvent(e, { spans: true }) ?? e.t}`;
184
+ })
185
+ .join('\n');
186
+ }
187
+ export function readStdin() {
188
+ try {
189
+ return readFileSync(0, 'utf8').replace(/\r?\n$/, '');
190
+ }
191
+ catch {
192
+ return '';
193
+ }
194
+ }
195
+ //# sourceMappingURL=observe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"observe.js","sourceRoot":"","sources":["../../src/commands/observe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,13 @@
1
+ /** What `plat login` stores. The token is a platform token, never a GitHub token. */
2
+ export interface StoredCredentials {
3
+ apiUrl: string;
4
+ token: string;
5
+ github: string;
6
+ expiresAt: string;
7
+ }
8
+ export declare function configDir(): string;
9
+ export declare function credentialsPath(): string;
10
+ export declare function saveCredentials(creds: StoredCredentials, path?: string): void;
11
+ export declare function loadCredentials(path?: string): StoredCredentials | null;
12
+ export declare function clearCredentials(path?: string): boolean;
13
+ export declare function isExpired(c: StoredCredentials, now?: number): boolean;
@@ -0,0 +1,42 @@
1
+ import { chmodSync, existsSync, mkdirSync, readFileSync, rmSync, writeFileSync } from 'node:fs';
2
+ import { homedir } from 'node:os';
3
+ import { dirname, join } from 'node:path';
4
+ export function configDir() {
5
+ if (process.env.PLAT_CONFIG_DIR)
6
+ return process.env.PLAT_CONFIG_DIR;
7
+ const base = process.env.XDG_CONFIG_HOME || join(homedir(), '.config');
8
+ return join(base, 'plat');
9
+ }
10
+ export function credentialsPath() {
11
+ return join(configDir(), 'credentials.json');
12
+ }
13
+ export function saveCredentials(creds, path = credentialsPath()) {
14
+ mkdirSync(dirname(path), { recursive: true, mode: 0o700 });
15
+ writeFileSync(path, `${JSON.stringify(creds, null, 2)}\n`, { mode: 0o600 });
16
+ // writeFileSync only applies `mode` when creating; enforce it on overwrite too.
17
+ chmodSync(path, 0o600);
18
+ }
19
+ export function loadCredentials(path = credentialsPath()) {
20
+ if (!existsSync(path))
21
+ return null;
22
+ try {
23
+ const c = JSON.parse(readFileSync(path, 'utf8'));
24
+ if (!c.token || !c.apiUrl)
25
+ return null;
26
+ return c;
27
+ }
28
+ catch {
29
+ return null;
30
+ }
31
+ }
32
+ export function clearCredentials(path = credentialsPath()) {
33
+ if (!existsSync(path))
34
+ return false;
35
+ rmSync(path);
36
+ return true;
37
+ }
38
+ export function isExpired(c, now = Date.now()) {
39
+ const t = Date.parse(c.expiresAt);
40
+ return Number.isFinite(t) && t <= now;
41
+ }
42
+ //# sourceMappingURL=credentials.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"credentials.js","sourceRoot":"","sources":["../src/credentials.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,SAAS,EAAE,UAAU,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AAChG,OAAO,EAAE,OAAO,EAAE,MAAM,SAAS,CAAC;AAClC,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAU1C,MAAM,UAAU,SAAS;IACvB,IAAI,OAAO,CAAC,GAAG,CAAC,eAAe;QAAE,OAAO,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC;IACpE,MAAM,IAAI,GAAG,OAAO,CAAC,GAAG,CAAC,eAAe,IAAI,IAAI,CAAC,OAAO,EAAE,EAAE,SAAS,CAAC,CAAC;IACvE,OAAO,IAAI,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;AAC5B,CAAC;AAED,MAAM,UAAU,eAAe;IAC7B,OAAO,IAAI,CAAC,SAAS,EAAE,EAAE,kBAAkB,CAAC,CAAC;AAC/C,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,KAAwB,EAAE,IAAI,GAAG,eAAe,EAAE;IAChF,SAAS,CAAC,OAAO,CAAC,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC3D,aAAa,CAAC,IAAI,EAAE,GAAG,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAC;IAC5E,gFAAgF;IAChF,SAAS,CAAC,IAAI,EAAE,KAAK,CAAC,CAAC;AACzB,CAAC;AAED,MAAM,UAAU,eAAe,CAAC,IAAI,GAAG,eAAe,EAAE;IACtD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,IAAI,CAAC;IACnC,IAAI,CAAC;QACH,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAsB,CAAC;QACtE,IAAI,CAAC,CAAC,CAAC,KAAK,IAAI,CAAC,CAAC,CAAC,MAAM;YAAE,OAAO,IAAI,CAAC;QACvC,OAAO,CAAC,CAAC;IACX,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,IAAI,CAAC;IACd,CAAC;AACH,CAAC;AAED,MAAM,UAAU,gBAAgB,CAAC,IAAI,GAAG,eAAe,EAAE;IACvD,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,KAAK,CAAC;IACpC,MAAM,CAAC,IAAI,CAAC,CAAC;IACb,OAAO,IAAI,CAAC;AACd,CAAC;AAED,MAAM,UAAU,SAAS,CAAC,CAAoB,EAAE,GAAG,GAAG,IAAI,CAAC,GAAG,EAAE;IAC9D,MAAM,CAAC,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC;IAClC,OAAO,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,GAAG,CAAC;AACxC,CAAC"}
@@ -0,0 +1,23 @@
1
+ import type { DeploymentEventEntry, DeploymentRecord, DeploymentStatus, PresignedPost } from '@ericminassian/platform-core';
2
+ import type { ApiClient } from './api.ts';
3
+ export declare const TERMINAL_STATUSES: readonly DeploymentStatus[];
4
+ export interface DeployOptions {
5
+ cwd: string;
6
+ stage?: string;
7
+ wait: boolean;
8
+ timeoutMs?: number;
9
+ pollMs?: number;
10
+ }
11
+ export interface DeployResult {
12
+ deployment: DeploymentRecord;
13
+ url?: string;
14
+ }
15
+ export declare function deploy(api: ApiClient, opts: DeployOptions): Promise<DeployResult>;
16
+ /** Builds the multipart body for an S3 presigned POST (policy fields first, file last). */
17
+ export declare function presignedPostForm(post: PresignedPost, data: Uint8Array, filename: string): FormData;
18
+ export declare function uploadPresignedPost(post: PresignedPost, path: string, name: string): Promise<void>;
19
+ export declare function waitForDeployment(api: ApiClient, id: string, opts: {
20
+ timeoutMs: number;
21
+ pollMs: number;
22
+ onEvent?: (e: DeploymentEventEntry) => void;
23
+ }): Promise<DeploymentRecord>;
package/dist/deploy.js ADDED
@@ -0,0 +1,100 @@
1
+ import { readFileSync } from 'node:fs';
2
+ import { basename } from 'node:path';
3
+ import pc from 'picocolors';
4
+ import { buildApp } from './build.js';
5
+ import { appendStepSummary, deriveStage, gitInfo, isGitHubActions, setOutput } from './github.js';
6
+ import { loadProject } from './project.js';
7
+ import { CliError, EXIT, info, step, success } from './util/output.js';
8
+ export const TERMINAL_STATUSES = ['succeeded', 'failed', 'rolled_back'];
9
+ export async function deploy(api, opts) {
10
+ const project = await loadProject(opts.cwd);
11
+ const stage = deriveStage(opts.stage);
12
+ const app = project.manifest.name;
13
+ const { files } = await buildApp({ cwd: project.root, project });
14
+ // The API always issues an upload for manifest.json; `files` lists the optional bundles.
15
+ const fileNames = Object.keys(files).filter((f) => f !== 'manifest.json');
16
+ const git = gitInfo(project.root);
17
+ step(`creating deployment of ${pc.bold(app)} to ${pc.bold(stage)}`);
18
+ const created = await api.createDeployment(app, {
19
+ stage,
20
+ manifest: project.raw,
21
+ files: fileNames,
22
+ ...git,
23
+ });
24
+ const id = created.deployment.id;
25
+ for (const name of Object.keys(files)) {
26
+ const post = created.uploads[name];
27
+ if (!post)
28
+ throw new CliError(`the API did not return an upload URL for ${name}`);
29
+ step(`uploading ${name}`);
30
+ await uploadPresignedPost(post, files[name], name);
31
+ }
32
+ step('starting deployment');
33
+ let deployment = await api.startDeployment(id);
34
+ if (!opts.wait) {
35
+ info(`deployment ${id} is ${deployment.status}; follow with \`plat deployments --stage ${stage}\``);
36
+ return { deployment, url: deployment.url };
37
+ }
38
+ deployment = await waitForDeployment(api, id, {
39
+ timeoutMs: opts.timeoutMs ?? 15 * 60_000,
40
+ pollMs: opts.pollMs ?? 2_000,
41
+ onEvent: printEvent,
42
+ });
43
+ if (deployment.status !== 'succeeded') {
44
+ throw new CliError(`deployment ${id} ${deployment.status}${deployment.error ? `: ${deployment.error}` : ''}`, {
45
+ hint: `see \`plat logs --stage ${stage}\` and the events above`,
46
+ exitCode: EXIT.deployFailed,
47
+ });
48
+ }
49
+ const url = deployment.url;
50
+ success(`deployed ${app} to ${stage}${url ? `: ${pc.underline(url)}` : ''}`);
51
+ if (isGitHubActions()) {
52
+ if (url)
53
+ setOutput('url', url);
54
+ setOutput('deployment', id);
55
+ appendStepSummary(`### Deployed \`${app}\` → \`${stage}\`\n\n${url ? `**URL:** ${url}\n\n` : ''}Deployment \`${id}\`${git.commit ? ` at \`${git.commit.slice(0, 7)}\`` : ''}`);
56
+ }
57
+ return { deployment, url };
58
+ }
59
+ /** Builds the multipart body for an S3 presigned POST (policy fields first, file last). */
60
+ export function presignedPostForm(post, data, filename) {
61
+ const form = new FormData();
62
+ for (const [k, v] of Object.entries(post.fields))
63
+ form.append(k, v);
64
+ form.append('file', new Blob([new Uint8Array(data)]), filename);
65
+ return form;
66
+ }
67
+ export async function uploadPresignedPost(post, path, name) {
68
+ const data = readFileSync(path);
69
+ const res = await fetch(post.url, { method: 'POST', body: presignedPostForm(post, data, basename(name)) });
70
+ if (!res.ok) {
71
+ const text = await res.text().catch(() => '');
72
+ throw new CliError(`upload of ${name} failed (HTTP ${res.status})`, {
73
+ hint: text.slice(0, 300) || undefined,
74
+ });
75
+ }
76
+ }
77
+ export async function waitForDeployment(api, id, opts) {
78
+ const deadline = Date.now() + opts.timeoutMs;
79
+ let seen = 0;
80
+ for (;;) {
81
+ const d = await api.getDeployment(id);
82
+ const events = d.events ?? [];
83
+ for (const e of events.slice(seen))
84
+ opts.onEvent?.(e);
85
+ seen = Math.max(seen, events.length);
86
+ if (TERMINAL_STATUSES.includes(d.status))
87
+ return d;
88
+ if (Date.now() > deadline) {
89
+ throw new CliError(`timed out waiting for deployment ${id} (status ${d.status})`, {
90
+ exitCode: EXIT.deployFailed,
91
+ });
92
+ }
93
+ await new Promise((r) => setTimeout(r, opts.pollMs));
94
+ }
95
+ }
96
+ function printEvent(e) {
97
+ const color = e.level === 'error' ? pc.red : e.level === 'warn' ? pc.yellow : pc.dim;
98
+ info(` ${color(new Date(e.ts).toISOString().slice(11, 19))} ${e.msg}${e.resource ? pc.dim(` (${e.resource})`) : ''}`);
99
+ }
100
+ //# sourceMappingURL=deploy.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deploy.js","sourceRoot":"","sources":["../src/deploy.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Local stand-in for EventBridge Scheduler (the emulator creates schedules but
3
+ * never fires them). Same expressions as plat.config.ts: 5-field cron in UTC
4
+ * (or the cron's timezone) or `rate(n unit)`.
5
+ */
6
+ export interface LocalCron {
7
+ name: string;
8
+ schedule: string;
9
+ timezone?: string;
10
+ }
11
+ export declare function nextRun(cron: LocalCron, from?: Date): Date;
12
+ export interface CronScheduler {
13
+ next(name: string): Date | undefined;
14
+ stop(): void;
15
+ }
16
+ export declare function scheduleCrons(crons: LocalCron[], fire: (name: string) => void | Promise<void>): CronScheduler;
@@ -0,0 +1,47 @@
1
+ import { CronExpressionParser } from 'cron-parser';
2
+ export function nextRun(cron, from = new Date()) {
3
+ const rate = /^rate\(\s*(\d+)\s+(minute|minutes|hour|hours|day|days)\s*\)$/.exec(cron.schedule.trim());
4
+ if (rate) {
5
+ const unit = rate[2].startsWith('minute')
6
+ ? 60_000
7
+ : rate[2].startsWith('hour')
8
+ ? 3_600_000
9
+ : 86_400_000;
10
+ return new Date(from.getTime() + Number(rate[1]) * unit);
11
+ }
12
+ return CronExpressionParser.parse(cron.schedule, { currentDate: from, tz: cron.timezone ?? 'UTC' })
13
+ .next()
14
+ .toDate();
15
+ }
16
+ export function scheduleCrons(crons, fire) {
17
+ const timers = new Map();
18
+ const nexts = new Map();
19
+ const arm = (c) => {
20
+ const at = nextRun(c);
21
+ nexts.set(c.name, at);
22
+ // setTimeout caps at ~24.8 days; re-arm in steps.
23
+ const delay = Math.min(at.getTime() - Date.now(), 2 ** 31 - 1);
24
+ timers.set(c.name, setTimeout(async () => {
25
+ if (Date.now() >= at.getTime() - 5) {
26
+ try {
27
+ await fire(c.name);
28
+ }
29
+ catch {
30
+ // reported by `fire`
31
+ }
32
+ }
33
+ arm(c);
34
+ }, Math.max(delay, 0)));
35
+ };
36
+ for (const c of crons)
37
+ arm(c);
38
+ return {
39
+ next: (name) => nexts.get(name),
40
+ stop: () => {
41
+ for (const t of timers.values())
42
+ clearTimeout(t);
43
+ timers.clear();
44
+ },
45
+ };
46
+ }
47
+ //# sourceMappingURL=crons.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"crons.js","sourceRoot":"","sources":["../../src/dev/crons.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oBAAoB,EAAE,MAAM,aAAa,CAAC;AAanD,MAAM,UAAU,OAAO,CAAC,IAAe,EAAE,IAAI,GAAG,IAAI,IAAI,EAAE;IACxD,MAAM,IAAI,GAAG,8DAA8D,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAC;IACvG,IAAI,IAAI,EAAE,CAAC;QACT,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,QAAQ,CAAC;YACxC,CAAC,CAAC,MAAM;YACR,CAAC,CAAC,IAAI,CAAC,CAAC,CAAE,CAAC,UAAU,CAAC,MAAM,CAAC;gBAC3B,CAAC,CAAC,SAAS;gBACX,CAAC,CAAC,UAAU,CAAC;QACjB,OAAO,IAAI,IAAI,CAAC,IAAI,CAAC,OAAO,EAAE,GAAG,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,IAAI,CAAC,CAAC;IAC3D,CAAC;IACD,OAAO,oBAAoB,CAAC,KAAK,CAAC,IAAI,CAAC,QAAQ,EAAE,EAAE,WAAW,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,CAAC,QAAQ,IAAI,KAAK,EAAE,CAAC;SAChG,IAAI,EAAE;SACN,MAAM,EAAE,CAAC;AACd,CAAC;AAOD,MAAM,UAAU,aAAa,CAC3B,KAAkB,EAClB,IAA4C;IAE5C,MAAM,MAAM,GAAG,IAAI,GAAG,EAA0B,CAAC;IACjD,MAAM,KAAK,GAAG,IAAI,GAAG,EAAgB,CAAC;IACtC,MAAM,GAAG,GAAG,CAAC,CAAY,EAAE,EAAE;QAC3B,MAAM,EAAE,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;QACtB,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,CAAC;QACtB,kDAAkD;QAClD,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,OAAO,EAAE,GAAG,IAAI,CAAC,GAAG,EAAE,EAAE,CAAC,IAAI,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/D,MAAM,CAAC,GAAG,CACR,CAAC,CAAC,IAAI,EACN,UAAU,CACR,KAAK,IAAI,EAAE;YACT,IAAI,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,CAAC,OAAO,EAAE,GAAG,CAAC,EAAE,CAAC;gBACnC,IAAI,CAAC;oBACH,MAAM,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;gBACrB,CAAC;gBAAC,MAAM,CAAC;oBACP,qBAAqB;gBACvB,CAAC;YACH,CAAC;YACD,GAAG,CAAC,CAAC,CAAC,CAAC;QACT,CAAC,EACD,IAAI,CAAC,GAAG,CAAC,KAAK,EAAE,CAAC,CAAC,CACnB,CACF,CAAC;IACJ,CAAC,CAAC;IACF,KAAK,MAAM,CAAC,IAAI,KAAK;QAAE,GAAG,CAAC,CAAC,CAAC,CAAC;IAC9B,OAAO;QACL,IAAI,EAAE,CAAC,IAAI,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,IAAI,CAAC;QAC/B,IAAI,EAAE,GAAG,EAAE;YACT,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,MAAM,EAAE;gBAAE,YAAY,CAAC,CAAC,CAAC,CAAC;YACjD,MAAM,CAAC,KAAK,EAAE,CAAC;QACjB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,6 @@
1
+ /** Path to tsx's CLI (it has no `./cli` export, so go through its package.json). */
2
+ export declare function tsxCli(): string;
3
+ /** A CLI-owned entry file next to this module (`.ts` in the repo, `.js` when published). */
4
+ export declare function devEntry(name: 'server-entry' | 'worker-host'): string;
5
+ /** argv for running an entry under tsx, optionally restarting on edits. */
6
+ export declare function tsxArgs(name: 'server-entry' | 'worker-host', watch: boolean): string[];