@ericminassian/platform 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.
- package/dist/app.d.ts +10 -0
- package/dist/app.js +23 -0
- package/dist/app.js.map +1 -0
- package/dist/auth/cookies.d.ts +10 -0
- package/dist/auth/cookies.js +37 -0
- package/dist/auth/cookies.js.map +1 -0
- package/dist/auth/index.d.ts +22 -0
- package/dist/auth/index.js +217 -0
- package/dist/auth/index.js.map +1 -0
- package/dist/auth/pkce.d.ts +16 -0
- package/dist/auth/pkce.js +32 -0
- package/dist/auth/pkce.js.map +1 -0
- package/dist/auth/tokens.d.ts +17 -0
- package/dist/auth/tokens.js +142 -0
- package/dist/auth/tokens.js.map +1 -0
- package/dist/bindings.d.ts +13 -0
- package/dist/bindings.js +32 -0
- package/dist/bindings.js.map +1 -0
- package/dist/clients.d.ts +38 -0
- package/dist/clients.js +65 -0
- package/dist/clients.js.map +1 -0
- package/dist/context.d.ts +31 -0
- package/dist/context.js +33 -0
- package/dist/context.js.map +1 -0
- package/dist/db.d.ts +97 -0
- package/dist/db.js +297 -0
- package/dist/db.js.map +1 -0
- package/dist/events.d.ts +9 -0
- package/dist/events.js +28 -0
- package/dist/events.js.map +1 -0
- package/dist/http.d.ts +14 -0
- package/dist/http.js +82 -0
- package/dist/http.js.map +1 -0
- package/dist/index.d.ts +30 -0
- package/dist/index.js +11 -0
- package/dist/index.js.map +1 -0
- package/dist/queue.d.ts +7 -0
- package/dist/queue.js +50 -0
- package/dist/queue.js.map +1 -0
- package/dist/secrets.d.ts +8 -0
- package/dist/secrets.js +42 -0
- package/dist/secrets.js.map +1 -0
- package/dist/server.d.ts +12 -0
- package/dist/server.js +232 -0
- package/dist/server.js.map +1 -0
- package/dist/storage.d.ts +30 -0
- package/dist/storage.js +108 -0
- package/dist/storage.js.map +1 -0
- package/dist/telemetry.d.ts +42 -0
- package/dist/telemetry.js +218 -0
- package/dist/telemetry.js.map +1 -0
- package/dist/testing.d.ts +31 -0
- package/dist/testing.js +54 -0
- package/dist/testing.js.map +1 -0
- package/dist/worker.d.ts +73 -0
- package/dist/worker.js +179 -0
- package/dist/worker.js.map +1 -0
- package/package.json +58 -3
- package/src/app.ts +32 -0
- package/src/auth/cookies.ts +39 -0
- package/src/auth/index.ts +246 -0
- package/src/auth/pkce.ts +43 -0
- package/src/auth/tokens.ts +174 -0
- package/src/bindings.ts +35 -0
- package/src/clients.ts +98 -0
- package/src/context.ts +56 -0
- package/src/db.ts +380 -0
- package/src/events.ts +42 -0
- package/src/http.ts +82 -0
- package/src/index.ts +40 -0
- package/src/queue.ts +67 -0
- package/src/secrets.ts +57 -0
- package/src/server.ts +274 -0
- package/src/storage.ts +143 -0
- package/src/telemetry.ts +260 -0
- package/src/testing.ts +73 -0
- package/src/worker.ts +291 -0
- package/README.md +0 -3
package/dist/storage.js
ADDED
|
@@ -0,0 +1,108 @@
|
|
|
1
|
+
import { getBindings } from './bindings.js';
|
|
2
|
+
import { client } from './clients.js';
|
|
3
|
+
import { span } from './telemetry.js';
|
|
4
|
+
function location(name) {
|
|
5
|
+
const s = getBindings().storage;
|
|
6
|
+
if (!s?.stores.includes(name)) {
|
|
7
|
+
const declared = s?.stores ?? [];
|
|
8
|
+
throw new Error(`Unknown store "${name}". Declared storage: ${declared.length ? declared.join(', ') : '(none)'} — add it under "storage" in platform.json.`);
|
|
9
|
+
}
|
|
10
|
+
return { bucket: s.bucket, prefix: `${s.prefix}${name}/` };
|
|
11
|
+
}
|
|
12
|
+
/** The S3 client and command module, loaded on first use. */
|
|
13
|
+
async function s3() {
|
|
14
|
+
const [c, m] = await Promise.all([client('s3'), import('@aws-sdk/client-s3')]);
|
|
15
|
+
return { c, m };
|
|
16
|
+
}
|
|
17
|
+
async function sign(command, expiresIn) {
|
|
18
|
+
const [{ getSignedUrl }, c] = await Promise.all([import('@aws-sdk/s3-request-presigner'), client('s3')]);
|
|
19
|
+
// biome-ignore lint/suspicious/noExplicitAny: presigner and client generics differ across smithy versions
|
|
20
|
+
return getSignedUrl(c, command, { expiresIn });
|
|
21
|
+
}
|
|
22
|
+
function objectKey(prefix, key) {
|
|
23
|
+
const k = key.replace(/^\/+/, '');
|
|
24
|
+
if (!k || k.split('/').some((p) => p === '..'))
|
|
25
|
+
throw new Error(`Invalid storage key "${key}"`);
|
|
26
|
+
return prefix + k;
|
|
27
|
+
}
|
|
28
|
+
function isNotFound(e) {
|
|
29
|
+
const name = e?.name;
|
|
30
|
+
const status = e?.$metadata?.httpStatusCode;
|
|
31
|
+
return name === 'NoSuchKey' || name === 'NotFound' || status === 404;
|
|
32
|
+
}
|
|
33
|
+
export function storage(name) {
|
|
34
|
+
const get = (key) => span('storage.get', name, async () => {
|
|
35
|
+
const { bucket, prefix } = location(name);
|
|
36
|
+
const { c, m } = await s3();
|
|
37
|
+
try {
|
|
38
|
+
const out = await c.send(new m.GetObjectCommand({ Bucket: bucket, Key: objectKey(prefix, key) }));
|
|
39
|
+
return out.Body ? await out.Body.transformToByteArray() : new Uint8Array();
|
|
40
|
+
}
|
|
41
|
+
catch (e) {
|
|
42
|
+
if (isNotFound(e))
|
|
43
|
+
return undefined;
|
|
44
|
+
throw e;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
47
|
+
return {
|
|
48
|
+
put: (key, body, opts) => span('storage.put', name, async () => {
|
|
49
|
+
const { bucket, prefix } = location(name);
|
|
50
|
+
const { c, m } = await s3();
|
|
51
|
+
await c.send(new m.PutObjectCommand({
|
|
52
|
+
Bucket: bucket,
|
|
53
|
+
Key: objectKey(prefix, key),
|
|
54
|
+
Body: typeof body === 'string' ? Buffer.from(body) : body,
|
|
55
|
+
...(opts?.contentType ? { ContentType: opts.contentType } : {}),
|
|
56
|
+
}));
|
|
57
|
+
}),
|
|
58
|
+
get,
|
|
59
|
+
getText: async (key) => {
|
|
60
|
+
const bytes = await get(key);
|
|
61
|
+
return bytes ? new TextDecoder().decode(bytes) : undefined;
|
|
62
|
+
},
|
|
63
|
+
delete: (key) => span('storage.delete', name, async () => {
|
|
64
|
+
const { bucket, prefix } = location(name);
|
|
65
|
+
const { c, m } = await s3();
|
|
66
|
+
await c.send(new m.DeleteObjectCommand({ Bucket: bucket, Key: objectKey(prefix, key) }));
|
|
67
|
+
}),
|
|
68
|
+
list: (sub, opts) => span('storage.list', name, async () => {
|
|
69
|
+
const { bucket, prefix } = location(name);
|
|
70
|
+
const { c, m } = await s3();
|
|
71
|
+
const out = await c.send(new m.ListObjectsV2Command({
|
|
72
|
+
Bucket: bucket,
|
|
73
|
+
Prefix: prefix + (sub ?? '').replace(/^\/+/, ''),
|
|
74
|
+
...(opts?.cursor ? { ContinuationToken: opts.cursor } : {}),
|
|
75
|
+
...(opts?.limit ? { MaxKeys: opts.limit } : {}),
|
|
76
|
+
}));
|
|
77
|
+
const objects = (out.Contents ?? []).map((o) => ({
|
|
78
|
+
key: (o.Key ?? '').slice(prefix.length),
|
|
79
|
+
size: o.Size ?? 0,
|
|
80
|
+
...(o.LastModified ? { lastModified: o.LastModified } : {}),
|
|
81
|
+
}));
|
|
82
|
+
return out.NextContinuationToken ? { objects, cursor: out.NextContinuationToken } : { objects };
|
|
83
|
+
}),
|
|
84
|
+
uploadUrl: (key, opts) => span('storage.sign', name, async () => {
|
|
85
|
+
const { bucket, prefix } = location(name);
|
|
86
|
+
const { m } = await s3();
|
|
87
|
+
const cmd = new m.PutObjectCommand({
|
|
88
|
+
Bucket: bucket,
|
|
89
|
+
Key: objectKey(prefix, key),
|
|
90
|
+
...(opts?.contentType ? { ContentType: opts.contentType } : {}),
|
|
91
|
+
});
|
|
92
|
+
return sign(cmd, opts?.expiresInSeconds ?? 900);
|
|
93
|
+
}),
|
|
94
|
+
downloadUrl: (key, opts) => span('storage.sign', name, async () => {
|
|
95
|
+
const { bucket, prefix } = location(name);
|
|
96
|
+
const { m } = await s3();
|
|
97
|
+
const cmd = new m.GetObjectCommand({
|
|
98
|
+
Bucket: bucket,
|
|
99
|
+
Key: objectKey(prefix, key),
|
|
100
|
+
...(opts?.filename
|
|
101
|
+
? { ResponseContentDisposition: `attachment; filename="${opts.filename.replace(/"/g, '')}"` }
|
|
102
|
+
: {}),
|
|
103
|
+
});
|
|
104
|
+
return sign(cmd, opts?.expiresInSeconds ?? 900);
|
|
105
|
+
}),
|
|
106
|
+
};
|
|
107
|
+
}
|
|
108
|
+
//# sourceMappingURL=storage.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"storage.js","sourceRoot":"","sources":["../src/storage.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
import { type ErrorEvent, type TelemetryEvent, type TelemetryKind } from '@ericminassian/platform-core';
|
|
2
|
+
/**
|
|
3
|
+
* Telemetry writer. Every line is one core `TelemetryEvent` as JSON on stdout
|
|
4
|
+
* (Lambda ships stdout to CloudWatch Logs; the account-level subscription
|
|
5
|
+
* filter forwards `_p: 1` lines to the telemetry processor). Under `plat dev`
|
|
6
|
+
* (`PLATFORM_LOG_PRETTY=1`) lines are printed compactly for humans instead.
|
|
7
|
+
* Nothing here may ever throw into app code.
|
|
8
|
+
*/
|
|
9
|
+
type Sink = (event: TelemetryEvent) => void;
|
|
10
|
+
/** Replace the output (tests). `null` restores stdout. */
|
|
11
|
+
export declare function setTelemetrySink(s: Sink | null): void;
|
|
12
|
+
type Fields<K extends TelemetryKind> = Omit<Extract<TelemetryEvent, {
|
|
13
|
+
t: K;
|
|
14
|
+
}>, '_p' | 'ts' | 'app' | 'stage' | 'rev' | 't'> & {
|
|
15
|
+
ts?: number;
|
|
16
|
+
};
|
|
17
|
+
export declare function emit<K extends TelemetryKind>(t: K, fields: Fields<K>): void;
|
|
18
|
+
/** Time `fn` as a span (`db.get`, `queue.send`, ...) under the current trace. */
|
|
19
|
+
export declare function span<T>(op: string, name: string | undefined, fn: () => Promise<T>): Promise<T>;
|
|
20
|
+
/** Emit an `err` event for a thrown value. */
|
|
21
|
+
export declare function emitError(err: unknown, source: ErrorEvent['source'], extra?: {
|
|
22
|
+
route?: string;
|
|
23
|
+
job?: string;
|
|
24
|
+
}): void;
|
|
25
|
+
export declare function toError(err: unknown): Error;
|
|
26
|
+
export declare const metrics: {
|
|
27
|
+
count(name: string, n?: number): void;
|
|
28
|
+
value(name: string, value: number, unit?: string): void;
|
|
29
|
+
};
|
|
30
|
+
export declare const log: {
|
|
31
|
+
debug: (msg: string, fields?: Record<string, unknown>) => void;
|
|
32
|
+
info: (msg: string, fields?: Record<string, unknown>) => void;
|
|
33
|
+
warn: (msg: string, fields?: Record<string, unknown>) => void;
|
|
34
|
+
error: (msg: string, fields?: Record<string, unknown> | unknown) => void;
|
|
35
|
+
};
|
|
36
|
+
/** Route console.* through telemetry so app logs carry the trace id. */
|
|
37
|
+
export declare function installConsoleCapture(): void;
|
|
38
|
+
/** Record outgoing `fetch` calls as spans (method + host only; no URLs with secrets). */
|
|
39
|
+
export declare function installFetchInstrumentation(): void;
|
|
40
|
+
/** Undo console/fetch patching (tests). */
|
|
41
|
+
export declare function uninstallInstrumentation(): void;
|
|
42
|
+
export {};
|
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
import { format } from 'node:util';
|
|
2
|
+
import { errorFingerprint, newSpanId, } from '@ericminassian/platform-core';
|
|
3
|
+
import { tryBindings } from './bindings.js';
|
|
4
|
+
import { currentContext } from './context.js';
|
|
5
|
+
// Captured before console is patched so telemetry never recurses through it.
|
|
6
|
+
const rawWrite = process.stdout.write.bind(process.stdout);
|
|
7
|
+
let sink = null;
|
|
8
|
+
/** Replace the output (tests). `null` restores stdout. */
|
|
9
|
+
export function setTelemetrySink(s) {
|
|
10
|
+
sink = s;
|
|
11
|
+
}
|
|
12
|
+
export function emit(t, fields) {
|
|
13
|
+
try {
|
|
14
|
+
const b = tryBindings();
|
|
15
|
+
const ctx = currentContext();
|
|
16
|
+
const event = {
|
|
17
|
+
_p: 1,
|
|
18
|
+
t,
|
|
19
|
+
ts: Date.now(),
|
|
20
|
+
app: b?.app ?? process.env.PLATFORM_APP ?? 'unknown',
|
|
21
|
+
stage: b?.stage ?? process.env.PLATFORM_STAGE ?? 'unknown',
|
|
22
|
+
rev: b?.revision ?? 'unknown',
|
|
23
|
+
...(ctx ? { trace: ctx.trace } : {}),
|
|
24
|
+
...fields,
|
|
25
|
+
};
|
|
26
|
+
if (sink)
|
|
27
|
+
sink(event);
|
|
28
|
+
else
|
|
29
|
+
rawWrite(`${process.env.PLATFORM_LOG_PRETTY === '1' ? pretty(event) : JSON.stringify(event)}\n`);
|
|
30
|
+
}
|
|
31
|
+
catch {
|
|
32
|
+
// never throw from telemetry
|
|
33
|
+
}
|
|
34
|
+
}
|
|
35
|
+
/** Time `fn` as a span (`db.get`, `queue.send`, ...) under the current trace. */
|
|
36
|
+
export async function span(op, name, fn) {
|
|
37
|
+
const t0 = performance.now();
|
|
38
|
+
const ctx = currentContext();
|
|
39
|
+
const id = newSpanId();
|
|
40
|
+
let status = 'ok';
|
|
41
|
+
try {
|
|
42
|
+
return await fn();
|
|
43
|
+
}
|
|
44
|
+
catch (e) {
|
|
45
|
+
status = 'error';
|
|
46
|
+
throw e;
|
|
47
|
+
}
|
|
48
|
+
finally {
|
|
49
|
+
// Spans only matter as part of a trace; skip them outside a request/job.
|
|
50
|
+
if (ctx)
|
|
51
|
+
emit('span', {
|
|
52
|
+
op,
|
|
53
|
+
...(name ? { name } : {}),
|
|
54
|
+
dur: round(performance.now() - t0),
|
|
55
|
+
status,
|
|
56
|
+
span: id,
|
|
57
|
+
parent: ctx.span,
|
|
58
|
+
start: round(t0 - ctx.startedAt),
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
/** Emit an `err` event for a thrown value. */
|
|
63
|
+
export function emitError(err, source, extra = {}) {
|
|
64
|
+
const e = toError(err);
|
|
65
|
+
emit('err', {
|
|
66
|
+
source,
|
|
67
|
+
name: e.name,
|
|
68
|
+
message: e.message,
|
|
69
|
+
...(e.stack ? { stack: e.stack } : {}),
|
|
70
|
+
...extra,
|
|
71
|
+
fingerprint: errorFingerprint(e.name, e.message, e.stack),
|
|
72
|
+
});
|
|
73
|
+
}
|
|
74
|
+
export function toError(err) {
|
|
75
|
+
if (err instanceof Error)
|
|
76
|
+
return err;
|
|
77
|
+
return new Error(typeof err === 'string' ? err : safeStringify(err));
|
|
78
|
+
}
|
|
79
|
+
// ---------------------------------------------------------------- metrics & log
|
|
80
|
+
export const metrics = {
|
|
81
|
+
count(name, n = 1) {
|
|
82
|
+
emit('metric', { name, value: n, unit: 'count' });
|
|
83
|
+
},
|
|
84
|
+
value(name, value, unit) {
|
|
85
|
+
emit('metric', { name, value, ...(unit ? { unit } : {}) });
|
|
86
|
+
},
|
|
87
|
+
};
|
|
88
|
+
function logAt(level, msg, fields) {
|
|
89
|
+
if (level === 'error' &&
|
|
90
|
+
(fields instanceof Error || (fields && typeof fields === 'object' && 'stack' in fields))) {
|
|
91
|
+
const e = toError(fields);
|
|
92
|
+
emit('log', { level, msg, error: { name: e.name, message: e.message, stack: e.stack } });
|
|
93
|
+
emitError(e, 'log', jobOrRoute());
|
|
94
|
+
return;
|
|
95
|
+
}
|
|
96
|
+
const extra = fields && typeof fields === 'object'
|
|
97
|
+
? fields
|
|
98
|
+
: fields === undefined
|
|
99
|
+
? {}
|
|
100
|
+
: { value: fields };
|
|
101
|
+
emit('log', { ...extra, level, msg });
|
|
102
|
+
}
|
|
103
|
+
export const log = {
|
|
104
|
+
debug: (msg, fields) => logAt('debug', msg, fields),
|
|
105
|
+
info: (msg, fields) => logAt('info', msg, fields),
|
|
106
|
+
warn: (msg, fields) => logAt('warn', msg, fields),
|
|
107
|
+
error: (msg, fields) => logAt('error', msg, fields),
|
|
108
|
+
};
|
|
109
|
+
function jobOrRoute() {
|
|
110
|
+
const ctx = currentContext();
|
|
111
|
+
if (!ctx)
|
|
112
|
+
return {};
|
|
113
|
+
return { ...(ctx.route ? { route: ctx.route } : {}), ...(ctx.job ? { job: ctx.job } : {}) };
|
|
114
|
+
}
|
|
115
|
+
// ---------------------------------------------------------------- console capture
|
|
116
|
+
let consolePatched = false;
|
|
117
|
+
const originalConsole = {};
|
|
118
|
+
/** Route console.* through telemetry so app logs carry the trace id. */
|
|
119
|
+
export function installConsoleCapture() {
|
|
120
|
+
if (consolePatched)
|
|
121
|
+
return;
|
|
122
|
+
consolePatched = true;
|
|
123
|
+
const map = [
|
|
124
|
+
['log', 'info'],
|
|
125
|
+
['info', 'info'],
|
|
126
|
+
['debug', 'debug'],
|
|
127
|
+
['warn', 'warn'],
|
|
128
|
+
['error', 'error'],
|
|
129
|
+
];
|
|
130
|
+
for (const [method, level] of map) {
|
|
131
|
+
originalConsole[method] = console[method];
|
|
132
|
+
console[method] = (...args) => {
|
|
133
|
+
emit('log', { level, msg: format(...args) });
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
// ---------------------------------------------------------------- fetch spans
|
|
138
|
+
let fetchPatched = false;
|
|
139
|
+
let originalFetch;
|
|
140
|
+
/** Record outgoing `fetch` calls as spans (method + host only; no URLs with secrets). */
|
|
141
|
+
export function installFetchInstrumentation() {
|
|
142
|
+
if (fetchPatched || typeof globalThis.fetch !== 'function')
|
|
143
|
+
return;
|
|
144
|
+
fetchPatched = true;
|
|
145
|
+
originalFetch = globalThis.fetch;
|
|
146
|
+
const original = globalThis.fetch.bind(globalThis);
|
|
147
|
+
globalThis.fetch = (async (input, init) => {
|
|
148
|
+
if (!currentContext())
|
|
149
|
+
return original(input, init);
|
|
150
|
+
let name = 'fetch';
|
|
151
|
+
try {
|
|
152
|
+
const url = new URL(typeof input === 'string' || input instanceof URL ? input : input.url);
|
|
153
|
+
const method = init?.method ?? (input instanceof Request ? input.method : 'GET');
|
|
154
|
+
name = `${method.toUpperCase()} ${url.host}`;
|
|
155
|
+
}
|
|
156
|
+
catch { }
|
|
157
|
+
return span('fetch', name, () => original(input, init));
|
|
158
|
+
});
|
|
159
|
+
}
|
|
160
|
+
/** Undo console/fetch patching (tests). */
|
|
161
|
+
export function uninstallInstrumentation() {
|
|
162
|
+
if (consolePatched) {
|
|
163
|
+
for (const [k, v] of Object.entries(originalConsole))
|
|
164
|
+
console[k] = v;
|
|
165
|
+
consolePatched = false;
|
|
166
|
+
}
|
|
167
|
+
if (fetchPatched && originalFetch) {
|
|
168
|
+
globalThis.fetch = originalFetch;
|
|
169
|
+
fetchPatched = false;
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
// ---------------------------------------------------------------- pretty printing
|
|
173
|
+
const COLORS = {
|
|
174
|
+
dim: '\x1b[2m',
|
|
175
|
+
red: '\x1b[31m',
|
|
176
|
+
yellow: '\x1b[33m',
|
|
177
|
+
green: '\x1b[32m',
|
|
178
|
+
cyan: '\x1b[36m',
|
|
179
|
+
reset: '\x1b[0m',
|
|
180
|
+
};
|
|
181
|
+
function pretty(e) {
|
|
182
|
+
const time = new Date(e.ts).toISOString().slice(11, 23);
|
|
183
|
+
const c = (color, s) => `${COLORS[color]}${s}${COLORS.reset}`;
|
|
184
|
+
switch (e.t) {
|
|
185
|
+
case 'req': {
|
|
186
|
+
const color = e.status >= 500 ? 'red' : e.status >= 400 ? 'yellow' : 'green';
|
|
187
|
+
return `${c('dim', time)} ${c(color, String(e.status))} ${e.method} ${e.path} ${c('dim', `${e.dur}ms${e.cold ? ' cold' : ''}`)}`;
|
|
188
|
+
}
|
|
189
|
+
case 'err':
|
|
190
|
+
return `${c('dim', time)} ${c('red', `✖ ${e.name}: ${e.message}`)}${e.stack ? `\n${c('dim', e.stack.split('\n').slice(1, 6).join('\n'))}` : ''}`;
|
|
191
|
+
case 'job':
|
|
192
|
+
return `${c('dim', time)} ${c(e.status === 'ok' ? 'cyan' : 'red', `${e.kind}:${e.name}`)} ${e.status} ${c('dim', `${e.dur}ms`)}`;
|
|
193
|
+
case 'span':
|
|
194
|
+
return `${c('dim', `${time} ↳ ${e.op}${e.name ? ` ${e.name}` : ''} ${e.dur}ms${e.status === 'error' ? ' error' : ''}`)}`;
|
|
195
|
+
case 'log': {
|
|
196
|
+
const { _p, t, ts, app, stage, rev, trace, span: _s, parent, level, msg, ...rest } = e;
|
|
197
|
+
const extra = Object.keys(rest).length ? ` ${c('dim', safeStringify(rest))}` : '';
|
|
198
|
+
const color = level === 'error' ? 'red' : level === 'warn' ? 'yellow' : 'reset';
|
|
199
|
+
return `${c('dim', time)} ${c(color, msg)}${extra}`;
|
|
200
|
+
}
|
|
201
|
+
case 'metric':
|
|
202
|
+
return `${c('dim', `${time} metric ${e.name}=${e.value}${e.unit ? ` ${e.unit}` : ''}`)}`;
|
|
203
|
+
case 'env':
|
|
204
|
+
return `${c('dim', `${time} ${e.runtime} ${e.event}${e.initMs !== undefined ? ` (${e.initMs}ms)` : ''}`)}`;
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
function round(ms) {
|
|
208
|
+
return Math.round(ms * 10) / 10;
|
|
209
|
+
}
|
|
210
|
+
function safeStringify(v) {
|
|
211
|
+
try {
|
|
212
|
+
return JSON.stringify(v);
|
|
213
|
+
}
|
|
214
|
+
catch {
|
|
215
|
+
return String(v);
|
|
216
|
+
}
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=telemetry.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"telemetry.js","sourceRoot":"","sources":["../src/telemetry.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Test helpers for apps and the SDK itself.
|
|
3
|
+
*
|
|
4
|
+
* import { useTestBindings, captureTelemetry } from '@ericminassian/platform/testing';
|
|
5
|
+
*
|
|
6
|
+
* For tests against real (emulated) resources use `plat test`, which starts
|
|
7
|
+
* the AWS Emulator, provisions the app and sets PLATFORM_BINDINGS for vitest.
|
|
8
|
+
*/
|
|
9
|
+
import type { Bindings, TelemetryEvent } from '@ericminassian/platform-core';
|
|
10
|
+
import { type SendClient } from './clients.ts';
|
|
11
|
+
export type { SendClient } from './clients.ts';
|
|
12
|
+
export { createPlatformFetch } from './server.ts';
|
|
13
|
+
export { createWorkerHandler } from './worker.ts';
|
|
14
|
+
/** Complete bindings with sensible test defaults. */
|
|
15
|
+
export declare function testBindings(overrides?: Partial<Bindings>): Bindings;
|
|
16
|
+
/** Install bindings for the current test process (returns them). */
|
|
17
|
+
export declare function useTestBindings(overrides?: Partial<Bindings>): Bindings;
|
|
18
|
+
/** Replace an AWS client with a fake `{ send(command) }`. */
|
|
19
|
+
export declare function mockClient(name: 'ddb' | 'sqs' | 'events' | 's3' | 'ssm' | 'lambda' | 'cognito', send: (command: {
|
|
20
|
+
constructor: {
|
|
21
|
+
name: string;
|
|
22
|
+
};
|
|
23
|
+
input: Record<string, unknown>;
|
|
24
|
+
}) => unknown): SendClient;
|
|
25
|
+
/** Collect telemetry events instead of writing them to stdout. Call `stop()` to restore. */
|
|
26
|
+
export declare function captureTelemetry(): {
|
|
27
|
+
events: TelemetryEvent[];
|
|
28
|
+
stop(): void;
|
|
29
|
+
};
|
|
30
|
+
/** Reset all SDK module state (bindings, clients, caches, telemetry sink). */
|
|
31
|
+
export declare function resetPlatform(): void;
|
package/dist/testing.js
ADDED
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
import { setBindings } from './bindings.js';
|
|
2
|
+
import { resetClients, setClient } from './clients.js';
|
|
3
|
+
import { clearSecretsCache } from './secrets.js';
|
|
4
|
+
import { setTelemetrySink, uninstallInstrumentation } from './telemetry.js';
|
|
5
|
+
export { createPlatformFetch } from './server.js';
|
|
6
|
+
export { createWorkerHandler } from './worker.js';
|
|
7
|
+
/** Complete bindings with sensible test defaults. */
|
|
8
|
+
export function testBindings(overrides = {}) {
|
|
9
|
+
return {
|
|
10
|
+
v: 1,
|
|
11
|
+
app: 'test-app',
|
|
12
|
+
stage: 'test',
|
|
13
|
+
host: 'test-app.localhost',
|
|
14
|
+
url: 'http://test-app.localhost:3000',
|
|
15
|
+
revision: 'dtest',
|
|
16
|
+
region: 'us-east-1',
|
|
17
|
+
queues: {},
|
|
18
|
+
secrets: {
|
|
19
|
+
path: '/platform/apps/test-app/test/secrets/',
|
|
20
|
+
sharedPath: '/platform/apps/test-app/_shared/secrets/',
|
|
21
|
+
names: [],
|
|
22
|
+
},
|
|
23
|
+
...overrides,
|
|
24
|
+
};
|
|
25
|
+
}
|
|
26
|
+
/** Install bindings for the current test process (returns them). */
|
|
27
|
+
export function useTestBindings(overrides = {}) {
|
|
28
|
+
const b = testBindings(overrides);
|
|
29
|
+
setBindings(b);
|
|
30
|
+
return b;
|
|
31
|
+
}
|
|
32
|
+
/** Replace an AWS client with a fake `{ send(command) }`. */
|
|
33
|
+
export function mockClient(name, send) {
|
|
34
|
+
const fake = {
|
|
35
|
+
send: async (command) => send(command),
|
|
36
|
+
};
|
|
37
|
+
setClient(name, fake);
|
|
38
|
+
return fake;
|
|
39
|
+
}
|
|
40
|
+
/** Collect telemetry events instead of writing them to stdout. Call `stop()` to restore. */
|
|
41
|
+
export function captureTelemetry() {
|
|
42
|
+
const events = [];
|
|
43
|
+
setTelemetrySink((e) => events.push(e));
|
|
44
|
+
return { events, stop: () => setTelemetrySink(null) };
|
|
45
|
+
}
|
|
46
|
+
/** Reset all SDK module state (bindings, clients, caches, telemetry sink). */
|
|
47
|
+
export function resetPlatform() {
|
|
48
|
+
setBindings(undefined);
|
|
49
|
+
resetClients();
|
|
50
|
+
clearSecretsCache();
|
|
51
|
+
setTelemetrySink(null);
|
|
52
|
+
uninstallInstrumentation();
|
|
53
|
+
}
|
|
54
|
+
//# sourceMappingURL=testing.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"testing.js","sourceRoot":"","sources":["../src/testing.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,WAAW,EAAE,MAAM,eAAe,CAAC;AAC5C,OAAO,EAAE,YAAY,EAAmB,SAAS,EAAE,MAAM,cAAc,CAAC;AACxE,OAAO,EAAE,iBAAiB,EAAE,MAAM,cAAc,CAAC;AACjD,OAAO,EAAE,gBAAgB,EAAE,wBAAwB,EAAE,MAAM,gBAAgB,CAAC;AAG5E,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAClD,OAAO,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAElD,qDAAqD;AACrD,MAAM,UAAU,YAAY,CAAC,SAAS,GAAsB,EAAE;IAC5D,OAAO;QACL,CAAC,EAAE,CAAC;QACJ,GAAG,EAAE,UAAU;QACf,KAAK,EAAE,MAAM;QACb,IAAI,EAAE,oBAAoB;QAC1B,GAAG,EAAE,gCAAgC;QACrC,QAAQ,EAAE,OAAO;QACjB,MAAM,EAAE,WAAW;QACnB,MAAM,EAAE,EAAE;QACV,OAAO,EAAE;YACP,IAAI,EAAE,uCAAuC;YAC7C,UAAU,EAAE,0CAA0C;YACtD,KAAK,EAAE,EAAE;SACV;QACD,GAAG,SAAS;KACb,CAAC;AACJ,CAAC;AAED,oEAAoE;AACpE,MAAM,UAAU,eAAe,CAAC,SAAS,GAAsB,EAAE;IAC/D,MAAM,CAAC,GAAG,YAAY,CAAC,SAAS,CAAC,CAAC;IAClC,WAAW,CAAC,CAAC,CAAC,CAAC;IACf,OAAO,CAAC,CAAC;AACX,CAAC;AAED,6DAA6D;AAC7D,MAAM,UAAU,UAAU,CACxB,IAAoE,EACpE,IAA6F;IAE7F,MAAM,IAAI,GAAe;QACvB,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,EAAE,CACtB,IAAI,CAAC,OAA4E,CAAC;KACrF,CAAC;IACF,SAAS,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IACtB,OAAO,IAAI,CAAC;AACd,CAAC;AAED,4FAA4F;AAC5F,MAAM,UAAU,gBAAgB;IAC9B,MAAM,MAAM,GAAqB,EAAE,CAAC;IACpC,gBAAgB,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;IACxC,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,GAAG,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,CAAC;AACxD,CAAC;AAED,8EAA8E;AAC9E,MAAM,UAAU,aAAa;IAC3B,WAAW,CAAC,SAAS,CAAC,CAAC;IACvB,YAAY,EAAE,CAAC;IACf,iBAAiB,EAAE,CAAC;IACpB,gBAAgB,CAAC,IAAI,CAAC,CAAC;IACvB,wBAAwB,EAAE,CAAC;AAC7B,CAAC"}
|
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Worker (Lambda Event Function) entry. Apps write:
|
|
3
|
+
*
|
|
4
|
+
* export default defineWorker({
|
|
5
|
+
* queues: { emails: async (msg) => { ... } },
|
|
6
|
+
* events: { 'order.created': async (evt) => { ... } },
|
|
7
|
+
* crons: { nightly: async () => { ... } },
|
|
8
|
+
* });
|
|
9
|
+
*
|
|
10
|
+
* `plat build` generates `export const handler = createWorkerHandler(def)`.
|
|
11
|
+
* One function per stage handles every queue, event subscription, cron and
|
|
12
|
+
* direct invocation; the handler dispatches on the event shape. Each job is
|
|
13
|
+
* auto-instrumented (`job`/`err` telemetry, trace propagation from the
|
|
14
|
+
* producer). SQS batches report partial failures.
|
|
15
|
+
*
|
|
16
|
+
* CONTRACT: used by the CLI build and the control plane. Keep stable.
|
|
17
|
+
*/
|
|
18
|
+
export interface JobContext {
|
|
19
|
+
/** Trace id propagated from whoever enqueued/published/invoked this job. */
|
|
20
|
+
trace: string;
|
|
21
|
+
attempt: number;
|
|
22
|
+
/** Remaining Lambda time in ms. */
|
|
23
|
+
remainingMs(): number;
|
|
24
|
+
}
|
|
25
|
+
export interface QueueMessage<T = unknown> {
|
|
26
|
+
id: string;
|
|
27
|
+
body: T;
|
|
28
|
+
attempt: number;
|
|
29
|
+
sentAt: Date;
|
|
30
|
+
}
|
|
31
|
+
export interface PlatformEvent<T = unknown> {
|
|
32
|
+
id: string;
|
|
33
|
+
type: string;
|
|
34
|
+
detail: T;
|
|
35
|
+
time: Date;
|
|
36
|
+
}
|
|
37
|
+
/** Decoded CloudWatch Logs subscription payload (system use: telemetry processor). */
|
|
38
|
+
export interface LogsBatch {
|
|
39
|
+
logGroup: string;
|
|
40
|
+
logStream: string;
|
|
41
|
+
logEvents: Array<{
|
|
42
|
+
id: string;
|
|
43
|
+
timestamp: number;
|
|
44
|
+
message: string;
|
|
45
|
+
}>;
|
|
46
|
+
}
|
|
47
|
+
type AnyPayload = any;
|
|
48
|
+
export interface WorkerDefinition {
|
|
49
|
+
queues?: Record<string, (message: QueueMessage<AnyPayload>, ctx: JobContext) => unknown | Promise<unknown>>;
|
|
50
|
+
events?: Record<string, (event: PlatformEvent<AnyPayload>, ctx: JobContext) => unknown | Promise<unknown>>;
|
|
51
|
+
crons?: Record<string, (ctx: JobContext) => unknown | Promise<unknown>>;
|
|
52
|
+
/** Direct invocations by name, e.g. the control plane's `deploy`. Return value is the invoke result. */
|
|
53
|
+
invoke?: Record<string, (payload: AnyPayload, ctx: JobContext) => unknown | Promise<unknown>>;
|
|
54
|
+
/** CloudWatch Logs subscription deliveries (system use). */
|
|
55
|
+
logs?: (batch: LogsBatch, ctx: JobContext) => unknown | Promise<unknown>;
|
|
56
|
+
}
|
|
57
|
+
/** Payload shapes the platform sends to the worker besides SQS/EventBridge records. */
|
|
58
|
+
export type DirectPayload = {
|
|
59
|
+
__platform: 'cron';
|
|
60
|
+
name: string;
|
|
61
|
+
trace?: string;
|
|
62
|
+
} | {
|
|
63
|
+
__platform: 'invoke';
|
|
64
|
+
name: string;
|
|
65
|
+
payload: unknown;
|
|
66
|
+
trace?: string;
|
|
67
|
+
};
|
|
68
|
+
export declare function defineWorker<T extends WorkerDefinition>(def: T): T;
|
|
69
|
+
/** Lambda handler for a worker definition. */
|
|
70
|
+
export declare function createWorkerHandler(def: WorkerDefinition): (event: unknown, context: unknown) => Promise<unknown>;
|
|
71
|
+
/** Invoke another named job on this stage's worker asynchronously. */
|
|
72
|
+
export declare function invokeJob(name: string, payload: unknown): Promise<void>;
|
|
73
|
+
export {};
|