woml-cli 1.0.5 → 1.0.6
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/cli.js +511 -36383
- package/dist/custom-notification-provider-host.js +12 -7796
- package/dist/custom-notification-provider-worker.js +4 -170
- package/dist/notification-provider-host.js +40 -26793
- package/dist/script-host-worker.js +6 -1614
- package/dist/script-host.js +13 -9340
- package/package.json +7 -13
- package/dist/cli.js.map +0 -177
- package/dist/custom-notification-provider-host.js.map +0 -97
- package/dist/custom-notification-provider-worker.js.map +0 -10
- package/dist/notification-provider-host.js.map +0 -160
- package/dist/script-host-worker.js.map +0 -11
- package/dist/script-host.js.map +0 -93
|
@@ -1,172 +1,6 @@
|
|
|
1
1
|
// @bun
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
function deepFreeze(value, seen = new WeakSet) {
|
|
6
|
-
if (typeof value !== "object" || value === null)
|
|
7
|
-
return value;
|
|
8
|
-
if (seen.has(value))
|
|
9
|
-
return value;
|
|
10
|
-
seen.add(value);
|
|
11
|
-
for (const child of Object.values(value))
|
|
12
|
-
deepFreeze(child, seen);
|
|
13
|
-
return Object.freeze(value);
|
|
14
|
-
}
|
|
15
|
-
function sensitiveStrings(value, found = []) {
|
|
16
|
-
if (typeof value === "string" && value.length > 0)
|
|
17
|
-
found.push(value);
|
|
18
|
-
else if (Array.isArray(value)) {
|
|
19
|
-
for (const child of value)
|
|
20
|
-
sensitiveStrings(child, found);
|
|
21
|
-
} else if (typeof value === "object" && value !== null) {
|
|
22
|
-
for (const child of Object.values(value))
|
|
23
|
-
sensitiveStrings(child, found);
|
|
24
|
-
}
|
|
25
|
-
return found;
|
|
26
|
-
}
|
|
27
|
-
function redact(message, props, notification) {
|
|
28
|
-
let safe = message;
|
|
29
|
-
for (const value of sensitiveStrings({ props, notification }).sort((left, right) => right.length - left.length)) {
|
|
30
|
-
safe = safe.split(value).join("[REDACTED]");
|
|
31
|
-
}
|
|
32
|
-
return safe.slice(0, 1024);
|
|
33
|
-
}
|
|
34
|
-
function printable(value) {
|
|
35
|
-
if (typeof value === "string")
|
|
36
|
-
return value;
|
|
37
|
-
if (value === undefined || value === null || typeof value === "number" || typeof value === "boolean" || typeof value === "bigint") {
|
|
38
|
-
return String(value);
|
|
39
|
-
}
|
|
40
|
-
try {
|
|
41
|
-
return JSON.stringify(value);
|
|
42
|
-
} catch {
|
|
43
|
-
return Object.prototype.toString.call(value);
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
function managedConsole(props, notification) {
|
|
47
|
-
const sensitive = sensitiveStrings({
|
|
48
|
-
props,
|
|
49
|
-
idempotencyKey: notification.idempotencyKey,
|
|
50
|
-
actions: notification.actions
|
|
51
|
-
}).sort((left, right) => right.length - left.length);
|
|
52
|
-
const write = (...values) => {
|
|
53
|
-
let message = values.map(printable).join(" ");
|
|
54
|
-
for (const value of sensitive) {
|
|
55
|
-
message = message.split(value).join("[REDACTED]");
|
|
56
|
-
}
|
|
57
|
-
process.stderr.write(`${message.slice(0, 4096)}
|
|
58
|
-
`);
|
|
59
|
-
};
|
|
60
|
-
return deepFreeze({
|
|
61
|
-
debug: write,
|
|
62
|
-
error: write,
|
|
63
|
-
info: write,
|
|
64
|
-
log: write,
|
|
65
|
-
warn: write
|
|
66
|
-
});
|
|
67
|
-
}
|
|
68
|
-
function validReceipt(value) {
|
|
69
|
-
if (typeof value !== "object" || value === null || Array.isArray(value)) {
|
|
70
|
-
return false;
|
|
71
|
-
}
|
|
72
|
-
const record = value;
|
|
73
|
-
return Object.keys(record).every((key) => key === "messageId") && (record.messageId === undefined || typeof record.messageId === "string" && record.messageId.length >= 1 && [...record.messageId].length <= 512);
|
|
74
|
-
}
|
|
2
|
+
import{parentPort as f}from"worker_threads";var p=Object.getPrototypeOf(async function(){}).constructor;function i(e,t=new WeakSet){if(typeof e!=="object"||e===null)return e;if(t.has(e))return e;t.add(e);for(let n of Object.values(e))i(n,t);return Object.freeze(e)}function d(e,t=[]){if(typeof e==="string"&&e.length>0)t.push(e);else if(Array.isArray(e))for(let n of e)d(n,t);else if(typeof e==="object"&&e!==null)for(let n of Object.values(e))d(n,t);return t}function g(e,t,n){let o=e;for(let s of d({props:t,notification:n}).sort((r,a)=>a.length-r.length))o=o.split(s).join("[REDACTED]");return o.slice(0,1024)}function w(e){if(typeof e==="string")return e;if(e===void 0||e===null||typeof e==="number"||typeof e==="boolean"||typeof e==="bigint")return String(e);try{return JSON.stringify(e)}catch{return Object.prototype.toString.call(e)}}function h(e,t){let n=d({props:e,idempotencyKey:t.idempotencyKey,actions:t.actions}).sort((s,r)=>r.length-s.length),o=(...s)=>{let r=s.map(w).join(" ");for(let a of n)r=r.split(a).join("[REDACTED]");process.stderr.write(`${r.slice(0,4096)}
|
|
3
|
+
`)};return i({debug:o,error:o,info:o,log:o,warn:o})}function b(e){if(typeof e!=="object"||e===null||Array.isArray(e))return!1;let t=e;return Object.keys(t).every((n)=>n==="messageId")&&(t.messageId===void 0||typeof t.messageId==="string"&&t.messageId.length>=1&&[...t.messageId].length<=512)}class c extends Error{retryable;constructor(e,t){super(e);this.retryable=t;this.name="ManagedServiceError"}}var R=i({http:{async request(e){if(typeof e!=="object"||e===null||typeof e.url!=="string")throw TypeError("services.http.request() requires a request object with a URL.");let t=new URL(e.url);for(let[m,u]of Object.entries(e.query??{}))for(let y of Array.isArray(u)?u:[u])if(y!==void 0&&y!==null)t.searchParams.append(m,String(y));let n=e.timeoutMs??30000;if(!Number.isSafeInteger(n)||n<1||n>86400000)throw TypeError("Managed HTTP timeout must be between 1 ms and 24 hours.");if(e.json!==void 0&&e.text!==void 0)throw TypeError("Managed HTTP accepts only one of json or text.");let o=new Headers(e.headers),s;if(e.json!==void 0){if(!o.has("content-type"))o.set("content-type","application/json");s=JSON.stringify(e.json)}else if(e.text!==void 0)s=e.text;let r;try{r=await fetch(t,{method:e.method?.toUpperCase()??"GET",headers:o,body:s,signal:AbortSignal.timeout(n)})}catch{throw new c("The managed HTTP request failed.",!0)}let a=e.acceptedStatus??{minimum:200,maximum:299};if(r.status<a.minimum||r.status>a.maximum)throw new c(`The managed HTTP response status ${r.status} is outside the accepted range.`,r.status===429||r.status>=500);let l=e.responseType==="text"?await r.text():await r.json();return i({ok:r.ok,status:r.status,headers:Object.fromEntries(r.headers.entries()),data:l,url:r.url,redirected:r.redirected})}}});async function k(e){try{let n=await new p("props","notification","attempt","services","console",`"use strict";
|
|
4
|
+
${e.source}`)(i(structuredClone(e.props)),i(structuredClone(e.notification)),i(structuredClone(e.attempt)),R,h(e.props,e.notification));if(!b(n))return{ok:!1,kind:"non_json",message:"Provider scripts must return {} or { messageId: string }.",retryable:!1};return{ok:!0,receipt:n}}catch(t){let n=t instanceof Error?t.message:String(t);return{ok:!1,kind:t instanceof c?"service_failed":"script_threw",message:g(n,e.props,e.notification),retryable:t instanceof c&&t.retryable}}}if(f===null)throw Error("Custom provider worker requires a parent port.");f.once("message",async(e)=>{f.postMessage(await k(e))});
|
|
75
5
|
|
|
76
|
-
|
|
77
|
-
retryable;
|
|
78
|
-
constructor(message, retryable) {
|
|
79
|
-
super(message);
|
|
80
|
-
this.retryable = retryable;
|
|
81
|
-
this.name = "ManagedServiceError";
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
var services = deepFreeze({
|
|
85
|
-
http: {
|
|
86
|
-
async request(input) {
|
|
87
|
-
if (typeof input !== "object" || input === null || typeof input.url !== "string") {
|
|
88
|
-
throw new TypeError("services.http.request() requires a request object with a URL.");
|
|
89
|
-
}
|
|
90
|
-
const url = new URL(input.url);
|
|
91
|
-
for (const [name, raw] of Object.entries(input.query ?? {})) {
|
|
92
|
-
for (const value of Array.isArray(raw) ? raw : [raw]) {
|
|
93
|
-
if (value !== undefined && value !== null) {
|
|
94
|
-
url.searchParams.append(name, String(value));
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
}
|
|
98
|
-
const timeoutMs = input.timeoutMs ?? 30000;
|
|
99
|
-
if (!Number.isSafeInteger(timeoutMs) || timeoutMs < 1 || timeoutMs > 86400000) {
|
|
100
|
-
throw new TypeError("Managed HTTP timeout must be between 1 ms and 24 hours.");
|
|
101
|
-
}
|
|
102
|
-
if (input.json !== undefined && input.text !== undefined) {
|
|
103
|
-
throw new TypeError("Managed HTTP accepts only one of json or text.");
|
|
104
|
-
}
|
|
105
|
-
const headers = new Headers(input.headers);
|
|
106
|
-
let body;
|
|
107
|
-
if (input.json !== undefined) {
|
|
108
|
-
if (!headers.has("content-type")) {
|
|
109
|
-
headers.set("content-type", "application/json");
|
|
110
|
-
}
|
|
111
|
-
body = JSON.stringify(input.json);
|
|
112
|
-
} else if (input.text !== undefined) {
|
|
113
|
-
body = input.text;
|
|
114
|
-
}
|
|
115
|
-
let response;
|
|
116
|
-
try {
|
|
117
|
-
response = await fetch(url, {
|
|
118
|
-
method: input.method?.toUpperCase() ?? "GET",
|
|
119
|
-
headers,
|
|
120
|
-
body,
|
|
121
|
-
signal: AbortSignal.timeout(timeoutMs)
|
|
122
|
-
});
|
|
123
|
-
} catch {
|
|
124
|
-
throw new ManagedServiceError("The managed HTTP request failed.", true);
|
|
125
|
-
}
|
|
126
|
-
const accepted = input.acceptedStatus ?? { minimum: 200, maximum: 299 };
|
|
127
|
-
if (response.status < accepted.minimum || response.status > accepted.maximum) {
|
|
128
|
-
throw new ManagedServiceError(`The managed HTTP response status ${response.status} is outside the accepted range.`, response.status === 429 || response.status >= 500);
|
|
129
|
-
}
|
|
130
|
-
const data = input.responseType === "text" ? await response.text() : await response.json();
|
|
131
|
-
return deepFreeze({
|
|
132
|
-
ok: response.ok,
|
|
133
|
-
status: response.status,
|
|
134
|
-
headers: Object.fromEntries(response.headers.entries()),
|
|
135
|
-
data,
|
|
136
|
-
url: response.url,
|
|
137
|
-
redirected: response.redirected
|
|
138
|
-
});
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
});
|
|
142
|
-
async function execute(request) {
|
|
143
|
-
try {
|
|
144
|
-
const run = new AsyncFunction("props", "notification", "attempt", "services", "console", `"use strict";
|
|
145
|
-
${request.source}`);
|
|
146
|
-
const result = await run(deepFreeze(structuredClone(request.props)), deepFreeze(structuredClone(request.notification)), deepFreeze(structuredClone(request.attempt)), services, managedConsole(request.props, request.notification));
|
|
147
|
-
if (!validReceipt(result)) {
|
|
148
|
-
return {
|
|
149
|
-
ok: false,
|
|
150
|
-
kind: "non_json",
|
|
151
|
-
message: "Provider scripts must return {} or { messageId: string }.",
|
|
152
|
-
retryable: false
|
|
153
|
-
};
|
|
154
|
-
}
|
|
155
|
-
return { ok: true, receipt: result };
|
|
156
|
-
} catch (error) {
|
|
157
|
-
const raw = error instanceof Error ? error.message : String(error);
|
|
158
|
-
return {
|
|
159
|
-
ok: false,
|
|
160
|
-
kind: error instanceof ManagedServiceError ? "service_failed" : "script_threw",
|
|
161
|
-
message: redact(raw, request.props, request.notification),
|
|
162
|
-
retryable: error instanceof ManagedServiceError && error.retryable
|
|
163
|
-
};
|
|
164
|
-
}
|
|
165
|
-
}
|
|
166
|
-
if (parentPort === null)
|
|
167
|
-
throw new Error("Custom provider worker requires a parent port.");
|
|
168
|
-
parentPort.once("message", async (request) => {
|
|
169
|
-
parentPort.postMessage(await execute(request));
|
|
170
|
-
});
|
|
171
|
-
|
|
172
|
-
//# debugId=09369A9DB883B22564756E2164756E21
|
|
6
|
+
//# debugId=CE6BDB25BA58486364756E2164756E21
|