@trayai/helix-sdk 0.91.0 → 0.93.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/CHANGELOG.md +36 -0
- package/README.md +46 -6
- package/dist/broker/index.d.ts +18 -8
- package/dist/broker/index.js +1 -1
- package/dist/chunk-FTYQLXLV.js +7 -0
- package/dist/chunk-GKP5Y3YJ.js +1 -0
- package/dist/index.d.ts +2 -2
- package/dist/index.js +1 -1
- package/dist/internal/index.d.ts +2 -1
- package/dist/internal/index.js +1 -1
- package/dist/testing/index.d.ts +1 -1
- package/dist/{types-D01XG3C4.d.ts → types-BeTrBJvz.d.ts} +13 -0
- package/package.json +1 -1
- package/dist/chunk-3SDUCOAT.js +0 -7
- package/dist/chunk-H4L4UWIK.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -9,6 +9,42 @@ general availability, minor versions may include breaking changes.
|
|
|
9
9
|
The SDK and [`@trayai/helix-cli`](https://www.npmjs.com/package/@trayai/helix-cli) are
|
|
10
10
|
released together and share a version — install matching versions.
|
|
11
11
|
|
|
12
|
+
## 0.93.0
|
|
13
|
+
|
|
14
|
+
### Added
|
|
15
|
+
|
|
16
|
+
- **Scheduled (cron) functions.** Files under `functions/_scheduled/` can default-export
|
|
17
|
+
`defineSchedule({ cron, timezone?, handler })` to run on a schedule instead of an HTTP
|
|
18
|
+
route. `cron` is a 5-field standard expression; `timezone` is an IANA name (default UTC).
|
|
19
|
+
The handler receives a `ScheduleContext` — the core `ctx` surface plus `ctx.trigger`
|
|
20
|
+
(`scheduledAt`, `firedAt`, `isManual`) and none of the request-derived fields. Schedules
|
|
21
|
+
fire on the deployed platform; `helix deploy` registers them. `ScheduleContext` and
|
|
22
|
+
`ScheduleTrigger` are exported. See the README's "Scheduled functions" section.
|
|
23
|
+
|
|
24
|
+
## 0.92.0
|
|
25
|
+
|
|
26
|
+
### Changed
|
|
27
|
+
|
|
28
|
+
- `ctx.http.authed(...)` now carries request and response bodies byte-for-byte.
|
|
29
|
+
Strings, `Uint8Array`/`ArrayBuffer`, `Blob`, `FormData`, and streams are accepted
|
|
30
|
+
as request bodies and sent verbatim — a string body is no longer rejected (and is
|
|
31
|
+
never JSON-quoted). Plain objects and arrays are still serialized as JSON.
|
|
32
|
+
Binary uploads (e.g. putting an object into S3) now work end-to-end; request
|
|
33
|
+
bodies are capped at 16 MB (use the target API's multipart or chunked upload
|
|
34
|
+
flow for anything larger).
|
|
35
|
+
- Authed response bodies are decoded by content-type: JSON is parsed as before,
|
|
36
|
+
textual types come back as a string, and any other content-type is returned as
|
|
37
|
+
raw bytes (`Uint8Array`), so binary downloads arrive unmangled.
|
|
38
|
+
- Authed redirect (3xx) responses are returned to your code with their `location`
|
|
39
|
+
header rather than being followed.
|
|
40
|
+
- `SdkError` errors from the authenticated HTTP path now include a machine-readable
|
|
41
|
+
`code` field on `error.detail` identifying the failure.
|
|
42
|
+
|
|
43
|
+
### Removed
|
|
44
|
+
|
|
45
|
+
- `SdkError.unsupportedBodyType` is no longer thrown by `ctx.http.authed(...)` —
|
|
46
|
+
previously rejected body types are now sent verbatim.
|
|
47
|
+
|
|
12
48
|
## 0.90.1
|
|
13
49
|
|
|
14
50
|
Changelog corrections only — no code changes. Entries below have been retitled to
|
package/README.md
CHANGED
|
@@ -12,6 +12,7 @@ The runtime SDK for **Helix** — a TypeScript-first platform for building integ
|
|
|
12
12
|
- [The `ctx` object](#the-ctx-object)
|
|
13
13
|
- [Authenticated HTTP](#authenticated-http)
|
|
14
14
|
- [Capability modules](#capability-modules)
|
|
15
|
+
- [Scheduled functions](#scheduled-functions)
|
|
15
16
|
- [Authentication](#authentication)
|
|
16
17
|
- [Configuration](#configuration)
|
|
17
18
|
- [Logging](#logging)
|
|
@@ -68,7 +69,7 @@ export default defineFunction(async (ctx) => {
|
|
|
68
69
|
|
|
69
70
|
## The `ctx` object
|
|
70
71
|
|
|
71
|
-
Every handler receives a `ctx` (`TrayContext`). You can also reach the current context anywhere in the async call tree — including shared helpers — with `getContext()`, so there's no need to thread `ctx` through your code.
|
|
72
|
+
Every HTTP handler receives a `ctx` (`TrayContext`); scheduled handlers receive a `ScheduleContext` (see [Scheduled functions](#scheduled-functions)). You can also reach the current context anywhere in the async call tree — including shared helpers — with `getContext()`, so there's no need to thread `ctx` through your code.
|
|
72
73
|
|
|
73
74
|
| Property | Description |
|
|
74
75
|
|----------|-------------|
|
|
@@ -96,16 +97,18 @@ Every handler receives a `ctx` (`TrayContext`). You can also reach the current c
|
|
|
96
97
|
export default defineFunction(async (ctx) => {
|
|
97
98
|
const slack = ctx.http.authed('slack'); // alias defined in helix.config.ts
|
|
98
99
|
const result = await slack.post('https://slack.com/api/chat.postMessage', {
|
|
99
|
-
body: { channel: 'C123', text: 'hi' }, //
|
|
100
|
+
body: { channel: 'C123', text: 'hi' }, // objects are sent as JSON
|
|
100
101
|
});
|
|
101
102
|
return { ok: result.body.ok };
|
|
102
103
|
});
|
|
103
104
|
```
|
|
104
105
|
|
|
105
|
-
Each method returns `{ status, body?, headers }`. An upstream non-2xx response is **not** thrown — you get the status as a value, matching `ctx.http`.
|
|
106
|
+
Each method returns `{ status, body?, headers }`. An upstream non-2xx response is **not** thrown — you get the status as a value, matching `ctx.http`. Behavior and constraints in this release:
|
|
106
107
|
|
|
107
108
|
- Outbound URLs must be `https:` (otherwise `SdkError.unsupportedScheme`).
|
|
108
|
-
-
|
|
109
|
+
- Request bodies are transmitted byte-for-byte: strings, `Uint8Array`/`ArrayBuffer`, `Blob`, `FormData`, and streams are sent verbatim (a string is never JSON-quoted); plain objects and arrays are serialized as JSON with a default `content-type: application/json` unless you set your own. Request bodies are capped at 16 MB — for anything larger, use the target API's multipart or chunked/resumable upload flow, keeping each part under the cap.
|
|
110
|
+
- Response bodies are decoded by content-type: JSON is parsed, textual types come back as a string, and everything else (e.g. `application/octet-stream`) is returned as raw bytes (`Uint8Array`) — binary downloads arrive unmangled.
|
|
111
|
+
- Redirects are not followed: a 3xx response is returned to your code with its `location` header, and following it is your decision.
|
|
109
112
|
- An unknown alias throws `SdkError.unknownAlias` (the error lists the configured aliases).
|
|
110
113
|
|
|
111
114
|
## Capability modules
|
|
@@ -132,6 +135,43 @@ const file = await ctx.files().get('temp/a.json'); // { data, metadata } | null
|
|
|
132
135
|
|
|
133
136
|
> `list` returns the immediate children of a prefix.
|
|
134
137
|
|
|
138
|
+
## Scheduled functions
|
|
139
|
+
|
|
140
|
+
`functions/_scheduled/` is a reserved namespace for schedule definitions: every module file in it runs on a cron schedule instead of an HTTP route and must default-export `defineSchedule`. Don't create normal HTTP functions there — files in this directory never route:
|
|
141
|
+
|
|
142
|
+
```typescript
|
|
143
|
+
// functions/_scheduled/daily-report.ts
|
|
144
|
+
import { defineSchedule } from '@trayai/helix-sdk';
|
|
145
|
+
|
|
146
|
+
export default defineSchedule({
|
|
147
|
+
cron: '0 6 * * *', // 5-field standard cron
|
|
148
|
+
timezone: 'Europe/London', // IANA timezone name; defaults to UTC
|
|
149
|
+
handler: async (ctx) => {
|
|
150
|
+
ctx.log.info('daily report', { firedAt: ctx.trigger.firedAt });
|
|
151
|
+
},
|
|
152
|
+
});
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
- **`cron`** is a 5-field standard expression (minute, hour, day-of-month, month, day-of-week). An expression that constrains both day-of-month and day-of-week is rejected at build time — leave one of them `*`.
|
|
156
|
+
- **`timezone`** must be an IANA name (`"Europe/London"`); offset forms (`"+05:00"`) are rejected. Omit it for UTC.
|
|
157
|
+
- The handler receives a `ScheduleContext`: the core `ctx` surface (`ctx.http`, `ctx.http.authed()`, `ctx.kv()`, `ctx.files()`, `ctx.log`, `ctx.config`, `ctx.state`, and the invocation identifiers) plus `ctx.trigger` (a `ScheduleTrigger`):
|
|
158
|
+
|
|
159
|
+
| Property | Description |
|
|
160
|
+
|----------|-------------|
|
|
161
|
+
| `ctx.trigger.type` | Always `'schedule'` |
|
|
162
|
+
| `ctx.trigger.scheduledAt` | When the cron said the run should fire (`Date`) |
|
|
163
|
+
| `ctx.trigger.firedAt` | When it actually executed (`Date`) |
|
|
164
|
+
| `ctx.trigger.isManual` | `true` when the run was triggered manually rather than by the schedule |
|
|
165
|
+
|
|
166
|
+
There is no request and no user: the request-derived fields (`ctx.input`, `ctx.method`, `ctx.path`, `ctx.headers`, `ctx.status()`, `ctx.error()`, `ctx.request`, `ctx.identity`) do not exist on a schedule context. Return nothing — there is no response; throwing an error fails the run.
|
|
167
|
+
|
|
168
|
+
Things to know:
|
|
169
|
+
|
|
170
|
+
- Schedules fire **on the deployed platform**. The local dev server does not fire them; `helix deploy` registers the schedules present at deploy time.
|
|
171
|
+
- Overlapping runs are possible — write handlers to tolerate running concurrently.
|
|
172
|
+
- Files and directories starting with `_` below `_scheduled/` are treated as helpers, not schedules — the only files that belong in the directory besides schedule definitions.
|
|
173
|
+
- `getContext()` works inside schedule handlers; shared code can detect a scheduled run by checking for `ctx.trigger`.
|
|
174
|
+
|
|
135
175
|
## Authentication
|
|
136
176
|
|
|
137
177
|
Authenticated features (`ctx.http.authed`, `ctx.kv`, `ctx.files`) require you to be logged in during local development:
|
|
@@ -216,10 +256,10 @@ The mock context is a Proxy: touching an always-present field (`http`, `db`, `lo
|
|
|
216
256
|
|
|
217
257
|
| Import | Contents |
|
|
218
258
|
|--------|----------|
|
|
219
|
-
| `@trayai/helix-sdk` | `defineFunction`, `defineConfig`, `getContext`, `loadConfig`, `requireWorkspaceId`, `createConfigService`, and the public types |
|
|
259
|
+
| `@trayai/helix-sdk` | `defineFunction`, `defineSchedule`, `defineConfig`, `getContext`, `loadConfig`, `requireWorkspaceId`, `createConfigService`, and the public types |
|
|
220
260
|
| `@trayai/helix-sdk/testing` | `runWithContext` |
|
|
221
261
|
|
|
222
|
-
Key exported types include `TrayContext`, `TrayConfig`, `LoadedTrayConfig`, `HttpClient`, `KeyValueStore`, `FileSystemClient`, `Logger`, `ConfigService`, and `WorkspaceIdRequiredError`.
|
|
262
|
+
Key exported types include `TrayContext`, `ScheduleContext`, `ScheduleTrigger`, `TrayConfig`, `LoadedTrayConfig`, `HttpClient`, `KeyValueStore`, `FileSystemClient`, `Logger`, `ConfigService`, and `WorkspaceIdRequiredError`.
|
|
223
263
|
|
|
224
264
|
## Tech stack
|
|
225
265
|
|
package/dist/broker/index.d.ts
CHANGED
|
@@ -16,26 +16,34 @@ interface BrokerDevCallParams {
|
|
|
16
16
|
url: string;
|
|
17
17
|
/** Extra request headers forwarded to the upstream (broker injects auth headers). */
|
|
18
18
|
headers?: Record<string, string>;
|
|
19
|
-
/**
|
|
19
|
+
/** Request body. Strings, byte buffers, blobs, and streams are sent as verbatim
|
|
20
|
+
bytes; plain objects/arrays are JSON-serialized (content-type defaults to
|
|
21
|
+
application/json unless the caller sets one). */
|
|
20
22
|
body?: unknown;
|
|
21
23
|
/** Extra query params appended to any already present on `url`. */
|
|
22
24
|
query?: Record<string, string | string[]>;
|
|
23
|
-
/** Per-call timeout in ms (default 60s
|
|
25
|
+
/** Per-call timeout in ms (default 60s; keep ≥ 45s — the broker's upstream
|
|
26
|
+
budget is 30s plus an internal-hop margin). */
|
|
24
27
|
timeoutMs?: number;
|
|
25
28
|
}
|
|
26
|
-
/** The third-party API's response,
|
|
29
|
+
/** The third-party API's response, verbatim (no envelope). */
|
|
27
30
|
interface UpstreamResponse {
|
|
28
31
|
status: number;
|
|
29
32
|
headers: Record<string, string | string[]>;
|
|
33
|
+
/** Parsed JSON for json content-types, string for textual ones, raw bytes
|
|
34
|
+
(`Uint8Array`) otherwise. Undefined for an empty body. */
|
|
30
35
|
body?: unknown;
|
|
31
36
|
}
|
|
32
37
|
/**
|
|
33
38
|
* Result of a one-shot dev broker call.
|
|
34
39
|
* - `upstream` — the broker accepted the call and forwarded it; carries the
|
|
35
|
-
* third-party API's status/headers/body
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
* `
|
|
40
|
+
* third-party API's status/headers/body verbatim, whatever the status
|
|
41
|
+
* (including unfollowed 3xx redirects with their `location` header).
|
|
42
|
+
* - `brokerError` — a broker-generated error, discriminated by the
|
|
43
|
+
* `x-helix-broker-error` response header (bad/expired token, unknown
|
|
44
|
+
* authentication, malformed request, unreachable upstream…). `brokerStatus`
|
|
45
|
+
* is the broker's own HTTP status, `code` the wire error code from that
|
|
46
|
+
* header, and `body` its error payload.
|
|
39
47
|
*/
|
|
40
48
|
type BrokerDevCallResult = {
|
|
41
49
|
kind: "upstream";
|
|
@@ -43,10 +51,12 @@ type BrokerDevCallResult = {
|
|
|
43
51
|
} | {
|
|
44
52
|
kind: "brokerError";
|
|
45
53
|
brokerStatus: number;
|
|
54
|
+
code: string;
|
|
46
55
|
body: unknown;
|
|
47
56
|
};
|
|
48
57
|
/**
|
|
49
|
-
* Stateless, one-shot call through the credential broker's dev forward
|
|
58
|
+
* Stateless, one-shot call through the credential broker's raw dev forward
|
|
59
|
+
* proxy (`ALL /private/v1/helix/broker/http/raw/dev`).
|
|
50
60
|
*
|
|
51
61
|
* This is the path `ctx.http.authed(...)` takes inside `helix dev`, factored
|
|
52
62
|
* out so CLI tooling (notably the `tray_call_credential_broker` MCP tool) can
|
package/dist/broker/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{
|
|
1
|
+
import{p as t,q as o,r as n,s}from"../chunk-GKP5Y3YJ.js";async function u(e){let i=o({authenticationId:e.authenticationId,method:e.method,url:e.url,body:e.body,headers:e.headers,query:e.query}),r=await s({proxyUrl:t(e.env,"dev"),credentialHeaders:{Authorization:`Bearer ${e.devToken}`},request:i,timeoutMs:e.timeoutMs??n});return r.kind==="brokerError"?{kind:"brokerError",brokerStatus:r.status,code:r.code,body:r.body}:{kind:"upstream",upstream:r.response}}export{u as callBrokerDev};
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
import{d as D,l as c,n as Qe,o as Ze,p as Pe,q as V,s as et}from"./chunk-GKP5Y3YJ.js";var R="X-Helix-Project-Execution-Token",F="X-Tray-Token",pr={mode:"dev",deploymentId:null},Te={...pr},O={};function uo(e){let{internalJwt:t,helixExecutionJwt:r,devToken:n,...o}=e;"internalJwt"in e&&(O.internalJwt=t),"helixExecutionJwt"in e&&(O.helixExecutionJwt=r),"devToken"in e&&(O.devToken=n),Te={...Te,...o}}function w(){return Te}function _(){return O.internalJwt}function P(){return O.helixExecutionJwt}function tt(){return O.devToken}var mo="tray-config-bridge",oe=null;function po(e){oe=e}function b(){if(!oe)throw new Error("Active tray config not seeded. Worker boot must call setActiveConfig() before handlers run.");return oe}function go(){oe=null}import{AsyncLocalStorage as xt}from"async_hooks";import{trace as Ir,SpanKind as Ar,SpanStatusCode as Ae}from"@opentelemetry/api";import{ExportResultCode as kr,W3CTraceContextPropagator as Dr}from"@opentelemetry/core";import{NodeTracerProvider as Or,SimpleSpanProcessor as Fr,BatchSpanProcessor as _r}from"@opentelemetry/sdk-trace-node";import{OTLPTraceExporter as gr}from"@opentelemetry/exporter-trace-otlp-proto";import{OTLPLogExporter as yr}from"@opentelemetry/exporter-logs-otlp-proto";function Ce(e){return D(e).hosts.ingest}function hr(){return P()??""}function rt(){return{[R]:hr()}}function nt(){let e=Ce(b().env);return new gr({url:`${e}/v1/traces`,headers:()=>Promise.resolve(rt())})}function ot(){let e=Ce(b().env);return new yr({url:`${e}/v1/logs`,headers:()=>Promise.resolve(rt())})}import{logs as at,SeverityNumber as ie}from"@opentelemetry/api-logs";import{LoggerProvider as Sr,BatchLogRecordProcessor as xr}from"@opentelemetry/sdk-logs";function z(e){try{return JSON.stringify(e)}catch(t){return JSON.stringify({_serialization_error:t instanceof Error?t.message:String(t)})}}function wr(e){return new TextEncoder().encode(e).length}var it="\u2026[truncated]",br=wr(it),J=4096;function I(e,t=J){let r=new TextEncoder().encode(e);if(r.length<=t)return e;let n=r.subarray(0,t-br);return new TextDecoder("utf-8").decode(n).replace(/�$/,"")+it}function y(e,t=J){return I(z(e),t)}var Er="@trayai/helix-sdk",q,st={debug:{number:ie.DEBUG,text:"DEBUG"},info:{number:ie.INFO,text:"INFO"},warn:{number:ie.WARN,text:"WARN"},error:{number:ie.ERROR,text:"ERROR"}};function vr(){return w().mode==="lambda"?[new xr({exporter:ot()})]:[]}function ct(){if(q!==void 0)return;let e=vr();e.length!==0&&(q=new Sr({processors:e}),at.setGlobalLoggerProvider(q))}function Rr(e,t,r){let n=st[e]??st.info;return{severityNumber:n.number,severityText:n.text,body:t,...r?{attributes:{"tray.log.meta":y(r)}}:{}}}function lt(e,t,r){at.getLogger(Er).emit(Rr(e,t,r))}async function ut(e=2e3){if(q===void 0)return;let t;try{await Promise.race([q.forceFlush(),new Promise(r=>{t=setTimeout(r,e)})])}catch(r){process.stderr.write(`[helix-sdk] otel log flush failed: ${r instanceof Error?r.message:String(r)}
|
|
2
|
+
`)}finally{t!==void 0&&clearTimeout(t)}}function Ie(){let e=process.env.TRAY_PRETTY_LOGS;return e==="1"||e==="true"}function Pr(){if(process.env.NO_COLOR!==void 0)return!1;let e=process.env.FORCE_COLOR;return e!==void 0&&e!=="0"&&e!=="false"?!0:!!process.stdout.isTTY&&process.env.TERM!=="dumb"}function S(e,t){return Pr()?`\x1B[${e}m${t}\x1B[0m`:t}var Tr=5,Cr={FN:"1;35",INFO:"34",AUTH:"35",API:"36",WARN:"33",ERROR:"31",DEBUG:"90"},dt="32",ft="31",se="2",mt="1";function ae(e){return S(Cr[e]??"0",e.padEnd(Tr))}function pt(e,t){return`${ae("FN")} ${S(mt,`${e} ${t}`.trim())}`}function gt(e,t,r,n){let o=e.toUpperCase(),s=`${n?`${S(se,n)} `:""}${ae(o)} ${t}`;return r&&Object.keys(r).length>0&&(s+=` ${S(se,z(r))}`),s}function yt(e){return new Date(e[0]*1e3).toTimeString().slice(0,8)}function ht(e){return`${ae("AUTH")} ${e}`}function wt(e,t,r,n,o){let i=r===void 0?"ERR":String(r),s=S(o==="error"?ft:dt,i);return`${ae("API")} ${e} ${t} \u2192 ${s} ${S(se,`${n}ms`)}`}function bt(e,t,r){let n=t?ft:dt,o=S(n,"\u25CF"),i=S(n,t?"error":"success");return`${o} ${S(mt,e)} ${i} ${S(se,`${r}ms`)}`}function L(e){try{process.stdout.write(e+`
|
|
3
|
+
`)}catch{}}var Et=new xt,Lr=new xt;function x(e){let t=Lr.getStore();t&&(t[e]=!0)}var Nr=/^[0-9a-f]{32}$/;function Br(e){let t=e.replace(/-/g,"").toLowerCase();return Nr.test(t)?t:null}var Mr={0:"STATUS_CODE_UNSET",1:"STATUS_CODE_OK",2:"STATUS_CODE_ERROR"},N=new Map;function vt(e,t,r){let n=N.get(e);n?n[t]=r:N.set(e,{[t]:r})}function v(e,t,r){e.setAttribute(t,y(r))}var Y;function St(e){return`${e[0]}${String(e[1]).padStart(9,"0")}`}function Ur(e){return Math.round(e[0]*1e3+e[1]/1e6)}function Rt(e){try{process.stdout.write(z(e)+`
|
|
4
|
+
`)}catch{}}var ke=class{export(t,r){for(let n of t){let o=n.spanContext().spanId,i=N.get(o),s={...n.attributes};if(i!==void 0){for(let[u,f]of Object.entries(i))typeof f=="string"?s[u]=I(f):typeof f=="object"&&f!==null?s[u]=y(f):s[u]=f;N.delete(o)}let a=Et.getStore(),l=a?Br(a):null;Rt({_otel:"span",traceId:l??n.spanContext().traceId,spanId:o,parentSpanId:n.parentSpanContext?.spanId??"",name:n.name,kind:n.kind,startTimeUnixNano:St(n.startTime),endTimeUnixNano:St(n.endTime),attributes:s,status:{code:Mr[n.status.code]??"STATUS_CODE_UNSET",...n.status.message?{message:I(n.status.message)}:{}}})}r({code:kr.SUCCESS})}forceFlush(){return Promise.resolve()}shutdown(){return Promise.resolve()}},De=class{onStart(t,r){}onEnd(t){N.delete(t.spanContext().spanId)}forceFlush(){return Promise.resolve()}shutdown(){return Promise.resolve()}},Oe=class{onStart(t){let r=t;(r.name==="function"||r.name==="App")&&L(`
|
|
5
|
+
`+pt(String(r.attributes.method??""),String(r.attributes.route??"")))}onEnd(t){let r=t.attributes;switch(t.name){case"log":{let n=t.spanContext().spanId,o=N.get(n)?.properties;L(gt(String(r.level??"info"),String(r.message??""),o,yt(t.startTime)));break}case"auth":L(ht(String(r.alias??"")));break;case"externalApi":{let n=typeof r.statusCode=="number"?r.statusCode:void 0;L(wt(String(r.method??""),String(r.host??""),n,Ur(t.duration),r.status==="error"?"error":"success"));break}}}forceFlush(){return Promise.resolve()}shutdown(){return Promise.resolve()}},Fe=class{constructor(t){this.inner=t}inner;onStart(t,r){this.inner.onStart(t,r)}onEnd(t){t.name!=="log"&&this.inner.onEnd(t)}forceFlush(){return this.inner.forceFlush()}shutdown(){return this.inner.shutdown()}};function jr(){let t=[Ie()?new Oe:new Fr(new ke)];return w().mode==="lambda"&&t.push(new Fe(new _r(nt()))),t.push(new De),t}function $r(){Y===void 0&&(Y=new Or({spanProcessors:jr()}),Y.register({propagator:new Dr}),ct())}async function Kr(e=2e3){let t=[ut(e)];Y!==void 0&&t.push((async()=>{let r;try{await Promise.race([Y.forceFlush(),new Promise(n=>{r=setTimeout(n,e)})])}catch(n){process.stderr.write(`[helix-sdk] otel flush failed: ${n instanceof Error?n.message:String(n)}
|
|
6
|
+
`)}finally{r!==void 0&&clearTimeout(r)}})()),await Promise.all(t)}var E=Ir.getTracer("@trayai/helix-sdk");function Hr({executionId:e,deploymentId:t,triggerType:r="http",routeOrJob:n,startedAt:o,startMs:i,errored:s,errorMessage:a,userId:l,flags:u}){let f=new Date().toISOString(),d=Date.now()-i;if(Ie()){L(`
|
|
7
|
+
`+bt(n,s,d));return}Rt({_otel:"summary",executionId:e,deploymentId:t,triggerType:r,routeOrJob:n,status:s?"error":"success",startedAt:o,finishedAt:f,durationMs:d,userId:l,hasError:s||u.hasError,hasAuth:u.hasAuth,hasExternal:u.hasExternal,hasDb:u.hasDb,errorSummary:s&&a!==null?I(a):null})}async function Ho(e,t){let r=e.startMs??Date.now();$r();let n=!1,o=null;try{return await Et.run(e.executionId,()=>E.startActiveSpan("App",{kind:Ar.SERVER,attributes:{method:e.method,route:e.route,...e.deploymentId?{deploymentId:e.deploymentId}:{}}},async i=>{try{let s=await t(),a=s?.httpResponse?.status??404;return n=a>=400,i.setAttribute("http.response.status_code",a),i.setAttribute("helix.status",n?"error":"success"),i.setStatus({code:n?Ae.ERROR:Ae.OK}),s}catch(s){throw n=!0,o=s instanceof Error?s.message:String(s),i.setAttribute("http.response.status_code",500),i.setAttribute("helix.status","error"),i.setStatus({code:Ae.ERROR,message:o}),s}finally{i.end()}}))}finally{Hr({executionId:e.executionId,deploymentId:e.deploymentId,routeOrJob:`${e.method} ${e.route}`,startedAt:e.startedAt,startMs:r,errored:n,errorMessage:o,userId:e.userId,flags:{hasDb:!1,hasExternal:!1,hasAuth:!1,hasError:!1}}),await Kr()}}var Ct=1024,T=100*1024*1024,Pt=250,Vr=3600,zr=Vr*1e3,Tt=new TextEncoder,Jr=/(^|\/)\.\.(\/|$)/,qr=/[?#]/;function Yr(e){for(let t=0;t<e.length;t++){let r=e.charCodeAt(t);if(r<=31||r===127)return!0}return!1}function A(e,t=Ct){if(e.length===0)throw c.filesPathInvalid("Path must be a non-empty string");ce(e,t)}function _e(e){return e.endsWith("/")?e.slice(0,-1):e}function ce(e,t=Ct){if(e.length===0)return;if(Jr.test(e))throw c.filesPathInvalid("Path contains path traversal segment");if(qr.test(e)||Yr(e))throw c.filesPathInvalid("Path contains illegal characters");let r=e.split("/");if(e.startsWith("/")||e.endsWith("/")||r.some(o=>o===""))throw c.filesPathInvalid("Path must not contain empty path segments");for(let o of r){let i=Tt.encode(o).length;if(i>Pt)throw c.filesPathInvalid(`Path segment exceeds ${Pt} UTF-8 bytes (got ${i})`)}let n=Tt.encode(e).length;if(n<1||n>t)throw c.filesPathInvalid(`Path must be between 1 and ${t} UTF-8 bytes (got ${n})`)}function It(e){if(e>T)throw c.filesValueTooLarge(`File exceeds maximum size of ${T} bytes (got ${e})`,T)}function B(e){let t=e!==void 0?e*1e3:zr;return new Date(Date.now()+t)}import{join as W}from"path";var Xr="files",Wr="files-meta",Gr=1023,Qr=1,Zr=5;function At(e){let t=Math.max(Buffer.byteLength(le(e),"utf8"),Buffer.byteLength(X(e),"utf8"));return Math.max(0,Gr-t-Qr-Zr)}function le(e){return W(e,".helix",Xr)}function X(e){return W(e,".helix",Wr)}function G(e,t){return W(le(e),...t.split("/"))}function ue(e,t){return W(X(e),...t.split("/"))+".json"}function de(e,t){return t.length===0?le(e):G(e,t)}function kt(e,t){return t.length===0?X(e):W(X(e),...t.split("/"))}var Dt="helix-schedule",k=class extends Error{constructor(t){super(`defineSchedule: ${t}`),this.name="ScheduleConfigError"}};function Xo(e){if(typeof e!="object"||e===null)throw new k("expected a config object");let{cron:t,timezone:r="UTC",handler:n}=e;if(typeof t!="string"||t.trim()==="")throw new k("`cron` must be a non-empty string");let o=t.trim().split(/\s+/).length;if(o!==5)throw new k(`\`cron\` must be a 5-field standard expression (minute hour day-of-month month day-of-week); got ${o} field(s) in "${t}"`);if(typeof r!="string"||!en(r))throw new k(`\`timezone\` must be a valid IANA timezone name (e.g. "Europe/London"); got "${String(r)}"`);if(typeof n!="function")throw new k("`handler` must be a function");return Object.freeze({kind:Dt,cron:t.trim(),timezone:r,concurrent:!0,handler:n})}function Wo(e){return typeof e=="object"&&e!==null&&e.kind===Dt&&typeof e.handler=="function"}function en(e){if(!/^[A-Za-z]/.test(e))return!1;try{return new Intl.DateTimeFormat(void 0,{timeZone:e}),!0}catch{return!1}}import{SpanKind as tn}from"@opentelemetry/api";function fe(e,t,r){let n=E.startSpan("log",{kind:tn.INTERNAL});n.setAttribute("message",t),n.setAttribute("level",e),r&&vt(n.spanContext().spanId,"properties",r),n.end(),lt(e,t,r)}function ti(){return{info:(e,t)=>fe("info",e,t),warn:(e,t)=>fe("warn",e,t),error:(e,t)=>fe("error",e,t),debug:(e,t)=>fe("debug",e,t)}}function oi(){try{return b().config??{}}catch(e){return console.warn(`[helix-sdk] Config not loaded: ${e instanceof Error?e.message:String(e)}. Using empty config.`),{}}}import rn from"ky";import{context as Le,trace as nn,SpanKind as pe,SpanStatusCode as Ot}from"@opentelemetry/api";async function me(e,t={}){let r=w(),{env:n}=b(),o,i={};if(r.mode==="lambda"){let a=_(),l=P(),u=!!(a&&a.trim().length>0),f=!!(l&&l.trim().length>0);if(!u&&!f)throw c.missingExecutionCredentials();u&&(i[F]=a),f&&(i[R]=l),r.deploymentId&&(i[Qe]=r.deploymentId),o=Pe(n,"runtime")}else{let a=tt();if(!a)throw c.missingTrayToken();i.Authorization=`Bearer ${a}`,o=Pe(n,"dev")}let s;try{s=await et({proxyUrl:o,credentialHeaders:i,request:e,timeoutMs:t.timeout,executionId:r.executionId})}catch(a){let l=a instanceof Error?a.message??String(a):String(a);throw c.brokerError(0,l)}if(s.kind==="brokerError"){let a=s.code===Ze?"credential broker does not support the raw proxy endpoints required by this SDK version \u2014 deploy a newer broker or pin an older SDK":s.message;throw c.brokerError(s.status,a,y(s.body),s.code)}return s.response}var on=["get","post","put","patch","delete","head","options"],Ft="[stream body omitted]";function _t(e){return typeof ReadableStream<"u"&&e instanceof ReadableStream?Ft:e instanceof ArrayBuffer?`[binary body: ${e.byteLength} bytes]`:ArrayBuffer.isView(e)?`[binary body: ${e.byteLength} bytes]`:typeof Blob<"u"&&e instanceof Blob?`[binary body: ${e.size} bytes]`:e}function Ne(e){try{return new URL(e).hostname}catch{return e}}function sn(e,t,r,n){let o=Ne(t),i="externalApi",s={kind:pe.CLIENT};return E.startActiveSpan(i,s,async a=>(a.setAttributes({method:e,host:o}),v(a,"request",{url:t,method:e,...r!==void 0?{body:_t(r)}:{}}),n(a)))}function Be(e,t,r){e.setAttribute("status",t),e.setStatus(t==="success"?{code:Ot.OK}:{code:Ot.ERROR,message:r}),e.end()}var an=16;async function cn(e,t){let r=e.clone().body;return r?Lt(r,t):new Uint8Array(0)}async function Lt(e,t){let r=e.getReader(),n=[],o=0,i=0;try{for(;;){let{done:l,value:u}=await r.read();if(l)break;if(!u||u.byteLength===0){if(i+=1,i>=an)break;continue}i=0;let f=t+1-o;if(u.byteLength>=f){n.push(u.slice(0,f)),o+=f;break}n.push(u),o+=u.byteLength}}finally{r.cancel().catch(()=>{}),r.releaseLock()}let s=new Uint8Array(o),a=0;for(let l of n)s.set(l,a),a+=l.byteLength;return s}async function Nt(e,t,r){if("kyResponse"in r)try{let n=await cn(r.kyResponse,J),o=new TextDecoder("utf-8").decode(n,{stream:!0}),i;try{i=JSON.parse(o)}catch{i=o}v(e,"response",i)}catch{v(e,"response",{status:t})}else v(e,"response",_t(r.bodyValue))}async function ln(e,t){if(t instanceof ReadableStream){let r=e.body??t;try{let[n,o]=r.tee(),i=new Request(e,{body:n,duplex:"half"}),s=await Lt(o,J);return{body:new TextDecoder("utf-8").decode(s,{stream:!0}),request:i}}catch{return{body:Ft}}}return typeof t=="string"?{body:t}:{}}function xi(){let e=rn.create({});function t(n){return(o,i)=>{let s=Le.active(),a,l=!1,u=(d,m)=>{a&&!l&&(l=!0,Be(a,d,m))},f=e.extend({hooks:{beforeRequest:[async(d,m)=>{let p=await ln(d,m.body),ne=p.body;if(a||(a=E.startSpan("externalApi",{kind:pe.CLIENT},s)),a.setAttributes({method:d.method.toUpperCase(),host:Ne(d.url)}),v(a,"request",{url:d.url,method:d.method.toUpperCase(),...ne!==void 0?{body:ne}:{}}),l=!1,x("hasExternal"),p.request)return p.request}],beforeRetry:[d=>{u("error","retry"),a=void 0,l=!1}],afterResponse:[async(d,m,p)=>{a&&(a.setAttribute("statusCode",p.status),await Nt(a,p.status,{kyResponse:p}),p.ok?u("success"):i?.throwHttpErrors===!1&&(x("hasError"),u("error",`HTTP ${p.status}`)))}],beforeError:[d=>(x("hasError"),u("error",d.message),d)]}});return a=E.startSpan("externalApi",{kind:pe.CLIENT},s),a.setAttributes({method:n.toUpperCase(),host:Ne(String(o))}),Le.with(nn.setSpan(Le.active(),a),()=>{let d=n==="options"?f(o,{...i,method:"OPTIONS"}):f[n](o,i);return d.catch(m=>{x("hasError"),u("error",m instanceof Error?m.message:String(m))}),d})}}let r=Object.fromEntries(on.map(n=>[n,t(n)]));return{...e,...r,authed(n){return un(n)}}}function un(e){let r=b().authentications??{};if(!r[e])throw c.unknownAlias(e,Object.keys(r));let n=r[e];function o(i){return(s,a={})=>{let l=i.toUpperCase();return sn(l,s,a.body,async u=>{x("hasAuth");let f=E.startSpan("auth",{kind:pe.INTERNAL});f.setAttribute("alias",e),f.setAttribute("id",n),f.end();try{let d=V({authenticationId:n,method:l,url:s,body:a.body,headers:a.headers,query:a.query}),m=await me(d,{timeout:a.timeout});return u.setAttribute("statusCode",m.status),await Nt(u,m.status,{bodyValue:m.body}),Be(u,"success"),m}catch(d){throw x("hasError"),d instanceof c&&d.detail.kind==="broker_error"&&d.detail.status>0&&u.setAttribute("statusCode",d.detail.status),Be(u,"error",d instanceof Error?d.message:String(d)),d}})}}return{get:o("get"),post:o("post"),put:o("put"),patch:o("patch"),delete:o("delete"),head:o("head"),options:o("options")}}import{SpanKind as bn,SpanStatusCode as jt}from"@opentelemetry/api";function Q(e){let t=e.trimStart().match(/^([A-Za-z]+)/);return t?t[1].toUpperCase():"QUERY"}var dn=18e4,Bt=dn-1e4,fn=2e3;async function Mt(e,t,r){let n=new Set(["FINISHED","FAILED","ABORTED"]),o=Date.now(),i=0;for(;Date.now()-o<Bt;){let s=await e(t,"DescribeStatement",{Id:r}),a=s.Status;if(n.has(a))return s;let l=Math.min(fn,200*2**i),u=l/2+Math.random()*(l/2),f=Bt-(Date.now()-o);await new Promise(d=>setTimeout(d,Math.min(u,f))),i++}throw c.dbCallFailed(`statement polling exceeded budget after ${Date.now()-o}ms`)}var mn=new Set(["SELECT","WITH","SHOW"]),pn=new Set(["INSERT","UPDATE","DELETE","MERGE"]);function gn(e){if(!e.clusterIdentifier&&!e.workgroupName)throw c.dbInvalidParameters("either clusterIdentifier or workgroupName is required");if(e.clusterIdentifier&&e.workgroupName)throw c.dbInvalidParameters("clusterIdentifier and workgroupName are mutually exclusive (Provisioned vs Serverless)");if(!e.database)throw c.dbInvalidParameters("database is required");if(e.clusterIdentifier&&!e.dbUser)throw c.dbInvalidParameters("dbUser is required when using clusterIdentifier (Provisioned)");if(!e.region)throw c.dbInvalidParameters("region is required")}function yn(e,t){let r=null;if(typeof t=="string")try{r=JSON.parse(t)}catch{}else t!==null&&typeof t=="object"&&(r=t);let n=typeof r?.__type=="string"?r.__type:void 0,o=typeof r?.message=="string"?r.message:void 0;if(n&&o)return c.dbQueryFailed(`${n}: ${o}`);let i=typeof t=="string"?I(t):y(t);return c.dbCallFailed(i)}function hn(e){if(e==null||typeof e!="string")return e;try{return JSON.parse(e)}catch{throw c.dbCallFailed("upstream body not JSON: "+e.slice(0,200))}}function wn(e,t){return typeof t!="number"||t<0?{}:mn.has(e)?{rowsRead:t}:pn.has(e)?{rowsWritten:t}:{}}function Ut(e){async function t(r,n,o){let i=V({authenticationId:e,method:"POST",url:`https://redshift-data.${r}.amazonaws.com/`,body:o,headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`RedshiftData.${n}`}});try{let{status:s,body:a}=await me(i);if(s>=400)throw yn(s,a);return hn(a)}catch(s){if(s instanceof c)throw s;let a=s instanceof Error?s.message??String(s):String(s);throw c.dbCallFailed(a,s instanceof Error?s:void 0)}}return{system:"redshift",validate:gn,async execute(r,n){let o=Q(n),i={Sql:n,Database:r.database,...r.clusterIdentifier&&{ClusterIdentifier:r.clusterIdentifier,DbUser:r.dbUser},...r.workgroupName&&{WorkgroupName:r.workgroupName},...r.statementName&&{StatementName:r.statementName}},s=await t(r.region,"ExecuteStatement",i),a=s,l=typeof a?.Id=="string"?a.Id:void 0;if(!l){let p=y(s);throw c.dbCallFailed(`ExecuteStatement response missing Id; got: ${p}`)}let u=await Mt(t,r.region,l),f=u.Status;if(f==="FAILED"){let p=typeof u.Error=="string"?u.Error:"statement failed";throw c.dbQueryFailed(`${p} (statement: ${l})`)}if(f==="ABORTED")throw c.dbQueryFailed(`statement aborted (statement: ${l})`);let d=wn(o,u.ResultRows);return u.HasResultSet===!1?{result:{rowsAffected:u.ResultRows??0},metadata:d}:{result:await t(r.region,"GetStatementResult",{Id:l}),metadata:d}}}}var Me=64*1024;function Sn(e){return e.length>Me?`${e.slice(0,Me)}...[truncated]`:e}function xn(e,t,r,n,o){e.setAttributes({system:t.system,statement:o,namespace:r.database,operation:n})}function En(e,t,r){let n=typeof t=="string"?t:JSON.stringify(t);return n.length>Me?v(e,"result",{truncated:!0,size:n.length}):v(e,"result",t),r.rowsRead!==void 0&&e.setAttribute("rowsRead",r.rowsRead),r.rowsWritten!==void 0&&e.setAttribute("rowsWritten",r.rowsWritten),n}async function vn(e,t,r){let n=Q(r),o=Sn(r);return E.startActiveSpan("database",{kind:bn.CLIENT},async i=>{xn(i,e,t,n,o);try{x("hasDb");let{result:s,metadata:a}=await e.execute(t,r),l=En(i,s,a);return i.setAttribute("status","success"),i.setStatus({code:jt.OK}),l}catch(s){x("hasError");let a=s instanceof Error?s.message:String(s);throw i.setAttribute("status","error"),i.setStatus({code:jt.ERROR,message:a}),s}finally{i.end()}})}function Rn(e){let r=b().authentications??{};if(!r[e])throw c.unknownAlias(e,Object.keys(r));let n=r[e],o=Ut(n);function i(s,a){return o.validate(s),vn(o,s,a)}return{parameters(s){return{sql(a){return i(s,a)}}},sql(s){return i({},s)}}}import{createStorage as An}from"unstorage";var $t=1024,Ue=250*1024,Pn=new TextEncoder,Tn=/(^|\/)\.\.(\/|$)/,Cn=/[?#]/,In=/[\u0000-\u001F\u007F]/;function Kt(e){if(e.length===0)throw c.kvKeyInvalid("Key must be a non-empty string");if(Tn.test(e))throw c.kvKeyInvalid("Key contains path traversal segment");if(Cn.test(e)||In.test(e))throw c.kvKeyInvalid("Key contains illegal characters");if(e.startsWith("/")||e.endsWith("/")||e.split("/").some(r=>r===""))throw c.kvKeyInvalid("Key must not contain empty path segments");let t=Pn.encode(e).length;if(t<1||t>$t)throw c.kvKeyInvalid(`Key must be between 1 and ${$t} UTF-8 bytes (got ${t})`)}function Ht(e){let t;try{t=JSON.stringify(e)}catch{throw c.kvValueInvalid("Value must be JSON-serializable")}if(t===void 0)throw c.kvValueInvalid("Value must be JSON-serializable");let r=Buffer.byteLength(t,"utf8");if(r>Ue)throw c.kvValueTooLarge(`Value exceeds maximum size of ${Ue} bytes (got ${r})`,Ue)}function Z(e){Kt(e)}function ge(e,t){let r=e[t];if(typeof r!="function")throw new Error(`KV driver is missing ${t}`);return r}function Vt(e){let t=ge(e,"getItem"),r=ge(e,"setItem"),n=ge(e,"removeItem"),o=ge(e,"hasItem"),i=e.getKeys;return{...e,getItem(s,a){return Z(s),t(s,a)},setItem(s,a,l){return Z(s),r(s,a,l)},removeItem(s,a){return Z(s),n(s,a)},hasItem(s,a){return Z(s),o(s,a)},getKeys(s,a){return s.length>0&&Z(s),i(s,a)}}}function ye(e){return An({driver:Vt(e)})}import{defineDriver as kn}from"unstorage";function Dn(e){try{return JSON.parse(e)}catch{return e}}var On=kn(e=>{let{client:t}=e;return{name:"helix-kv",async getItem(r){let n=await t.get(r);return n===null?null:JSON.stringify(n)},async setItem(r,n){await t.set(r,Dn(n))},async removeItem(r){await t.delete(r)},async hasItem(r){return await t.has(r)},async getKeys(){throw new Error("KV key listing is not supported")}}});function zt(e){return On({client:e})}import Ln from"ky";import{z as h}from"zod";async function M(e){let t=e.headers.get("content-type")??"",r=await e.text();if(r.length!==0)return t.includes("application/json")?JSON.parse(r):r}function Jt(e){return D(e).hosts.api}function Fn(e){return`/private/v1/helix/projects/${encodeURIComponent(e)}/storage/kv`}function _n(e){return e.split("/").map(encodeURIComponent).join("/")}function ee(e,t,r){return`${e}${Fn(t)}/${_n(r)}`}var Nn=6e4,je=h.lazy(()=>h.union([h.string(),h.number(),h.boolean(),h.null(),h.array(je),h.record(je)])),Bn=h.object({projectId:h.string(),key:h.string(),value:je,type:h.enum(["string","number","boolean","null","array","object"]),organizationId:h.string(),scope:h.string(),createdBy:h.string(),createdAt:h.number(),updatedBy:h.string(),updatedAt:h.number()});function Mn(){let e=_(),t=P(),r=!!(e&&e.trim().length>0),n=!!(t&&t.trim().length>0);if(!r&&!n)throw c.missingExecutionCredentials();let o={Accept:"application/json"};return r&&(o[F]=e),n&&(o[R]=t),o}function Un(e){if(e!==null&&typeof e=="object"){let t=e;if(typeof t.message=="string")return t.message;if(typeof t.error=="string")return t.error}return String(e??"unknown error")}function he(e,t){throw c.kvCallFailed(e,Un(t),y(t))}async function we(e,t,r={}){try{let n=await Ln(t,{method:e,headers:Mn(),...r.json!==void 0?{json:r.json}:{},throwHttpErrors:!1,timeout:Nn}),o=e==="head"?void 0:await M(n);return{status:n.status,body:o}}catch(n){if(n instanceof c)throw n;let o=n instanceof Error?n.message??String(n):String(n);throw c.kvCallFailed(0,o)}}function qt(e){let t=Jt(e.env),{projectId:r}=e;return{async get(n){let{status:o,body:i}=await we("get",ee(t,r,n));if(o===404)return null;(o<200||o>=300)&&he(o,i);let s=Bn.safeParse(i);if(!s.success)throw c.kvCallFailed(o,"platform returned malformed KeyValueEntry",y(i));return s.data.value},async set(n,o){let{status:i,body:s}=await we("put",ee(t,r,n),{json:{value:o}});(i<200||i>=300)&&he(i,s)},async delete(n){let{status:o,body:i}=await we("delete",ee(t,r,n));o!==204&&he(o,i)},async has(n){let{status:o,body:i}=await we("head",ee(t,r,n));if(o===200)return!0;if(o===404)return!1;he(o,i)}}}function be(e){return{getItem:(t,r)=>e.getItem(t,r),removeItem:(t,r)=>e.removeItem(t,r),hasItem:(t,r)=>e.hasItem(t,r),setItem:async(t,r,n)=>{Ht(r),await e.setItem(t,r,n)}}}function jn(){let e=b();if(e.kind!=="provisioned")throw c.kvRequiresProvisioning();return{projectId:e.projectId,env:e.env}}function Yt(e){let t=jn(),r=e??qt(t),n=ye(zt(r));return be(n)}import $n from"unstorage/drivers/memory";var $e;function Kn(){return $e||($e=ye($n())),$e}function Xt(){return be(Kn())}function Hn(){return typeof __TRAY_SDK_MODE__<"u"?__TRAY_SDK_MODE__==="lambda":w().mode==="lambda"}function Rs(){return Hn()?Yt():Xt()}import{createHash as Jn}from"crypto";import{mkdir as qn,readFile as er,readdir as tr,rm as Gt,unlink as Yn,writeFile as Qt}from"fs/promises";import{dirname as Xn}from"path";async function Vn(e){let t=e.getReader(),r=[],n=0;for(;;){let{done:o,value:i}=await t.read();if(o)break;if(i){if(n+=i.byteLength,n>T)throw await t.cancel(),c.filesValueTooLarge(`File exceeds maximum size of ${T} bytes (got more than ${T})`,T);r.push(i)}}return Buffer.concat(r)}async function U(e){return Buffer.isBuffer(e)?e:typeof e=="string"?Buffer.from(e,"utf-8"):e instanceof ReadableStream?Vn(e):Buffer.from(e)}var zn={pdf:"application/pdf",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",json:"application/json",txt:"text/plain",html:"text/html",htm:"text/html",css:"text/css",js:"application/javascript",xml:"application/xml",zip:"application/zip"},Wt="application/octet-stream";function Se(e){let t=e.lastIndexOf(".");if(t===-1||t===e.length-1)return Wt;let r=e.slice(t+1).toLowerCase();return zn[r]??Wt}function $(){let e=w().projectRoot;if(!e)throw c.filesNotAvailable();return e}async function j(e){try{return await e()}catch(t){if(t instanceof c)throw t;let r=t?.code;throw r?c.filesCallFailed(0,`Local file storage operation failed: ${r}`):c.filesCallFailed(0,"Local file storage operation failed: unknown error")}}function xe(e,t){return{path:e,size:t.size,contentType:t.contentType,lastModified:new Date(t.lastModified),etag:t.etag}}async function Ke(e){try{let t=await er(ue($(),e),"utf-8");return JSON.parse(t)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Zt(e){await qn(Xn(e),{recursive:!0})}async function Wn(e,t){let r=de(e,t),n;try{n=await tr(r,{withFileTypes:!0})}catch(o){if(o.code==="ENOENT")return[];throw o}return n.filter(o=>o.isFile()).map(o=>t.length===0?o.name:`${t}/${o.name}`)}async function rr(e,t){let r=de(e,t),n;try{n=await tr(r,{withFileTypes:!0})}catch(i){if(i.code==="ENOENT")return[];throw i}let o=[];for(let i of n){let s=t.length===0?i.name:`${t}/${i.name}`;i.isDirectory()?o.push(...await rr(e,s)):i.isFile()&&o.push(s)}return o}function nr(){return{async put(e,t,r){return j(async()=>{let n=$(),o=await U(t),i=r?.contentType??Se(e),s=Jn("sha1").update(o).digest("hex"),a=new Date,l=G(n,e);await Zt(l),await Qt(l,o);let u={size:o.byteLength,contentType:i,lastModified:a.toISOString(),etag:s},f=ue(n,e);return await Zt(f),await Qt(f,JSON.stringify(u)),xe(e,u)})},async get(e){return j(async()=>{let t=await Ke(e);return t?{data:await er(G($(),e)),metadata:xe(e,t)}:null})},async head(e){return j(async()=>{let t=await Ke(e);return t?xe(e,t):null})},async delete(e){return j(async()=>{let t=$();await Promise.all([G(t,e),ue(t,e)].map(async r=>{try{await Yn(r)}catch(n){if(n.code!=="ENOENT")throw n}}))})},async deleteMany(e){return j(async()=>{let t=$(),r=await rr(t,e);return await Promise.all([Gt(de(t,e),{recursive:!0,force:!0}),Gt(kt(t,e),{recursive:!0,force:!0})]),{deleted:r.length}})},async list(e,t){return j(async()=>{let r=$(),n=t?.limit??100,i=(await Wn(r,e??"")).slice(0,n);return{files:(await Promise.all(i.map(async a=>{let l=await Ke(a);return l?xe(a,l):null}))).filter(a=>a!==null),cursor:null}})},async getUploadUrl(e,t){let r=w().devServerUrl;if(!r)throw c.filesNotAvailable();return{url:`${r}/_helix/files/${e}`,expiresAt:B(t?.expiresIn)}},async getDownloadUrl(e,t){let r=w().devServerUrl;if(!r)throw c.filesNotAvailable();return{url:`${r}/_helix/files/${e}`,expiresAt:B(t?.expiresIn)}}}}import{createHash as no}from"crypto";function Ee(e){return D(e).hosts.api}function Gn(e){return`/private/v1/helix/files/projects/${encodeURIComponent(e)}`}function te(e,t){return`${e}${Gn(t)}`}function K(e,t,r){return`${te(e,t)}/${encodeURIComponent(r)}`}function ve(e,t,r){return`${K(e,t,r)}/upload`}function or(e,t,r){return`${K(e,t,r)}/download`}function ir(e,t,r){return`${K(e,t,r)}/signed-url`}function sr(e,t,r,n){let o=new URLSearchParams({name:n});return r&&o.set("parentFolder",r),`${te(e,t)}/file?${o.toString()}`}function ar(e,t,r,n){let o=new URLSearchParams({limit:String(n)});return r&&o.set("id",r),`${te(e,t)}?${o.toString()}`}import Ve from"ky";import{z as g}from"zod";var ze=6e4,cr=g.object({id:g.string(),workspaceId:g.string(),projectId:g.string(),parentFolder:g.string().nullable().optional(),name:g.string(),size:g.number().nullable().optional(),objectType:g.enum(["Folder","File"]),contentType:g.string().nullable().optional(),createdAt:g.string(),updatedAt:g.string()}),Qn=g.object({signedURL:g.string()}),Zn=g.object({path:g.array(g.object({id:g.string(),name:g.string()})),elements:g.array(cr)});function Je(){let e=_(),t=P(),r=!!(e&&e.trim().length>0),n=!!(t&&t.trim().length>0);if(!r&&!n)throw c.missingExecutionCredentials();let o={Accept:"application/json"};return r&&(o[F]=e),n&&(o[R]=t),o}function lr(e){if(e!==null&&typeof e=="object"){let t=e;if(typeof t.message=="string")return t.message;if(typeof t.error=="string")return t.error}return String(e??"unknown error")}function C(e,t){throw c.filesCallFailed(e,lr(t),y(t))}function eo(e,t){return e===400&&lr(t).toLowerCase()==="resource not found"}async function to(e){let t=new Response(e),r=t.headers.get("content-type")??"multipart/form-data",n=await t.arrayBuffer();return{body:Buffer.from(n),contentType:r}}async function H(e,t,r={}){try{let n=await Ve(t,{method:e,headers:Je(),...r.json!==void 0?{json:r.json}:{},throwHttpErrors:!1,timeout:ze}),o=await M(n);return{status:n.status,body:o}}catch(n){if(n instanceof c)throw n;let o=n instanceof Error?n.message:String(n);throw c.filesCallFailed(0,o)}}function He(e,t){let r=cr.safeParse(t);if(!r.success)throw c.filesCallFailed(e,"platform returned malformed ObjectMetadata",y(t));return r.data}function ur(e){let t=Ee(e.env),{projectId:r}=e;return{async createMetadata(n){let{status:o,body:i}=await H("post",te(t,r),{json:n});return(o<200||o>=300)&&C(o,i),He(o,i)},async getByName(n,o){let{status:i,body:s}=await H("get",sr(t,r,n,o));return i===404||eo(i,s)?null:((i<200||i>=300)&&C(i,s),He(i,s))},async getById(n){let{status:o,body:i}=await H("get",K(t,r,n));return o===404?null:((o<200||o>=300)&&C(o,i),He(o,i))},async listChildren(n,o){let{status:i,body:s}=await H("get",ar(t,r,n,o));(i<200||i>=300)&&C(i,s);let a=Zn.safeParse(s);if(!a.success)throw c.filesCallFailed(i,"platform returned malformed listing",y(s));return a.data},async uploadContent(n,o,i,s){let a=new FormData;a.append("fileUploadContentInput",new Blob([new Uint8Array(o)],{type:s}),i);let{body:l,contentType:u}=await to(a),f;try{f=await Ve(ve(t,r,n),{method:"post",headers:{...Je(),"content-type":u},body:new Uint8Array(l),throwHttpErrors:!1,timeout:ze})}catch(m){if(m instanceof c)throw m;let p=m instanceof Error?m.message:String(m);throw c.filesCallFailed(0,p)}let d=await M(f);(f.status<200||f.status>=300)&&C(f.status,d)},async downloadContent(n){let o;try{o=await Ve(or(t,r,n),{method:"get",headers:Je(),throwHttpErrors:!1,timeout:ze})}catch(s){if(s instanceof c)throw s;let a=s instanceof Error?s.message:String(s);throw c.filesCallFailed(0,a)}if(o.status<200||o.status>=300){let s=await M(o);C(o.status,s)}let i=await o.arrayBuffer();return Buffer.from(i)},async getSignedDownloadUrl(n){let{status:o,body:i}=await H("get",ir(t,r,n));(o<200||o>=300)&&C(o,i);let s=Qn.safeParse(i);if(!s.success)throw c.filesCallFailed(o,"platform returned malformed signed URL response",y(i));return s.data.signedURL},async deleteById(n){let{status:o,body:i}=await H("delete",K(t,r,n));o===204||o===404||(o<200||o>=300)&&C(o,i)}}}function qe(e){return e.split("/").filter(t=>t.length>0)}function Ye(e){return e instanceof c&&e.detail.kind==="files_call_failed"&&e.detail.status===409}async function ro(e,t,r){let n=await e.getByName(t,r);if(n)return n;try{return await e.createMetadata({parentFolder:t,objectType:"Folder",name:r})}catch(o){if(Ye(o)){let i=await e.getByName(t,r);if(i)return i}throw o}}async function Xe(e,t){let r=qe(t),n=r[r.length-1],o;for(let i of r.slice(0,-1))o=(await ro(e,o,i)).id;return{parentFolder:o,name:n}}async function re(e,t){let r=qe(t),n=r[r.length-1],o;for(let i of r.slice(0,-1)){let s=await e.getByName(o,i);if(!s||s.objectType!=="Folder")return null;o=s.id}return{parentFolder:o,name:n}}async function We(e,t){if(t.length===0)return;let r=qe(t),n;for(let o of r){let i=await e.getByName(n,o);if(!i||i.objectType!=="Folder")return null;n=i.id}return n}var oo=500,io=8;async function so(e,t,r){let n=new Array(e.length),o=0;async function i(){for(;o<e.length;){let s=o++;n[s]=await r(e[s])}}return await Promise.all(Array.from({length:Math.min(t,e.length)},i)),n}function ao(){let e=b();if(e.kind!=="provisioned")throw c.filesRequiresProvisioning();return{projectId:e.projectId,env:e.env}}function co(e){return no("sha1").update(`${e.id}:${e.updatedAt}:${e.size??0}`).digest("hex")}function Re(e,t,r){return{path:e,size:t.size??0,contentType:t.contentType??r??"application/octet-stream",lastModified:new Date(t.updatedAt),etag:co(t)}}async function dr(e,t,r,n){try{return await e.createMetadata({parentFolder:t,objectType:"File",contentType:n,name:r})}catch(o){if(Ye(o)){let i=await e.getByName(t,r);if(i)return i}throw o}}async function fr(e,t){let{elements:r}=await e.listChildren(t,oo);return(await so(r,io,async o=>{let i=o.objectType==="Folder"?await fr(e,o.id):1;return await e.deleteById(o.id),i})).reduce((o,i)=>o+i,0)}function mr(e){let t=ao(),r=e??ur(t),n=Ee(t.env),{projectId:o}=t;return{async put(i,s,a){let{parentFolder:l,name:u}=await Xe(r,i),f=await U(s),d=a?.contentType??Se(i),m=await r.getByName(l,u);if(m&&m.objectType!=="File")throw c.filesCallFailed(409,`A folder already exists at "${i}"`);let p=m??await dr(r,l,u,d);await r.uploadContent(p.id,f,u,d);let ne=await r.getById(p.id);return Re(i,ne??p,d)},async get(i){let s=await re(r,i);if(!s)return null;let a=await r.getByName(s.parentFolder,s.name);return!a||a.objectType!=="File"?null:{data:await r.downloadContent(a.id),metadata:Re(i,a)}},async head(i){let s=await re(r,i);if(!s)return null;let a=await r.getByName(s.parentFolder,s.name);return!a||a.objectType!=="File"?null:Re(i,a)},async delete(i){let s=await re(r,i);if(!s)return;let a=await r.getByName(s.parentFolder,s.name);a&&await r.deleteById(a.id)},async deleteMany(i){let s=await We(r,i);if(s===null)return{deleted:0};let a=await fr(r,s);return i.length>0&&s!==void 0&&await r.deleteById(s),{deleted:a}},async list(i,s){let a=await We(r,i??"");if(a===null)return{files:[],cursor:null};let l=s?.limit??100,{elements:u}=await r.listChildren(a,l);return{files:u.filter(d=>d.objectType==="File").map(d=>Re(i?`${i}/${d.name}`:d.name,d)),cursor:null}},async getUploadUrl(i,s){let{parentFolder:a,name:l}=await Xe(r,i),f=await r.getByName(a,l)??await dr(r,a,l,s?.contentType);return{url:ve(n,o,f.id),expiresAt:B(s?.expiresIn)}},async getDownloadUrl(i,s){let a=await re(r,i),l=a?await r.getByName(a.parentFolder,a.name):null;if(!l||l.objectType!=="File")throw c.filesCallFailed(404,`File not found: ${i}`);return{url:await r.getSignedDownloadUrl(l.id),expiresAt:B(s?.expiresIn)}}}}function Ge(e,t){let r=t?.maxPathBytes;return{async put(n,o,i){A(n,r);let s=await U(o);return It(s.byteLength),e.put(n,s,i)},async get(n){return A(n,r),e.get(n)},async head(n){return A(n,r),e.head(n)},async delete(n){return A(n,r),e.delete(n)},async deleteMany(n){let o=_e(n);return ce(o,r),e.deleteMany(o)},async list(n,o){let i=_e(n??"");return ce(i,r),e.list(i,o)},async getUploadUrl(n,o){return A(n,r),e.getUploadUrl(n,o)},async getDownloadUrl(n,o){return A(n,r),e.getDownloadUrl(n,o)}}}function lo(){return typeof __TRAY_SDK_MODE__<"u"?__TRAY_SDK_MODE__==="lambda":w().mode==="lambda"}function ya(){if(lo())return Ge(mr());let e=w().projectRoot;return Ge(nr(),{maxPathBytes:e?At(e):void 0})}export{uo as a,w as b,mo as c,po as d,b as e,go as f,Et as g,Lr as h,x as i,v as j,$r as k,Kr as l,E as m,Hr as n,Ho as o,ti as p,oi as q,xi as r,Rn as s,Rs as t,A as u,G as v,ue as w,ya as x,Dt as y,k as z,Xo as A,Wo as B};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
var w=new Set(["production"]),s=new Map,l={name:"production",exposedName:"us1",displayName:"production",hosts:{api:"https://api.tray.io",broker:"https://api.tray.io/private/v1/code",ingest:"https://api.tray.io/private/v1/helix/otlp",weaver:"https://weaver.tray.io",app:"https://app.tray.io",projectHost:"helix-app.ai",dashboard:"https://app.helix.tray.ai",auth:"https://auth.tray.io"},login:{storePrefix:"PROD",appUrl:"https://app.tray.io",cookieName:"prod_tray_lid",cookieDomain:"tray.io"}};s.set(l.name,l);var v=["api","broker","ingest","weaver","app","projectHost","dashboard"],k=["auth"],_=["storePrefix","appUrl","cookieName","cookieDomain"];function S(e){if(!e.name||typeof e.name!="string")throw new Error("EnvironmentProfile.name must be a non-empty string");if(!e.exposedName||typeof e.exposedName!="string")throw new Error("EnvironmentProfile.exposedName must be a non-empty string");if(!e.displayName||typeof e.displayName!="string")throw new Error("EnvironmentProfile.displayName must be a non-empty string");if(!e.hosts||typeof e.hosts!="object")throw new Error("EnvironmentProfile.hosts must be an object");if(!e.login||typeof e.login!="object")throw new Error("EnvironmentProfile.login must be an object");for(let r of v)if(typeof e.hosts[r]!="string"||!e.hosts[r])throw new Error(`EnvironmentProfile.hosts.${r} must be a non-empty string`);for(let r of k){let n=e.hosts[r];if(n!==void 0&&(typeof n!="string"||!n))throw new Error(`EnvironmentProfile.hosts.${r} must be a non-empty string when set`)}for(let r of _)if(typeof e.login[r]!="string"||!e.login[r])throw new Error(`EnvironmentProfile.login.${r} must be a non-empty string`)}function R(e,r){return e.name===r.name&&e.exposedName===r.exposedName&&e.displayName===r.displayName&&v.every(n=>e.hosts[n]===r.hosts[n])&&k.every(n=>e.hosts[n]===r.hosts[n])&&_.every(n=>e.login[n]===r.login[n])}function L(e){S(e);let r=s.get(e.name);if(r){if(R(r,e))return;throw new Error(`EnvironmentProfile.name "${e.name}" is already registered with different values`)}for(let n of s.values())if(n.exposedName===e.exposedName)throw new Error(`EnvironmentProfile.exposedName "${e.exposedName}" is already used by "${n.name}"`);s.set(e.name,e)}function P(e){return s.has(e)}function K(e){return s.get(e)}function h(e){let r=s.get(e);if(!r)throw new Error(`Unknown environment: ${e}`);return r}function V(){return[...s.keys()]}function M(){return[...s.values()].map(e=>e.exposedName)}function N(e){for(let r of s.values())if(r.exposedName===e)return r.name}var p=Symbol.for("@trayai/helix-sdk.forcedEnvironment");function T(e){let r=globalThis;if(e===void 0||e.trim()===""){delete r[p];return}let n=e.trim(),t=N(n);if(t){r[p]=t;return}if(P(n)){r[p]=n;return}throw new Error(`Unknown environment: ${n}`)}function Y(){return globalThis[p]}function J(){return[...s.values()].filter(e=>!w.has(e.name))}function G(){T(void 0),s.clear(),s.set(l.name,{...l,hosts:{...l.hosts},login:{...l.login}})}var c=class e extends Error{detail;constructor(r){super(I(r)),this.name="SdkError",this.detail=r}get kind(){return this.detail.kind}static unknownAlias(r,n){return new e({kind:"unknown_alias",alias:r,available:n})}static inputValidationFailed(r){return new e({kind:"input_validation_failed",fields:r})}static outputValidationFailed(r){return new e({kind:"output_validation_failed",fields:r})}static configLoadFailed(r){return new e({kind:"config_load_failed",cause:r})}static brokerError(r,n,t,a){return new e({kind:"broker_error",status:r,message:n,body:t,code:a})}static unsupportedBodyType(r){return new e({kind:"unsupported_body_type",actualType:r})}static unsupportedScheme(r){return new e({kind:"unsupported_scheme",scheme:r})}static missingExecutionCredentials(){return new e({kind:"missing_execution_credentials"})}static missingTrayToken(){return new e({kind:"missing_tray_token"})}static dbCallFailed(r,n){return new e({kind:"db_call_failed",message:r,cause:n})}static dbQueryFailed(r){return new e({kind:"db_query_failed",message:r})}static dbInvalidParameters(r){return new e({kind:"db_invalid_parameters",message:r})}static kvKeyInvalid(r){return new e({kind:"kv_key_invalid",message:r})}static kvValueInvalid(r){return new e({kind:"kv_value_invalid",message:r})}static kvValueTooLarge(r,n){return new e({kind:"kv_value_too_large",message:r,maxBytes:n})}static kvNotAvailable(){return new e({kind:"kv_not_available"})}static kvCallFailed(r,n,t){return new e({kind:"kv_call_failed",status:r,message:n,body:t})}static kvRequiresProvisioning(){return new e({kind:"kv_requires_provisioning"})}static filesPathInvalid(r){return new e({kind:"files_path_invalid",message:r})}static filesValueInvalid(r){return new e({kind:"files_value_invalid",message:r})}static filesValueTooLarge(r,n){return new e({kind:"files_value_too_large",message:r,maxBytes:n})}static filesNotAvailable(){return new e({kind:"files_not_available"})}static filesCallFailed(r,n,t){return new e({kind:"files_call_failed",status:r,message:n,body:t})}static filesRequiresProvisioning(){return new e({kind:"files_requires_provisioning"})}};function Q(e){return e instanceof c}function I(e){switch(e.kind){case"unknown_alias":return`Unknown auth alias "${e.alias}". Available: ${e.available.join(", ")||"(none)"}`;case"input_validation_failed":return`Input validation failed for fields: ${e.fields.join(", ")}`;case"output_validation_failed":return`Output validation failed for fields: ${e.fields.join(", ")}`;case"config_load_failed":return`Config load failed: ${e.cause}`;case"broker_error":return e.code?`broker error: ${e.status} ${e.code}: ${e.message}`:`broker error: ${e.status} ${e.message}`;case"unsupported_body_type":return`unsupported body type: ${e.actualType}`;case"unsupported_scheme":return`unsupported scheme: ${e.scheme} (only https supported)`;case"missing_execution_credentials":return"missing execution credentials: at least one of internalJwt / helixExecutionJwt must be set before an authed broker/KV call";case"missing_tray_token":return"Not logged in. Run `helix login` to authenticate before making authed HTTP calls in dev.";case"db_call_failed":return`Database call failed: ${e.message}`;case"db_query_failed":return`Database query failed: ${e.message}`;case"db_invalid_parameters":return`Invalid database parameters: ${e.message}`;case"kv_key_invalid":return`Invalid KV key: ${e.message}`;case"kv_value_invalid":return e.message;case"kv_value_too_large":return e.message;case"kv_not_available":return"Key-value store is not available in this environment";case"kv_call_failed":return`KV platform error: ${e.status} ${e.message}`;case"kv_requires_provisioning":return"Key-value store requires a provisioned project (run helix project set)";case"files_path_invalid":return`Invalid file path: ${e.message}`;case"files_value_invalid":return e.message;case"files_value_too_large":return e.message;case"files_not_available":return"File storage is not available in this environment";case"files_call_failed":return`Files platform error: ${e.status} ${e.message}`;case"files_requires_provisioning":return"File storage requires a provisioned project (run helix project set)"}}import{z as u}from"zod";var E="x-helix-destination-url",x="x-helix-authentication-id",D="x-helix-deployment-id",b="x-execution-id",U="x-helix-broker-error",re="route_not_found",$=new Set([E,x,D,"authorization","x-tray-token","x-helix-project-execution-token","host","content-length","connection","transfer-encoding","te","upgrade","keep-alive","expect","proxy-authorization","proxy-connection","accept-encoding","x-request-id",b]);function A(e){let r=e.toLowerCase();return $.has(r)||r.startsWith("x-tray-internal-")}var q=u.object({error:u.object({code:u.string(),message:u.string(),issues:u.array(u.unknown()).optional()})});function ne(e,r){let n=`${h(e).hosts.api}/private/v1/helix/broker/http/raw`;return r==="dev"?`${n}/dev`:n}function O(e){return typeof e=="string"||e instanceof ArrayBuffer||ArrayBuffer.isView(e)||typeof Blob<"u"&&e instanceof Blob||typeof FormData<"u"&&e instanceof FormData||e instanceof URLSearchParams||typeof ReadableStream<"u"&&e instanceof ReadableStream}function te(e){let r=new URL(e.url);if(r.protocol!=="https:")throw c.unsupportedScheme(r.protocol.replace(/:$/,""));if(e.query!==void 0)if(e.query instanceof URLSearchParams)for(let[i,o]of e.query.entries())r.searchParams.append(i,o);else for(let[i,o]of Object.entries(e.query))for(let m of Array.isArray(o)?o:[o])r.searchParams.append(i,m);let n;e.headers===void 0?n=[]:e.headers instanceof Headers?n=Array.from(e.headers.entries()):Array.isArray(e.headers)?n=e.headers:n=Object.entries(e.headers);let t=n.filter(([i])=>!A(i)),a=e.body!==void 0&&e.body!==null,d,f,g=!1;return a&&(O(e.body)?(d=e.body,g=typeof ReadableStream<"u"&&e.body instanceof ReadableStream):(d=JSON.stringify(e.body),t.some(([o])=>o.toLowerCase()==="content-type")||(f="application/json"))),{authenticationId:e.authenticationId,method:e.method.toUpperCase(),destinationUrl:r.toString(),headers:t,body:d,isStreamBody:g,defaultContentType:f}}var C=6e4;function j(e){return e.includes("json")}function B(e){return e.startsWith("text/")||e.includes("xml")||e.includes("urlencoded")||e.includes("javascript")||e.includes("ecmascript")}function H(e,r){if(e.byteLength===0)return;let n=r.toLowerCase();if(j(n)){let t=new TextDecoder("utf-8").decode(e);try{return JSON.parse(t)}catch{return t}}return B(n)?new TextDecoder("utf-8").decode(e):e}function F(e){let r={};for(let[n,t]of e.entries())r[n.toLowerCase()]=t;return r}async function oe(e){let{request:r}=e,n=new Headers;for(let[i,o]of r.headers)n.append(i,o);r.defaultContentType&&!n.has("content-type")&&n.set("content-type",r.defaultContentType),n.set(E,r.destinationUrl),n.set(x,r.authenticationId);for(let[i,o]of Object.entries(e.credentialHeaders))n.set(i,o);e.executionId&&n.set(b,e.executionId);let t={method:r.method,headers:n,redirect:"manual",signal:AbortSignal.timeout(e.timeoutMs??C)};r.body!==void 0&&(t.body=r.body,r.isStreamBody&&(t.duplex="half"));let a=await fetch(e.proxyUrl,t),d=a.headers.get(U);if(d!==null){let i=await a.text(),o=i,m=i||d;try{o=JSON.parse(i);let y=q.safeParse(o);y.success&&(m=y.data.error.message)}catch{}return{kind:"brokerError",status:a.status,code:d,message:m,body:o}}let f=new Uint8Array(await a.arrayBuffer()),g=a.headers.get("content-type")??"";return{kind:"upstream",response:{status:a.status,headers:F(a.headers),body:H(f,g)}}}export{L as a,P as b,K as c,h as d,V as e,M as f,N as g,T as h,Y as i,J as j,G as k,c as l,Q as m,D as n,re as o,ne as p,te as q,C as r,oe as s};
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as h3 from 'h3';
|
|
2
2
|
import { ZodType } from 'zod';
|
|
3
|
-
import { F as FunctionHandler, D as DefineFunctionOptions, a as DefineScheduleConfig, S as ScheduleDefinition, P as PlatformContext } from './types-
|
|
4
|
-
export { b as DbCallParameters, c as DbClient, d as FileSystemClient, H as HttpClient, K as KeyValueStore, L as Logger, e as ScheduleContext, f as ScheduleHandler, g as ScheduleTrigger, h as SqlBuilder, T as TrayContext, U as UnvalidatedInput } from './types-
|
|
3
|
+
import { F as FunctionHandler, D as DefineFunctionOptions, a as DefineScheduleConfig, S as ScheduleDefinition, P as PlatformContext } from './types-BeTrBJvz.js';
|
|
4
|
+
export { b as DbCallParameters, c as DbClient, d as FileSystemClient, H as HttpClient, K as KeyValueStore, L as Logger, e as ScheduleContext, f as ScheduleHandler, g as ScheduleTrigger, h as SqlBuilder, T as TrayContext, U as UnvalidatedInput } from './types-BeTrBJvz.js';
|
|
5
5
|
import { T as TrayConfig, L as LoadedTrayConfig, W as WatchErrorPhase } from './sdk-config-_xIe9XvP.js';
|
|
6
6
|
export { P as ProvisionedTrayConfig, S as SdkRuntimeConfig, U as UnprovisionedTrayConfig, a as WORKSPACE_ID_REQUIRED_CODE, b as WorkspaceIdRequiredError, g as getSdkConfig, l as loadConfig, c as loadedTrayConfigSchema, p as projectIdSchema, r as requireWorkspaceId, d as resolveConfigFile, w as workspaceIdSchema } from './sdk-config-_xIe9XvP.js';
|
|
7
7
|
export { a as ENVIRONMENT_VALUES, E as Environment, e as environmentSchema } from './env-schema-DkgTG5b0.js';
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{A as Ce,B as ve,b as T,g as U,h as I,i as N,j as C,k as q,l as M,m as $,n as Z,o as ge,p as K,q as z,r as G,s as J,t as Q,x as X,y as he,z as ye}from"./chunk-3SDUCOAT.js";import{a as B,b as me}from"./chunk-WUCX7RZO.js";import{b as H,e as A,i as W,l as g,m as V}from"./chunk-H4L4UWIK.js";import{randomUUID as _e}from"crypto";import{SpanStatusCode as ne,SpanKind as Re}from"@opentelemetry/api";import{defineEventHandler as Pe,getMethod as Le,getRequestURL as Fe,getHeaders as se,getHeader as oe}from"h3";import{readBody as we,getQuery as Ee,getRouterParams as ke}from"h3";async function Y(e,t){let r=await Se(e),n=Ee(e),o=ke(e)??{},s={...n,...r,...o};return t?xe(s,t):s}async function Se(e){try{let t=await we(e);return t&&typeof t=="object"?t:(t!=null&&t!==""&&console.warn("[helix-sdk] Request body present but not a JSON object \u2014 ignored"),{})}catch(t){if(t instanceof Error&&"statusCode"in t&&t.statusCode===400){let n=new Error("Malformed request body");throw n.statusCode=400,n.data={message:"Request body is not valid JSON"},n}let r=e.method?.toUpperCase();if(r==="GET"||r==="HEAD"||r==="DELETE")return{};throw t}}function xe(e,t){let r=t.safeParse(e);if(!r.success){let n=new Error("Input validation failed");throw n.statusCode=400,n.data=r.error.flatten(),n}return r.data}var v=class extends Error{statusCode;constructor(t,r){super(r),this.statusCode=t,this.name="HttpError"}};function ee(e){return t=>{e.node.res.statusCode=t}}function te(){return(e,t)=>{throw new v(e,t)}}function re(e,t){let{statusCode:r,message:n}=Te(t.detail);return e.node.res.statusCode=r,{error:n,statusCode:r}}function Te(e){switch(e.kind){case"unknown_alias":return{statusCode:400,message:"Unknown authentication alias"};case"input_validation_failed":return{statusCode:400,message:"Input validation failed"};case"output_validation_failed":return{statusCode:500,message:"Internal server error"};case"config_load_failed":return{statusCode:500,message:"Configuration error"};case"broker_error":return{statusCode:502,message:"Broker error"};case"unsupported_body_type":return{statusCode:400,message:"Unsupported request body type"};case"unsupported_scheme":return{statusCode:400,message:"Unsupported URL scheme"};case"missing_execution_credentials":return{statusCode:401,message:"Missing execution credentials"};case"missing_tray_token":return{statusCode:500,message:"Missing Tray token"};case"db_call_failed":return{statusCode:502,message:e.message};case"db_query_failed":return{statusCode:502,message:`Database query failed: ${e.message}`};case"db_invalid_parameters":return{statusCode:400,message:e.message};case"kv_key_invalid":return{statusCode:400,message:e.message};case"kv_value_invalid":return{statusCode:400,message:e.message};case"kv_value_too_large":return{statusCode:400,message:e.message};case"kv_not_available":return{statusCode:501,message:"Key-value store is not available in this environment"};case"kv_call_failed":return{statusCode:502,message:"Key-value store request failed"};case"kv_requires_provisioning":return{statusCode:500,message:"Internal server error"};case"files_path_invalid":return{statusCode:400,message:e.message};case"files_value_invalid":return{statusCode:400,message:e.message};case"files_value_too_large":return{statusCode:400,message:e.message};case"files_not_available":return{statusCode:501,message:"File storage is not available in this environment"};case"files_call_failed":return{statusCode:502,message:"File storage request failed"};case"files_requires_provisioning":return{statusCode:500,message:"Internal server error"};default:return{statusCode:500,message:`Unhandled error kind: ${e.kind}`}}}var Ie=["authorization","x-tray-token","set-cookie","x-kong-request-id","traceparent","x-real-ip","cookie"];function be(e){return e.toLowerCase().includes("tray_lid")}function b(e){let t={};for(let[r,n]of Object.entries(e))if(!Ie.includes(r.toLowerCase())){if(r.toLowerCase()==="cookie"&&n){let o=n.split(";").map(s=>s.trim()).filter(s=>{let a=s.split("=")[0].trim();return!be(a)}).join("; ");o&&(t[r]=o);continue}t[r]=n}return t}function je(e,t){let{inputSchema:r,outputSchema:n}=Ue(t),o=e;return Pe(async s=>{let a=T(),{executionId:i,userId:c,deploymentId:f}=Ne(a,s),p=Date.now(),y=new Date().toISOString(),m=Le(s),l=Fe(s).pathname,u=z(),h=K(),E=`${m} ${l}`;q();let O={hasDb:!1,hasExternal:!1,hasAuth:!1,hasError:!1};return De(()=>I.run(O,()=>U.run(i,async()=>{let k=await Oe(s,r);if(!k.ok)return{response:k.response,errored:!1,errorMessage:null};let pe=Me(s,k.input,u,h,m,l,i,f,c);return He(o,pe,n,s,h,i,f,{method:m,path:l,rawInput:k.input})})),{executionId:i,deploymentId:f,routeOrJob:E,startedAt:y,startMs:p,userId:c,flags:O})})}async function De(e,t){let r=!1,n=null;try{let o=await e();return r=o.errored,n=o.errorMessage,o.response}finally{Z({...t,errored:r,errorMessage:n}),await M()}}async function Oe(e,t){try{return{ok:!0,input:await Y(e,t)}}catch(r){let n=qe(e,r);if(n)return{ok:!1,response:n};throw r}}async function He(e,t,r,n,o,s,a,i){return $.startActiveSpan("function",{root:!0,kind:Re.SERVER,attributes:{method:i.method,route:i.path,executionId:s,...a?{deploymentId:a}:{}}},async c=>{t.traceId=c.spanContext().traceId;let f=b(se(n));C(c,"input",i.rawInput),C(c,"request",{method:i.method,path:i.path,headers:f,body:i.rawInput});let p=!1,y=null,m,l;try{let u=await B.run(t,()=>e(t));if(m=u,u==null)n.node.res.statusCode=204,l="";else if(u instanceof Response)l=u;else if(r){let h=r.safeParse(u);if(!h.success){let E=Object.keys(h.error.flatten().fieldErrors);throw o.error("Output validation failed",{fields:E,executionId:s}),g.outputValidationFailed(E)}l=h.data}else l=u}catch(u){p=!0,y=u instanceof Error?u.message:String(u),N("hasError"),l=Ae(u,n,o,s)}finally{We(c,n,{errored:p,errorMessage:y,handlerResult:m,response:l})}return{response:l,errored:p,errorMessage:y}})}function Ae(e,t,r,n){if(e instanceof v)return t.node.res.statusCode=e.statusCode,{error:e.message,statusCode:e.statusCode};if(V(e))return re(t,e);r.error("Unhandled error in handler",{error:e instanceof Error?e.message:String(e),executionId:n}),t.node.res.statusCode=500;let o=process.env.NODE_ENV==="development";return{error:o&&e instanceof Error?e.message:"Internal server error",statusCode:500,...o&&e instanceof Error&&e.stack?{stack:e.stack}:{}}}function We(e,t,r){e.setAttribute("statusCode",t.node.res.statusCode),!r.errored&&r.handlerResult!==void 0&&C(e,"output",r.handlerResult),C(e,"response",r.response);let n=I.getStore();e.setAttribute("hasAuth",n?.hasAuth??!1),e.setAttribute("hasExternal",n?.hasExternal??!1),e.setAttribute("hasDb",n?.hasDb??!1),e.setAttribute("status",r.errored?"error":"success");let o=r.errored||(n?.hasError??!1);e.setStatus({code:o?ne.ERROR:ne.OK,...r.errorMessage?{message:r.errorMessage}:{}}),e.end()}function Ue(e){if(!e)return{inputSchema:void 0,outputSchema:void 0};if(e instanceof Object&&"_def"in e)return{inputSchema:e,outputSchema:void 0};if(typeof e=="object"&&("input"in e||"output"in e)){let t=e;return{inputSchema:t.input,outputSchema:t.output}}return{inputSchema:e,outputSchema:void 0}}function Ne(e,t){let r=e.mode==="lambda",n=(r?e.executionId:oe(t,"x-tray-execution-id"))??_e(),o=(r?e.userId:oe(t,"x-tray-user-id"))??null,s=r?e.deploymentId??null:null;return{executionId:n,userId:o,deploymentId:s}}function qe(e,t){if(!(t instanceof Error)||!("statusCode"in t)||!("data"in t))return null;let r=t.statusCode,n=t.data;e.node.res.statusCode=r;let o=n&&typeof n=="object"&&"fieldErrors"in n?n.fieldErrors:void 0;return{error:"Input validation failed",statusCode:r,...o?{fields:Object.keys(o)}:{}}}function Me(e,t,r,n,o,s,a,i,c){return{input:t,method:o,path:s,headers:b(se(e)),http:G(),db:f=>J(f),kv:()=>Q(),files:()=>X(),log:n,config:r,status:ee(e),error:te(),state:{},request:e,executionId:a,deploymentId:i,userId:c,identity:c!==null?{user:{id:c}}:null,traceId:""}}function $e(e){return e}import{resolve as _}from"path";import{existsSync as ae}from"fs";import{loadConfig as Ke}from"c12";import{z as d}from"zod";import{z as Ze}from"zod";var Be=["production"],S=Ze.string().refine(e=>H(e),e=>({message:`Invalid enum value. Expected ${A().map(t=>`'${t}'`).join(" | ")}, received '${e}'`}));var R=d.string().uuid("projectId must be a valid UUID"),P=d.string().min(1,"workspaceId must be a non-empty string"),ze=d.object({name:d.string().min(1,"name is required"),projectId:R.optional(),workspaceId:P.optional(),env:S.default("production"),authentications:d.record(d.string()).optional().default({}),config:d.record(d.unknown()).optional().default({})}),ie=d.object({name:d.string().min(1,"name is required"),workspaceId:P.optional(),env:S,authentications:d.record(d.string()),config:d.record(d.unknown())}),Ve=d.discriminatedUnion("kind",[ie.extend({kind:d.literal("provisioned"),projectId:R}),ie.extend({kind:d.literal("unprovisioned")})]),de=["helix","tray"],ce=["ts","mts","cts","js","mjs","cjs"];function x(e){for(let t of de)for(let r of ce){let n=_(e,`${t}.config.${r}`);if(ae(n))return n}}function Ge(e){for(let t of de)if(ce.some(r=>ae(_(e,`${t}.config.${r}`))))return t;return"helix"}function L(e){return{name:Ge(e),cwd:e,rcFile:!1,globalRc:!1,packageJson:!1,dotenv:!1,extend:!1}}function F(e,t){if(e!==null&&typeof e=="object"&&"extends"in e)throw g.configLoadFailed(`helix.config.ts at ${t}: 'extends' is not supported \u2014 remove the field`);let r=ze.safeParse(e);if(!r.success){let f=r.error.issues.map(p=>p.message).join("; ");throw g.configLoadFailed(`Invalid helix.config.ts at ${t}: ${f}`)}let{projectId:n,workspaceId:o,...s}=r.data,a=o!==void 0?{workspaceId:o}:{},i=W(),c=i!==void 0?{...s,env:i}:s;return n!==void 0?{kind:"provisioned",projectId:n,...c,...a}:{kind:"unprovisioned",...c,...a}}async function w(e){let t=e??process.cwd(),r;try{r=await Ke(L(t))}catch(o){throw g.configLoadFailed(`Failed to load helix.config.ts: ${o instanceof Error?o.message:String(o)}`)}let n=r._configFile??x(t);if(!n)throw g.configLoadFailed(`helix.config.ts not found at ${_(t,"helix.config.ts")}`);return F(r.config,n)}var ue="WORKSPACE_ID_REQUIRED";function Je(e){if(e.workspaceId===void 0)throw Object.assign(new Error("No workspaceId found in helix.config.ts. Discover & choose one \u2014 self-serve fix: run `helix workspace select`; agent-driven fix: call the `tray_list_workspaces` MCP tool. Already know the id? Run `helix workspace set <id>` or call the `tray_set_workspace_id` MCP tool. deploy cannot proceed without a workspace."),{code:ue});return e.workspaceId}import{existsSync as Qe,watch as Xe,writeSync as Ye}from"fs";import{join as et,resolve as tt}from"path";import{watchConfig as rt}from"c12";function nt(e,t){let r=e instanceof Error?e.message:String(e);Ye(2,`[helix-watch] ${t.phase} error: ${r}
|
|
1
|
+
import{A as Ce,B as ve,b as T,g as U,h as I,i as N,j as C,k as q,l as M,m as $,n as Z,o as ge,p as K,q as z,r as G,s as J,t as Q,x as X,y as he,z as ye}from"./chunk-FTYQLXLV.js";import{a as B,b as me}from"./chunk-WUCX7RZO.js";import{b as H,e as A,i as W,l as g,m as V}from"./chunk-GKP5Y3YJ.js";import{randomUUID as _e}from"crypto";import{SpanStatusCode as ne,SpanKind as Re}from"@opentelemetry/api";import{defineEventHandler as Pe,getMethod as Le,getRequestURL as Fe,getHeaders as se,getHeader as oe}from"h3";import{readBody as we,getQuery as Ee,getRouterParams as ke}from"h3";async function Y(e,t){let r=await Se(e),n=Ee(e),o=ke(e)??{},s={...n,...r,...o};return t?xe(s,t):s}async function Se(e){try{let t=await we(e);return t&&typeof t=="object"?t:(t!=null&&t!==""&&console.warn("[helix-sdk] Request body present but not a JSON object \u2014 ignored"),{})}catch(t){if(t instanceof Error&&"statusCode"in t&&t.statusCode===400){let n=new Error("Malformed request body");throw n.statusCode=400,n.data={message:"Request body is not valid JSON"},n}let r=e.method?.toUpperCase();if(r==="GET"||r==="HEAD"||r==="DELETE")return{};throw t}}function xe(e,t){let r=t.safeParse(e);if(!r.success){let n=new Error("Input validation failed");throw n.statusCode=400,n.data=r.error.flatten(),n}return r.data}var v=class extends Error{statusCode;constructor(t,r){super(r),this.statusCode=t,this.name="HttpError"}};function ee(e){return t=>{e.node.res.statusCode=t}}function te(){return(e,t)=>{throw new v(e,t)}}function re(e,t){let{statusCode:r,message:n}=Te(t.detail);return e.node.res.statusCode=r,{error:n,statusCode:r}}function Te(e){switch(e.kind){case"unknown_alias":return{statusCode:400,message:"Unknown authentication alias"};case"input_validation_failed":return{statusCode:400,message:"Input validation failed"};case"output_validation_failed":return{statusCode:500,message:"Internal server error"};case"config_load_failed":return{statusCode:500,message:"Configuration error"};case"broker_error":return{statusCode:502,message:"Broker error"};case"unsupported_body_type":return{statusCode:400,message:"Unsupported request body type"};case"unsupported_scheme":return{statusCode:400,message:"Unsupported URL scheme"};case"missing_execution_credentials":return{statusCode:401,message:"Missing execution credentials"};case"missing_tray_token":return{statusCode:500,message:"Missing Tray token"};case"db_call_failed":return{statusCode:502,message:e.message};case"db_query_failed":return{statusCode:502,message:`Database query failed: ${e.message}`};case"db_invalid_parameters":return{statusCode:400,message:e.message};case"kv_key_invalid":return{statusCode:400,message:e.message};case"kv_value_invalid":return{statusCode:400,message:e.message};case"kv_value_too_large":return{statusCode:400,message:e.message};case"kv_not_available":return{statusCode:501,message:"Key-value store is not available in this environment"};case"kv_call_failed":return{statusCode:502,message:"Key-value store request failed"};case"kv_requires_provisioning":return{statusCode:500,message:"Internal server error"};case"files_path_invalid":return{statusCode:400,message:e.message};case"files_value_invalid":return{statusCode:400,message:e.message};case"files_value_too_large":return{statusCode:400,message:e.message};case"files_not_available":return{statusCode:501,message:"File storage is not available in this environment"};case"files_call_failed":return{statusCode:502,message:"File storage request failed"};case"files_requires_provisioning":return{statusCode:500,message:"Internal server error"};default:return{statusCode:500,message:`Unhandled error kind: ${e.kind}`}}}var Ie=["authorization","x-tray-token","set-cookie","x-kong-request-id","traceparent","x-real-ip","cookie"];function be(e){return e.toLowerCase().includes("tray_lid")}function b(e){let t={};for(let[r,n]of Object.entries(e))if(!Ie.includes(r.toLowerCase())){if(r.toLowerCase()==="cookie"&&n){let o=n.split(";").map(s=>s.trim()).filter(s=>{let a=s.split("=")[0].trim();return!be(a)}).join("; ");o&&(t[r]=o);continue}t[r]=n}return t}function je(e,t){let{inputSchema:r,outputSchema:n}=Ue(t),o=e;return Pe(async s=>{let a=T(),{executionId:i,userId:c,deploymentId:f}=Ne(a,s),p=Date.now(),y=new Date().toISOString(),m=Le(s),l=Fe(s).pathname,u=z(),h=K(),E=`${m} ${l}`;q();let O={hasDb:!1,hasExternal:!1,hasAuth:!1,hasError:!1};return De(()=>I.run(O,()=>U.run(i,async()=>{let k=await Oe(s,r);if(!k.ok)return{response:k.response,errored:!1,errorMessage:null};let pe=Me(s,k.input,u,h,m,l,i,f,c);return He(o,pe,n,s,h,i,f,{method:m,path:l,rawInput:k.input})})),{executionId:i,deploymentId:f,routeOrJob:E,startedAt:y,startMs:p,userId:c,flags:O})})}async function De(e,t){let r=!1,n=null;try{let o=await e();return r=o.errored,n=o.errorMessage,o.response}finally{Z({...t,errored:r,errorMessage:n}),await M()}}async function Oe(e,t){try{return{ok:!0,input:await Y(e,t)}}catch(r){let n=qe(e,r);if(n)return{ok:!1,response:n};throw r}}async function He(e,t,r,n,o,s,a,i){return $.startActiveSpan("function",{root:!0,kind:Re.SERVER,attributes:{method:i.method,route:i.path,executionId:s,...a?{deploymentId:a}:{}}},async c=>{t.traceId=c.spanContext().traceId;let f=b(se(n));C(c,"input",i.rawInput),C(c,"request",{method:i.method,path:i.path,headers:f,body:i.rawInput});let p=!1,y=null,m,l;try{let u=await B.run(t,()=>e(t));if(m=u,u==null)n.node.res.statusCode=204,l="";else if(u instanceof Response)l=u;else if(r){let h=r.safeParse(u);if(!h.success){let E=Object.keys(h.error.flatten().fieldErrors);throw o.error("Output validation failed",{fields:E,executionId:s}),g.outputValidationFailed(E)}l=h.data}else l=u}catch(u){p=!0,y=u instanceof Error?u.message:String(u),N("hasError"),l=Ae(u,n,o,s)}finally{We(c,n,{errored:p,errorMessage:y,handlerResult:m,response:l})}return{response:l,errored:p,errorMessage:y}})}function Ae(e,t,r,n){if(e instanceof v)return t.node.res.statusCode=e.statusCode,{error:e.message,statusCode:e.statusCode};if(V(e))return re(t,e);r.error("Unhandled error in handler",{error:e instanceof Error?e.message:String(e),executionId:n}),t.node.res.statusCode=500;let o=process.env.NODE_ENV==="development";return{error:o&&e instanceof Error?e.message:"Internal server error",statusCode:500,...o&&e instanceof Error&&e.stack?{stack:e.stack}:{}}}function We(e,t,r){e.setAttribute("statusCode",t.node.res.statusCode),!r.errored&&r.handlerResult!==void 0&&C(e,"output",r.handlerResult),C(e,"response",r.response);let n=I.getStore();e.setAttribute("hasAuth",n?.hasAuth??!1),e.setAttribute("hasExternal",n?.hasExternal??!1),e.setAttribute("hasDb",n?.hasDb??!1),e.setAttribute("status",r.errored?"error":"success");let o=r.errored||(n?.hasError??!1);e.setStatus({code:o?ne.ERROR:ne.OK,...r.errorMessage?{message:r.errorMessage}:{}}),e.end()}function Ue(e){if(!e)return{inputSchema:void 0,outputSchema:void 0};if(e instanceof Object&&"_def"in e)return{inputSchema:e,outputSchema:void 0};if(typeof e=="object"&&("input"in e||"output"in e)){let t=e;return{inputSchema:t.input,outputSchema:t.output}}return{inputSchema:e,outputSchema:void 0}}function Ne(e,t){let r=e.mode==="lambda",n=(r?e.executionId:oe(t,"x-tray-execution-id"))??_e(),o=(r?e.userId:oe(t,"x-tray-user-id"))??null,s=r?e.deploymentId??null:null;return{executionId:n,userId:o,deploymentId:s}}function qe(e,t){if(!(t instanceof Error)||!("statusCode"in t)||!("data"in t))return null;let r=t.statusCode,n=t.data;e.node.res.statusCode=r;let o=n&&typeof n=="object"&&"fieldErrors"in n?n.fieldErrors:void 0;return{error:"Input validation failed",statusCode:r,...o?{fields:Object.keys(o)}:{}}}function Me(e,t,r,n,o,s,a,i,c){return{input:t,method:o,path:s,headers:b(se(e)),http:G(),db:f=>J(f),kv:()=>Q(),files:()=>X(),log:n,config:r,status:ee(e),error:te(),state:{},request:e,executionId:a,deploymentId:i,userId:c,identity:c!==null?{user:{id:c}}:null,traceId:""}}function $e(e){return e}import{resolve as _}from"path";import{existsSync as ae}from"fs";import{loadConfig as Ke}from"c12";import{z as d}from"zod";import{z as Ze}from"zod";var Be=["production"],S=Ze.string().refine(e=>H(e),e=>({message:`Invalid enum value. Expected ${A().map(t=>`'${t}'`).join(" | ")}, received '${e}'`}));var R=d.string().uuid("projectId must be a valid UUID"),P=d.string().min(1,"workspaceId must be a non-empty string"),ze=d.object({name:d.string().min(1,"name is required"),projectId:R.optional(),workspaceId:P.optional(),env:S.default("production"),authentications:d.record(d.string()).optional().default({}),config:d.record(d.unknown()).optional().default({})}),ie=d.object({name:d.string().min(1,"name is required"),workspaceId:P.optional(),env:S,authentications:d.record(d.string()),config:d.record(d.unknown())}),Ve=d.discriminatedUnion("kind",[ie.extend({kind:d.literal("provisioned"),projectId:R}),ie.extend({kind:d.literal("unprovisioned")})]),de=["helix","tray"],ce=["ts","mts","cts","js","mjs","cjs"];function x(e){for(let t of de)for(let r of ce){let n=_(e,`${t}.config.${r}`);if(ae(n))return n}}function Ge(e){for(let t of de)if(ce.some(r=>ae(_(e,`${t}.config.${r}`))))return t;return"helix"}function L(e){return{name:Ge(e),cwd:e,rcFile:!1,globalRc:!1,packageJson:!1,dotenv:!1,extend:!1}}function F(e,t){if(e!==null&&typeof e=="object"&&"extends"in e)throw g.configLoadFailed(`helix.config.ts at ${t}: 'extends' is not supported \u2014 remove the field`);let r=ze.safeParse(e);if(!r.success){let f=r.error.issues.map(p=>p.message).join("; ");throw g.configLoadFailed(`Invalid helix.config.ts at ${t}: ${f}`)}let{projectId:n,workspaceId:o,...s}=r.data,a=o!==void 0?{workspaceId:o}:{},i=W(),c=i!==void 0?{...s,env:i}:s;return n!==void 0?{kind:"provisioned",projectId:n,...c,...a}:{kind:"unprovisioned",...c,...a}}async function w(e){let t=e??process.cwd(),r;try{r=await Ke(L(t))}catch(o){throw g.configLoadFailed(`Failed to load helix.config.ts: ${o instanceof Error?o.message:String(o)}`)}let n=r._configFile??x(t);if(!n)throw g.configLoadFailed(`helix.config.ts not found at ${_(t,"helix.config.ts")}`);return F(r.config,n)}var ue="WORKSPACE_ID_REQUIRED";function Je(e){if(e.workspaceId===void 0)throw Object.assign(new Error("No workspaceId found in helix.config.ts. Discover & choose one \u2014 self-serve fix: run `helix workspace select`; agent-driven fix: call the `tray_list_workspaces` MCP tool. Already know the id? Run `helix workspace set <id>` or call the `tray_set_workspace_id` MCP tool. deploy cannot proceed without a workspace."),{code:ue});return e.workspaceId}import{existsSync as Qe,watch as Xe,writeSync as Ye}from"fs";import{join as et,resolve as tt}from"path";import{watchConfig as rt}from"c12";function nt(e,t){let r=e instanceof Error?e.message:String(e);Ye(2,`[helix-watch] ${t.phase} error: ${r}
|
|
2
2
|
`)}function j(){return{kind:"unprovisioned",name:"",authentications:{},config:{},env:"production"}}var ot=/^(?:helix|tray)\.config\.(?:m|c)?[jt]s$/,fe=new Set;function le(e){return x(e)!==void 0}async function st(e,t){if(le(e.cwd))try{return{current:await w(e.cwd),initialLoadSucceeded:!0}}catch(r){return t(r,{phase:"reload"}),{current:j(),initialLoadSucceeded:!1}}if(e.watch){let r=tt(e.cwd);fe.has(r)||(process.stderr.write(`warning: no helix.config.ts found at ${e.cwd}; tray running with default config \u2014 create one via \`helix init\`
|
|
3
3
|
`),fe.add(r))}return{current:j(),initialLoadSucceeded:!1}}var D=class{constructor(t,r,n){this.cwd=t;this.onError=r;this.emit=n}cwd;onError;emit;stopped=!1;directoryWatcher=null;c12Unwatch=null;c12AttachPromise=null;updateChain=Promise.resolve();start(t){t?this.attachC12Watcher():this.attachCreationWatcher()}watcherReady(){return this.c12AttachPromise===null?Promise.resolve():this.c12AttachPromise.catch(()=>{})}async stop(){this.stopped=!0,this.directoryWatcher&&(this.directoryWatcher.close(),this.directoryWatcher=null),this.c12AttachPromise&&await this.c12AttachPromise.catch(t=>this.onError(t,{phase:"attach"})),this.c12Unwatch&&(await this.c12Unwatch(),this.c12Unwatch=null)}attachC12Watcher(){this.c12AttachPromise===null&&(this.c12AttachPromise=rt({...L(this.cwd),onUpdate:({newConfig:t})=>{this.stopped||(this.updateChain=this.updateChain.then(async()=>{if(this.stopped)return;let r;try{r=F(t.config,this.cwd)}catch(n){this.onError(n,{phase:"validation"});return}try{this.emit(r)}catch(n){this.onError(n,{phase:"reload"})}}))}}).then(async t=>{if(this.stopped){t.unwatch();return}this.c12Unwatch=t.unwatch;let{watch:r}=await import("chokidar"),n=r(this.cwd,{persistent:!1,depth:0});try{await new Promise((o,s)=>{n.once("ready",o),n.once("error",s)})}finally{await n.close()}}).catch(t=>{this.onError(t,{phase:"attach"})}))}attachCreationWatcher(){try{this.directoryWatcher=Xe(this.cwd,{persistent:!1},(t,r)=>{if(this.stopped||!r)return;let n=r.toString();ot.test(n)&&Qe(et(this.cwd,n))&&(this.updateChain=this.updateChain.then(async()=>{if(this.stopped)return;let o;try{o=await w(this.cwd)}catch(a){this.onError(a,{phase:"reload"});return}if(this.stopped)return;this.emit(o);let s=this.directoryWatcher;s&&(this.directoryWatcher=null,s.close()),this.attachC12Watcher()}))}),this.directoryWatcher.on("error",t=>{this.onError(t,{phase:"attach"})})}catch(t){this.onError(t,{phase:"attach"})}}};async function it(e){let t=e.onError??nt,r=new Set,n=await st(e,t),o=n.current;function s(i){o=i;for(let c of[...r])try{c(i)}catch(f){t(f,{phase:"reload"})}}let a=new D(e.cwd,t,s);return e.watch&&a.start(n.initialLoadSucceeded),{get(){return o},async reload(){if(!le(e.cwd)){let i=j();return s(i),i}try{let i=await w(e.cwd);return s(i),i}catch(i){return t(i,{phase:"reload"}),o}},subscribe(i){return r.add(i),()=>{r.delete(i)}},async stop(){r.clear(),await a.stop()},ready(){return a.watcherReady()}}}export{Be as ENVIRONMENT_VALUES,he as SCHEDULE_DEFINITION_KIND,ye as ScheduleConfigError,ue as WORKSPACE_ID_REQUIRED_CODE,it as createConfigService,$e as defineConfig,je as defineFunction,Ce as defineSchedule,S as environmentSchema,me as getContext,T as getSdkConfig,ve as isScheduleDefinition,w as loadConfig,Ve as loadedTrayConfigSchema,R as projectIdSchema,Je as requireWorkspaceId,x as resolveConfigFile,ge as runWithinAppSpan,P as workspaceIdSchema};
|
package/dist/internal/index.d.ts
CHANGED
|
@@ -62,6 +62,7 @@ type SdkErrorDetail = {
|
|
|
62
62
|
status: number;
|
|
63
63
|
message: string;
|
|
64
64
|
body?: string;
|
|
65
|
+
code?: string;
|
|
65
66
|
} | {
|
|
66
67
|
readonly kind: "unsupported_body_type";
|
|
67
68
|
actualType: string;
|
|
@@ -129,7 +130,7 @@ declare class SdkError extends Error {
|
|
|
129
130
|
static inputValidationFailed(fields: string[]): SdkError;
|
|
130
131
|
static outputValidationFailed(fields: string[]): SdkError;
|
|
131
132
|
static configLoadFailed(cause: string): SdkError;
|
|
132
|
-
static brokerError(status: number, message: string, body?: string): SdkError;
|
|
133
|
+
static brokerError(status: number, message: string, body?: string, code?: string): SdkError;
|
|
133
134
|
static unsupportedBodyType(actualType: string): SdkError;
|
|
134
135
|
static unsupportedScheme(scheme: string): SdkError;
|
|
135
136
|
static missingExecutionCredentials(): SdkError;
|
package/dist/internal/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{B as P,a as J,b as m,c as L,d as T,e as U,f as G,g as h,h as p,i as g,j as S,k as E,l as x,m as y,n as A,p as w,q as I,r as v,s as C,t as D,u as re,v as oe,w as ne,x as F}from"../chunk-
|
|
1
|
+
import{B as P,a as J,b as m,c as L,d as T,e as U,f as G,g as h,h as p,i as g,j as S,k as E,l as x,m as y,n as A,p as w,q as I,r as v,s as C,t as D,u as re,v as oe,w as ne,x as F}from"../chunk-FTYQLXLV.js";import{a as b}from"../chunk-WUCX7RZO.js";import{a as V,b as _,c as q,d as B,e as z,f as Q,g as W,h as X,i as Y,j as Z,k as ee,m as te}from"../chunk-GKP5Y3YJ.js";import{randomUUID as se}from"crypto";import{SpanStatusCode as k,SpanKind as ie}from"@opentelemetry/api";var t=class extends Error{constructor(e){super(`runScheduledFunction: ${e}`),this.name="ScheduleInvocationError"}};async function ae(s,e){if(typeof e!="object"||e===null)throw new t("`invocation` must be an object");let{schedulePath:r}=e;if(typeof r!="string"||r.length===0)throw new t("`schedulePath` must be a non-empty string");if(typeof e.isManual!="boolean")throw new t("`isManual` must be a boolean");if(!P(s))throw new t(`default export of "${r}" is not a defineSchedule definition`);let O=N("scheduledAt",e.scheduledAt),M=N("firedAt",e.firedAt),d=m(),a=d.executionId??se(),l=d.deploymentId??null,j=Date.now(),R=new Date().toISOString(),$=I(),K=w();E();let i={hasDb:!1,hasExternal:!1,hasAuth:!1,hasError:!1},c=!1,u=null;try{await p.run(i,()=>h.run(a,()=>y.startActiveSpan("schedule",{root:!0,kind:ie.SERVER,attributes:{method:"SCHEDULE",route:r,executionId:a,...l?{deploymentId:l}:{}}},async o=>{let H={type:"schedule",scheduledAt:O,firedAt:M,isManual:e.isManual},f={http:v(),db:n=>C(n),kv:()=>D(),files:()=>F(),log:K,config:$,state:{},executionId:a,deploymentId:l,traceId:o.spanContext().traceId,trigger:H};S(o,"input",{scheduledAt:e.scheduledAt,firedAt:e.firedAt,isManual:e.isManual});try{await b.run(f,()=>s.handler(f))}catch(n){throw c=!0,u=n instanceof Error?n.message:String(n),g("hasError"),n}finally{o.setAttribute("hasAuth",i.hasAuth),o.setAttribute("hasExternal",i.hasExternal),o.setAttribute("hasDb",i.hasDb),o.setAttribute("status",c?"error":"success");let n=c||i.hasError;o.setStatus({code:n?k.ERROR:k.OK,...u?{message:u}:{}}),o.end()}})))}finally{A({executionId:a,deploymentId:l,triggerType:"schedule",routeOrJob:r,startedAt:R,startMs:j,errored:c,errorMessage:u,userId:null,flags:i}),await x()}}function N(s,e){if(typeof e!="string"||e.length===0)throw new t(`\`${s}\` must be a timestamp string; got ${JSON.stringify(e)}`);let r=new Date(e);if(Number.isNaN(r.getTime()))throw new t(`\`${s}\` must be a Date-parseable timestamp; got ${JSON.stringify(e)}`);return r}export{L as CONFIG_BRIDGE_CHANNEL,t as ScheduleInvocationError,re as assertValidPath,G as clearActiveConfig,oe as contentFilePath,U as getActiveConfig,Z as getAdditionalEnvironmentProfiles,q as getEnvironmentProfile,_ as isKnownEnvironment,te as isSdkError,z as listEnvironmentNames,Q as listExposedEnvNames,ne as metaFilePath,W as parseExposedEnvironment,V as registerEnvironmentProfile,B as requireEnvironmentProfile,ee as resetEnvironmentRegistryForTests,Y as resolveForcedEnvironment,ae as runScheduledFunction,T as setActiveConfig,X as setForcedEnvironment,J as setSdkConfig};
|
package/dist/testing/index.d.ts
CHANGED
|
@@ -101,13 +101,26 @@ interface Logger {
|
|
|
101
101
|
debug(message: string, data?: Record<string, unknown>): void;
|
|
102
102
|
}
|
|
103
103
|
interface BrokerCallOptions {
|
|
104
|
+
/** Request body. Strings, byte buffers (`Uint8Array`/`ArrayBuffer`), blobs,
|
|
105
|
+
form data, and streams are sent as verbatim bytes — never JSON-quoted.
|
|
106
|
+
Plain objects/arrays are JSON-serialized (content-type defaults to
|
|
107
|
+
application/json unless set in `headers`). Bodies over 16 MB are
|
|
108
|
+
rejected by the broker — use the target API's multipart or chunked
|
|
109
|
+
upload flow for anything larger, keeping each part under the cap. */
|
|
104
110
|
body?: unknown;
|
|
105
111
|
headers?: Record<string, string>;
|
|
106
112
|
query?: Record<string, string | string[]>;
|
|
113
|
+
/** Per-call timeout in ms (default 60s). Keep ≥ 45s: the broker's upstream
|
|
114
|
+
budget is 30s plus an internal-hop margin. */
|
|
107
115
|
timeout?: number;
|
|
108
116
|
}
|
|
109
117
|
interface BrokerCallResult {
|
|
118
|
+
/** Upstream status verbatim — 4xx/5xx are returned, not thrown, and 3xx
|
|
119
|
+
redirects are NOT followed (the `location` header is present; following
|
|
120
|
+
it is the app's decision). */
|
|
110
121
|
status: number;
|
|
122
|
+
/** Parsed JSON for json content-types, string for textual ones, raw bytes
|
|
123
|
+
(`Uint8Array`) otherwise. Undefined for an empty body. */
|
|
111
124
|
body?: unknown;
|
|
112
125
|
headers: Record<string, string | string[]>;
|
|
113
126
|
}
|
package/package.json
CHANGED
package/dist/chunk-3SDUCOAT.js
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
import{d as D,l as c,n as z,o as oe,p as Qe,q as Ze}from"./chunk-H4L4UWIK.js";var R="X-Helix-Project-Execution-Token",F="X-Tray-Token",pr={mode:"dev",deploymentId:null},Pe={...pr},O={};function mo(e){let{internalJwt:t,helixExecutionJwt:r,devToken:n,...o}=e;"internalJwt"in e&&(O.internalJwt=t),"helixExecutionJwt"in e&&(O.helixExecutionJwt=r),"devToken"in e&&(O.devToken=n),Pe={...Pe,...o}}function w(){return Pe}function _(){return O.internalJwt}function T(){return O.helixExecutionJwt}function et(){return O.devToken}var go="tray-config-bridge",ie=null;function yo(e){ie=e}function b(){if(!ie)throw new Error("Active tray config not seeded. Worker boot must call setActiveConfig() before handlers run.");return ie}function ho(){ie=null}import{AsyncLocalStorage as St}from"async_hooks";import{trace as kr,SpanKind as Ir,SpanStatusCode as Ie}from"@opentelemetry/api";import{ExportResultCode as Ar,W3CTraceContextPropagator as Dr}from"@opentelemetry/core";import{NodeTracerProvider as Or,SimpleSpanProcessor as Fr,BatchSpanProcessor as _r}from"@opentelemetry/sdk-trace-node";import{OTLPTraceExporter as gr}from"@opentelemetry/exporter-trace-otlp-proto";import{OTLPLogExporter as yr}from"@opentelemetry/exporter-logs-otlp-proto";function Ce(e){return D(e).hosts.ingest}function hr(){return T()??""}function tt(){return{[R]:hr()}}function rt(){let e=Ce(b().env);return new gr({url:`${e}/v1/traces`,headers:()=>Promise.resolve(tt())})}function nt(){let e=Ce(b().env);return new yr({url:`${e}/v1/logs`,headers:()=>Promise.resolve(tt())})}import{logs as st,SeverityNumber as se}from"@opentelemetry/api-logs";import{LoggerProvider as Sr,BatchLogRecordProcessor as Er}from"@opentelemetry/sdk-logs";function J(e){try{return JSON.stringify(e)}catch(t){return JSON.stringify({_serialization_error:t instanceof Error?t.message:String(t)})}}function wr(e){return new TextEncoder().encode(e).length}var ot="\u2026[truncated]",br=wr(ot),q=4096;function k(e,t=q){let r=new TextEncoder().encode(e);if(r.length<=t)return e;let n=r.subarray(0,t-br);return new TextDecoder("utf-8").decode(n).replace(/�$/,"")+ot}function g(e,t=q){return k(J(e),t)}var xr="@trayai/helix-sdk",Y,it={debug:{number:se.DEBUG,text:"DEBUG"},info:{number:se.INFO,text:"INFO"},warn:{number:se.WARN,text:"WARN"},error:{number:se.ERROR,text:"ERROR"}};function vr(){return w().mode==="lambda"?[new Er({exporter:nt()})]:[]}function at(){if(Y!==void 0)return;let e=vr();e.length!==0&&(Y=new Sr({processors:e}),st.setGlobalLoggerProvider(Y))}function Rr(e,t,r){let n=it[e]??it.info;return{severityNumber:n.number,severityText:n.text,body:t,...r?{attributes:{"tray.log.meta":g(r)}}:{}}}function ct(e,t,r){st.getLogger(xr).emit(Rr(e,t,r))}async function lt(e=2e3){if(Y===void 0)return;let t;try{await Promise.race([Y.forceFlush(),new Promise(r=>{t=setTimeout(r,e)})])}catch(r){process.stderr.write(`[helix-sdk] otel log flush failed: ${r instanceof Error?r.message:String(r)}
|
|
2
|
-
`)}finally{t!==void 0&&clearTimeout(t)}}function ke(){let e=process.env.TRAY_PRETTY_LOGS;return e==="1"||e==="true"}function Tr(){if(process.env.NO_COLOR!==void 0)return!1;let e=process.env.FORCE_COLOR;return e!==void 0&&e!=="0"&&e!=="false"?!0:!!process.stdout.isTTY&&process.env.TERM!=="dumb"}function S(e,t){return Tr()?`\x1B[${e}m${t}\x1B[0m`:t}var Pr=5,Cr={FN:"1;35",INFO:"34",AUTH:"35",API:"36",WARN:"33",ERROR:"31",DEBUG:"90"},ut="32",dt="31",ae="2",ft="1";function ce(e){return S(Cr[e]??"0",e.padEnd(Pr))}function mt(e,t){return`${ce("FN")} ${S(ft,`${e} ${t}`.trim())}`}function pt(e,t,r,n){let o=e.toUpperCase(),s=`${n?`${S(ae,n)} `:""}${ce(o)} ${t}`;return r&&Object.keys(r).length>0&&(s+=` ${S(ae,J(r))}`),s}function gt(e){return new Date(e[0]*1e3).toTimeString().slice(0,8)}function yt(e){return`${ce("AUTH")} ${e}`}function ht(e,t,r,n,o){let i=r===void 0?"ERR":String(r),s=S(o==="error"?dt:ut,i);return`${ce("API")} ${e} ${t} \u2192 ${s} ${S(ae,`${n}ms`)}`}function wt(e,t,r){let n=t?dt:ut,o=S(n,"\u25CF"),i=S(n,t?"error":"success");return`${o} ${S(ft,e)} ${i} ${S(ae,`${r}ms`)}`}function B(e){try{process.stdout.write(e+`
|
|
3
|
-
`)}catch{}}var Et=new St,Br=new St;function E(e){let t=Br.getStore();t&&(t[e]=!0)}var Lr=/^[0-9a-f]{32}$/;function Nr(e){let t=e.replace(/-/g,"").toLowerCase();return Lr.test(t)?t:null}var jr={0:"STATUS_CODE_UNSET",1:"STATUS_CODE_OK",2:"STATUS_CODE_ERROR"},L=new Map;function xt(e,t,r){let n=L.get(e);n?n[t]=r:L.set(e,{[t]:r})}function v(e,t,r){e.setAttribute(t,g(r))}var X;function bt(e){return`${e[0]}${String(e[1]).padStart(9,"0")}`}function Mr(e){return Math.round(e[0]*1e3+e[1]/1e6)}function vt(e){try{process.stdout.write(J(e)+`
|
|
4
|
-
`)}catch{}}var Ae=class{export(t,r){for(let n of t){let o=n.spanContext().spanId,i=L.get(o),s={...n.attributes};if(i!==void 0){for(let[u,f]of Object.entries(i))typeof f=="string"?s[u]=k(f):typeof f=="object"&&f!==null?s[u]=g(f):s[u]=f;L.delete(o)}let a=Et.getStore(),l=a?Nr(a):null;vt({_otel:"span",traceId:l??n.spanContext().traceId,spanId:o,parentSpanId:n.parentSpanContext?.spanId??"",name:n.name,kind:n.kind,startTimeUnixNano:bt(n.startTime),endTimeUnixNano:bt(n.endTime),attributes:s,status:{code:jr[n.status.code]??"STATUS_CODE_UNSET",...n.status.message?{message:k(n.status.message)}:{}}})}r({code:Ar.SUCCESS})}forceFlush(){return Promise.resolve()}shutdown(){return Promise.resolve()}},De=class{onStart(t,r){}onEnd(t){L.delete(t.spanContext().spanId)}forceFlush(){return Promise.resolve()}shutdown(){return Promise.resolve()}},Oe=class{onStart(t){let r=t;(r.name==="function"||r.name==="App")&&B(`
|
|
5
|
-
`+mt(String(r.attributes.method??""),String(r.attributes.route??"")))}onEnd(t){let r=t.attributes;switch(t.name){case"log":{let n=t.spanContext().spanId,o=L.get(n)?.properties;B(pt(String(r.level??"info"),String(r.message??""),o,gt(t.startTime)));break}case"auth":B(yt(String(r.alias??"")));break;case"externalApi":{let n=typeof r.statusCode=="number"?r.statusCode:void 0;B(ht(String(r.method??""),String(r.host??""),n,Mr(t.duration),r.status==="error"?"error":"success"));break}}}forceFlush(){return Promise.resolve()}shutdown(){return Promise.resolve()}},Fe=class{constructor(t){this.inner=t}inner;onStart(t,r){this.inner.onStart(t,r)}onEnd(t){t.name!=="log"&&this.inner.onEnd(t)}forceFlush(){return this.inner.forceFlush()}shutdown(){return this.inner.shutdown()}};function Ur(){let t=[ke()?new Oe:new Fr(new Ae)];return w().mode==="lambda"&&t.push(new Fe(new _r(rt()))),t.push(new De),t}function $r(){X===void 0&&(X=new Or({spanProcessors:Ur()}),X.register({propagator:new Dr}),at())}async function Kr(e=2e3){let t=[lt(e)];X!==void 0&&t.push((async()=>{let r;try{await Promise.race([X.forceFlush(),new Promise(n=>{r=setTimeout(n,e)})])}catch(n){process.stderr.write(`[helix-sdk] otel flush failed: ${n instanceof Error?n.message:String(n)}
|
|
6
|
-
`)}finally{r!==void 0&&clearTimeout(r)}})()),await Promise.all(t)}var x=kr.getTracer("@trayai/helix-sdk");function Hr({executionId:e,deploymentId:t,triggerType:r="http",routeOrJob:n,startedAt:o,startMs:i,errored:s,errorMessage:a,userId:l,flags:u}){let f=new Date().toISOString(),d=Date.now()-i;if(ke()){B(`
|
|
7
|
-
`+wt(n,s,d));return}vt({_otel:"summary",executionId:e,deploymentId:t,triggerType:r,routeOrJob:n,status:s?"error":"success",startedAt:o,finishedAt:f,durationMs:d,userId:l,hasError:s||u.hasError,hasAuth:u.hasAuth,hasExternal:u.hasExternal,hasDb:u.hasDb,errorSummary:s&&a!==null?k(a):null})}async function zo(e,t){let r=e.startMs??Date.now();$r();let n=!1,o=null;try{return await Et.run(e.executionId,()=>x.startActiveSpan("App",{kind:Ir.SERVER,attributes:{method:e.method,route:e.route,...e.deploymentId?{deploymentId:e.deploymentId}:{}}},async i=>{try{let s=await t(),a=s?.httpResponse?.status??404;return n=a>=400,i.setAttribute("http.response.status_code",a),i.setAttribute("helix.status",n?"error":"success"),i.setStatus({code:n?Ie.ERROR:Ie.OK}),s}catch(s){throw n=!0,o=s instanceof Error?s.message:String(s),i.setAttribute("http.response.status_code",500),i.setAttribute("helix.status","error"),i.setStatus({code:Ie.ERROR,message:o}),s}finally{i.end()}}))}finally{Hr({executionId:e.executionId,deploymentId:e.deploymentId,routeOrJob:`${e.method} ${e.route}`,startedAt:e.startedAt,startMs:r,errored:n,errorMessage:o,userId:e.userId,flags:{hasDb:!1,hasExternal:!1,hasAuth:!1,hasError:!1}}),await Kr()}}var Pt=1024,P=100*1024*1024,Rt=250,Vr=3600,zr=Vr*1e3,Tt=new TextEncoder,Jr=/(^|\/)\.\.(\/|$)/,qr=/[?#]/;function Yr(e){for(let t=0;t<e.length;t++){let r=e.charCodeAt(t);if(r<=31||r===127)return!0}return!1}function I(e,t=Pt){if(e.length===0)throw c.filesPathInvalid("Path must be a non-empty string");le(e,t)}function _e(e){return e.endsWith("/")?e.slice(0,-1):e}function le(e,t=Pt){if(e.length===0)return;if(Jr.test(e))throw c.filesPathInvalid("Path contains path traversal segment");if(qr.test(e)||Yr(e))throw c.filesPathInvalid("Path contains illegal characters");let r=e.split("/");if(e.startsWith("/")||e.endsWith("/")||r.some(o=>o===""))throw c.filesPathInvalid("Path must not contain empty path segments");for(let o of r){let i=Tt.encode(o).length;if(i>Rt)throw c.filesPathInvalid(`Path segment exceeds ${Rt} UTF-8 bytes (got ${i})`)}let n=Tt.encode(e).length;if(n<1||n>t)throw c.filesPathInvalid(`Path must be between 1 and ${t} UTF-8 bytes (got ${n})`)}function Ct(e){if(e>P)throw c.filesValueTooLarge(`File exceeds maximum size of ${P} bytes (got ${e})`,P)}function N(e){let t=e!==void 0?e*1e3:zr;return new Date(Date.now()+t)}import{join as G}from"path";var Xr="files",Wr="files-meta",Gr=1023,Qr=1,Zr=5;function kt(e){let t=Math.max(Buffer.byteLength(ue(e),"utf8"),Buffer.byteLength(W(e),"utf8"));return Math.max(0,Gr-t-Qr-Zr)}function ue(e){return G(e,".helix",Xr)}function W(e){return G(e,".helix",Wr)}function Q(e,t){return G(ue(e),...t.split("/"))}function de(e,t){return G(W(e),...t.split("/"))+".json"}function fe(e,t){return t.length===0?ue(e):Q(e,t)}function It(e,t){return t.length===0?W(e):G(W(e),...t.split("/"))}var At="helix-schedule",A=class extends Error{constructor(t){super(`defineSchedule: ${t}`),this.name="ScheduleConfigError"}};function Go(e){if(typeof e!="object"||e===null)throw new A("expected a config object");let{cron:t,timezone:r="UTC",handler:n}=e;if(typeof t!="string"||t.trim()==="")throw new A("`cron` must be a non-empty string");let o=t.trim().split(/\s+/).length;if(o!==5)throw new A(`\`cron\` must be a 5-field standard expression (minute hour day-of-month month day-of-week); got ${o} field(s) in "${t}"`);if(typeof r!="string"||!en(r))throw new A(`\`timezone\` must be a valid IANA timezone name (e.g. "Europe/London"); got "${String(r)}"`);if(typeof n!="function")throw new A("`handler` must be a function");return Object.freeze({kind:At,cron:t.trim(),timezone:r,concurrent:!0,handler:n})}function Qo(e){return typeof e=="object"&&e!==null&&e.kind===At&&typeof e.handler=="function"}function en(e){if(!/^[A-Za-z]/.test(e))return!1;try{return new Intl.DateTimeFormat(void 0,{timeZone:e}),!0}catch{return!1}}import{SpanKind as tn}from"@opentelemetry/api";function me(e,t,r){let n=x.startSpan("log",{kind:tn.INTERNAL});n.setAttribute("message",t),n.setAttribute("level",e),r&&xt(n.spanContext().spanId,"properties",r),n.end(),ct(e,t,r)}function ni(){return{info:(e,t)=>me("info",e,t),warn:(e,t)=>me("warn",e,t),error:(e,t)=>me("error",e,t),debug:(e,t)=>me("debug",e,t)}}function si(){try{return b().config??{}}catch(e){return console.warn(`[helix-sdk] Config not loaded: ${e instanceof Error?e.message:String(e)}. Using empty config.`),{}}}import on from"ky";import{context as Be,trace as sn,SpanKind as ge,SpanStatusCode as Ft}from"@opentelemetry/api";import rn from"ky";async function Dt(e,t={}){let r=_(),n=T(),o=!!(r&&r.trim().length>0),i=!!(n&&n.trim().length>0);if(!o&&!i)throw c.missingExecutionCredentials();let{env:s}=b(),a=oe(s),l=t.timeout??6e4,u={Accept:"application/json"};o&&(u[F]=r),i&&(u[R]=n);let f=w().deploymentId,d=f?{...e,deploymentId:f}:e,m=await rn.post(`${a}/broker/http`,{json:d,headers:u,throwHttpErrors:!1,timeout:l}),p;return(m.headers.get("content-type")??"").includes("application/json")?p=await m.json():p=await m.text(),{status:m.status,body:p}}import nn from"ky";async function Ot(e,t={}){let r=et();if(!r)throw c.missingTrayToken();let{env:n}=b(),o=oe(n),i=t.timeout??6e4,s=await nn.post(`${o}/broker/http/dev`,{json:e,headers:{Authorization:`Bearer ${r}`,Accept:"application/json"},throwHttpErrors:!1,timeout:i}),a;return(s.headers.get("content-type")??"").includes("application/json")?a=await s.json():a=await s.text(),{status:s.status,body:a}}async function pe(e,t={}){let r=w().mode==="lambda"?Dt:Ot,n;try{n=await r(e,t)}catch(a){if(a instanceof c)throw a;let l=a instanceof Error?a.message??String(a):String(a);throw c.brokerError(0,l)}let{status:o,body:i}=n;if(o<200||o>=300){let a;if(i!==null&&typeof i=="object"){let l=i;typeof l.message=="string"?a=l.message:typeof l.error=="string"?a=l.error:a=String(i)}else a=String(i);throw c.brokerError(o,a,g(i))}let s=Qe.safeParse(i);if(!s.success)throw c.brokerError(o,"broker returned malformed response",g(i));return Ze(s.data)}var an=["get","post","put","patch","delete","head","options"],_t="[stream body omitted]";function Le(e){try{return new URL(e).hostname}catch{return e}}function cn(e,t,r,n){let o=Le(t),i="externalApi",s={kind:ge.CLIENT};return x.startActiveSpan(i,s,async a=>(a.setAttributes({method:e,host:o}),v(a,"request",{url:t,method:e,...r!==void 0?{body:r instanceof ReadableStream?_t:r}:{}}),n(a)))}function Ne(e,t,r){e.setAttribute("status",t),e.setStatus(t==="success"?{code:Ft.OK}:{code:Ft.ERROR,message:r}),e.end()}var ln=16;async function un(e,t){let r=e.clone().body;return r?Bt(r,t):new Uint8Array(0)}async function Bt(e,t){let r=e.getReader(),n=[],o=0,i=0;try{for(;;){let{done:l,value:u}=await r.read();if(l)break;if(!u||u.byteLength===0){if(i+=1,i>=ln)break;continue}i=0;let f=t+1-o;if(u.byteLength>=f){n.push(u.slice(0,f)),o+=f;break}n.push(u),o+=u.byteLength}}finally{r.cancel().catch(()=>{}),r.releaseLock()}let s=new Uint8Array(o),a=0;for(let l of n)s.set(l,a),a+=l.byteLength;return s}async function Lt(e,t,r){if("kyResponse"in r)try{let n=await un(r.kyResponse,q),o=new TextDecoder("utf-8").decode(n,{stream:!0}),i;try{i=JSON.parse(o)}catch{i=o}v(e,"response",i)}catch{v(e,"response",{status:t})}else v(e,"response",r.bodyValue)}async function dn(e,t){if(t instanceof ReadableStream){let r=e.body??t;try{let[n,o]=r.tee(),i=new Request(e,{body:n,duplex:"half"}),s=await Bt(o,q);return{body:new TextDecoder("utf-8").decode(s,{stream:!0}),request:i}}catch{return{body:_t}}}return typeof t=="string"?{body:t}:{}}function Ni(){let e=on.create({});function t(n){return(o,i)=>{let s=Be.active(),a,l=!1,u=(d,m)=>{a&&!l&&(l=!0,Ne(a,d,m))},f=e.extend({hooks:{beforeRequest:[async(d,m)=>{let p=await dn(d,m.body),V=p.body;if(a||(a=x.startSpan("externalApi",{kind:ge.CLIENT},s)),a.setAttributes({method:d.method.toUpperCase(),host:Le(d.url)}),v(a,"request",{url:d.url,method:d.method.toUpperCase(),...V!==void 0?{body:V}:{}}),l=!1,E("hasExternal"),p.request)return p.request}],beforeRetry:[d=>{u("error","retry"),a=void 0,l=!1}],afterResponse:[async(d,m,p)=>{a&&(a.setAttribute("statusCode",p.status),await Lt(a,p.status,{kyResponse:p}),p.ok?u("success"):i?.throwHttpErrors===!1&&(E("hasError"),u("error",`HTTP ${p.status}`)))}],beforeError:[d=>(E("hasError"),u("error",d.message),d)]}});return a=x.startSpan("externalApi",{kind:ge.CLIENT},s),a.setAttributes({method:n.toUpperCase(),host:Le(String(o))}),Be.with(sn.setSpan(Be.active(),a),()=>{let d=n==="options"?f(o,{...i,method:"OPTIONS"}):f[n](o,i);return d.catch(m=>{E("hasError"),u("error",m instanceof Error?m.message:String(m))}),d})}}let r=Object.fromEntries(an.map(n=>[n,t(n)]));return{...e,...r,authed(n){return fn(n)}}}function fn(e){let r=b().authentications??{};if(!r[e])throw c.unknownAlias(e,Object.keys(r));let n=r[e];function o(i){return(s,a={})=>{let l=i.toUpperCase();return cn(l,s,a.body,async u=>{E("hasAuth");let f=x.startSpan("auth",{kind:ge.INTERNAL});f.setAttribute("alias",e),f.setAttribute("id",n),f.end();try{let d=z({authenticationId:n,method:l,url:s,body:a.body,headers:a.headers,query:a.query}),m=await pe(d,{timeout:a.timeout});return u.setAttribute("statusCode",m.status),await Lt(u,m.status,{bodyValue:m.body}),Ne(u,"success"),m}catch(d){throw E("hasError"),d instanceof c&&d.detail.kind==="broker_error"&&d.detail.status>0&&u.setAttribute("statusCode",d.detail.status),Ne(u,"error",d instanceof Error?d.message:String(d)),d}})}}return{get:o("get"),post:o("post"),put:o("put"),patch:o("patch"),delete:o("delete"),head:o("head"),options:o("options")}}import{SpanKind as En,SpanStatusCode as Ut}from"@opentelemetry/api";function Z(e){let t=e.trimStart().match(/^([A-Za-z]+)/);return t?t[1].toUpperCase():"QUERY"}var mn=18e4,Nt=mn-1e4,pn=2e3;async function jt(e,t,r){let n=new Set(["FINISHED","FAILED","ABORTED"]),o=Date.now(),i=0;for(;Date.now()-o<Nt;){let s=await e(t,"DescribeStatement",{Id:r}),a=s.Status;if(n.has(a))return s;let l=Math.min(pn,200*2**i),u=l/2+Math.random()*(l/2),f=Nt-(Date.now()-o);await new Promise(d=>setTimeout(d,Math.min(u,f))),i++}throw c.dbCallFailed(`statement polling exceeded budget after ${Date.now()-o}ms`)}var gn=new Set(["SELECT","WITH","SHOW"]),yn=new Set(["INSERT","UPDATE","DELETE","MERGE"]);function hn(e){if(!e.clusterIdentifier&&!e.workgroupName)throw c.dbInvalidParameters("either clusterIdentifier or workgroupName is required");if(e.clusterIdentifier&&e.workgroupName)throw c.dbInvalidParameters("clusterIdentifier and workgroupName are mutually exclusive (Provisioned vs Serverless)");if(!e.database)throw c.dbInvalidParameters("database is required");if(e.clusterIdentifier&&!e.dbUser)throw c.dbInvalidParameters("dbUser is required when using clusterIdentifier (Provisioned)");if(!e.region)throw c.dbInvalidParameters("region is required")}function wn(e,t){let r=null;if(typeof t=="string")try{r=JSON.parse(t)}catch{}else t!==null&&typeof t=="object"&&(r=t);let n=typeof r?.__type=="string"?r.__type:void 0,o=typeof r?.message=="string"?r.message:void 0;if(n&&o)return c.dbQueryFailed(`${n}: ${o}`);let i=typeof t=="string"?k(t):g(t);return c.dbCallFailed(i)}function bn(e){if(e==null||typeof e!="string")return e;try{return JSON.parse(e)}catch{throw c.dbCallFailed("upstream body not JSON: "+e.slice(0,200))}}function Sn(e,t){return typeof t!="number"||t<0?{}:gn.has(e)?{rowsRead:t}:yn.has(e)?{rowsWritten:t}:{}}function Mt(e){async function t(r,n,o){let i=z({authenticationId:e,method:"POST",url:`https://redshift-data.${r}.amazonaws.com/`,body:o,headers:{"Content-Type":"application/x-amz-json-1.1","X-Amz-Target":`RedshiftData.${n}`}});try{let{status:s,body:a}=await pe(i);if(s>=400)throw wn(s,a);return bn(a)}catch(s){if(s instanceof c)throw s;let a=s instanceof Error?s.message??String(s):String(s);throw c.dbCallFailed(a,s instanceof Error?s:void 0)}}return{system:"redshift",validate:hn,async execute(r,n){let o=Z(n),i={Sql:n,Database:r.database,...r.clusterIdentifier&&{ClusterIdentifier:r.clusterIdentifier,DbUser:r.dbUser},...r.workgroupName&&{WorkgroupName:r.workgroupName},...r.statementName&&{StatementName:r.statementName}},s=await t(r.region,"ExecuteStatement",i),a=s,l=typeof a?.Id=="string"?a.Id:void 0;if(!l){let p=g(s);throw c.dbCallFailed(`ExecuteStatement response missing Id; got: ${p}`)}let u=await jt(t,r.region,l),f=u.Status;if(f==="FAILED"){let p=typeof u.Error=="string"?u.Error:"statement failed";throw c.dbQueryFailed(`${p} (statement: ${l})`)}if(f==="ABORTED")throw c.dbQueryFailed(`statement aborted (statement: ${l})`);let d=Sn(o,u.ResultRows);return u.HasResultSet===!1?{result:{rowsAffected:u.ResultRows??0},metadata:d}:{result:await t(r.region,"GetStatementResult",{Id:l}),metadata:d}}}}var je=64*1024;function xn(e){return e.length>je?`${e.slice(0,je)}...[truncated]`:e}function vn(e,t,r,n,o){e.setAttributes({system:t.system,statement:o,namespace:r.database,operation:n})}function Rn(e,t,r){let n=typeof t=="string"?t:JSON.stringify(t);return n.length>je?v(e,"result",{truncated:!0,size:n.length}):v(e,"result",t),r.rowsRead!==void 0&&e.setAttribute("rowsRead",r.rowsRead),r.rowsWritten!==void 0&&e.setAttribute("rowsWritten",r.rowsWritten),n}async function Tn(e,t,r){let n=Z(r),o=xn(r);return x.startActiveSpan("database",{kind:En.CLIENT},async i=>{vn(i,e,t,n,o);try{E("hasDb");let{result:s,metadata:a}=await e.execute(t,r),l=Rn(i,s,a);return i.setAttribute("status","success"),i.setStatus({code:Ut.OK}),l}catch(s){E("hasError");let a=s instanceof Error?s.message:String(s);throw i.setAttribute("status","error"),i.setStatus({code:Ut.ERROR,message:a}),s}finally{i.end()}})}function Pn(e){let r=b().authentications??{};if(!r[e])throw c.unknownAlias(e,Object.keys(r));let n=r[e],o=Mt(n);function i(s,a){return o.validate(s),Tn(o,s,a)}return{parameters(s){return{sql(a){return i(s,a)}}},sql(s){return i({},s)}}}import{createStorage as Dn}from"unstorage";var $t=1024,Me=250*1024,Cn=new TextEncoder,kn=/(^|\/)\.\.(\/|$)/,In=/[?#]/,An=/[\u0000-\u001F\u007F]/;function Kt(e){if(e.length===0)throw c.kvKeyInvalid("Key must be a non-empty string");if(kn.test(e))throw c.kvKeyInvalid("Key contains path traversal segment");if(In.test(e)||An.test(e))throw c.kvKeyInvalid("Key contains illegal characters");if(e.startsWith("/")||e.endsWith("/")||e.split("/").some(r=>r===""))throw c.kvKeyInvalid("Key must not contain empty path segments");let t=Cn.encode(e).length;if(t<1||t>$t)throw c.kvKeyInvalid(`Key must be between 1 and ${$t} UTF-8 bytes (got ${t})`)}function Ht(e){let t;try{t=JSON.stringify(e)}catch{throw c.kvValueInvalid("Value must be JSON-serializable")}if(t===void 0)throw c.kvValueInvalid("Value must be JSON-serializable");let r=Buffer.byteLength(t,"utf8");if(r>Me)throw c.kvValueTooLarge(`Value exceeds maximum size of ${Me} bytes (got ${r})`,Me)}function ee(e){Kt(e)}function ye(e,t){let r=e[t];if(typeof r!="function")throw new Error(`KV driver is missing ${t}`);return r}function Vt(e){let t=ye(e,"getItem"),r=ye(e,"setItem"),n=ye(e,"removeItem"),o=ye(e,"hasItem"),i=e.getKeys;return{...e,getItem(s,a){return ee(s),t(s,a)},setItem(s,a,l){return ee(s),r(s,a,l)},removeItem(s,a){return ee(s),n(s,a)},hasItem(s,a){return ee(s),o(s,a)},getKeys(s,a){return s.length>0&&ee(s),i(s,a)}}}function he(e){return Dn({driver:Vt(e)})}import{defineDriver as On}from"unstorage";function Fn(e){try{return JSON.parse(e)}catch{return e}}var _n=On(e=>{let{client:t}=e;return{name:"helix-kv",async getItem(r){let n=await t.get(r);return n===null?null:JSON.stringify(n)},async setItem(r,n){await t.set(r,Fn(n))},async removeItem(r){await t.delete(r)},async hasItem(r){return await t.has(r)},async getKeys(){throw new Error("KV key listing is not supported")}}});function zt(e){return _n({client:e})}import Nn from"ky";import{z as h}from"zod";async function j(e){let t=e.headers.get("content-type")??"",r=await e.text();if(r.length!==0)return t.includes("application/json")?JSON.parse(r):r}function Jt(e){return D(e).hosts.api}function Bn(e){return`/private/v1/helix/projects/${encodeURIComponent(e)}/storage/kv`}function Ln(e){return e.split("/").map(encodeURIComponent).join("/")}function te(e,t,r){return`${e}${Bn(t)}/${Ln(r)}`}var jn=6e4,Ue=h.lazy(()=>h.union([h.string(),h.number(),h.boolean(),h.null(),h.array(Ue),h.record(Ue)])),Mn=h.object({projectId:h.string(),key:h.string(),value:Ue,type:h.enum(["string","number","boolean","null","array","object"]),organizationId:h.string(),scope:h.string(),createdBy:h.string(),createdAt:h.number(),updatedBy:h.string(),updatedAt:h.number()});function Un(){let e=_(),t=T(),r=!!(e&&e.trim().length>0),n=!!(t&&t.trim().length>0);if(!r&&!n)throw c.missingExecutionCredentials();let o={Accept:"application/json"};return r&&(o[F]=e),n&&(o[R]=t),o}function $n(e){if(e!==null&&typeof e=="object"){let t=e;if(typeof t.message=="string")return t.message;if(typeof t.error=="string")return t.error}return String(e??"unknown error")}function we(e,t){throw c.kvCallFailed(e,$n(t),g(t))}async function be(e,t,r={}){try{let n=await Nn(t,{method:e,headers:Un(),...r.json!==void 0?{json:r.json}:{},throwHttpErrors:!1,timeout:jn}),o=e==="head"?void 0:await j(n);return{status:n.status,body:o}}catch(n){if(n instanceof c)throw n;let o=n instanceof Error?n.message??String(n):String(n);throw c.kvCallFailed(0,o)}}function qt(e){let t=Jt(e.env),{projectId:r}=e;return{async get(n){let{status:o,body:i}=await be("get",te(t,r,n));if(o===404)return null;(o<200||o>=300)&&we(o,i);let s=Mn.safeParse(i);if(!s.success)throw c.kvCallFailed(o,"platform returned malformed KeyValueEntry",g(i));return s.data.value},async set(n,o){let{status:i,body:s}=await be("put",te(t,r,n),{json:{value:o}});(i<200||i>=300)&&we(i,s)},async delete(n){let{status:o,body:i}=await be("delete",te(t,r,n));o!==204&&we(o,i)},async has(n){let{status:o,body:i}=await be("head",te(t,r,n));if(o===200)return!0;if(o===404)return!1;we(o,i)}}}function Se(e){return{getItem:(t,r)=>e.getItem(t,r),removeItem:(t,r)=>e.removeItem(t,r),hasItem:(t,r)=>e.hasItem(t,r),setItem:async(t,r,n)=>{Ht(r),await e.setItem(t,r,n)}}}function Kn(){let e=b();if(e.kind!=="provisioned")throw c.kvRequiresProvisioning();return{projectId:e.projectId,env:e.env}}function Yt(e){let t=Kn(),r=e??qt(t),n=he(zt(r));return Se(n)}import Hn from"unstorage/drivers/memory";var $e;function Vn(){return $e||($e=he(Hn())),$e}function Xt(){return Se(Vn())}function zn(){return typeof __TRAY_SDK_MODE__<"u"?__TRAY_SDK_MODE__==="lambda":w().mode==="lambda"}function Us(){return zn()?Yt():Xt()}import{createHash as Yn}from"crypto";import{mkdir as Xn,readFile as er,readdir as tr,rm as Gt,unlink as Wn,writeFile as Qt}from"fs/promises";import{dirname as Gn}from"path";async function Jn(e){let t=e.getReader(),r=[],n=0;for(;;){let{done:o,value:i}=await t.read();if(o)break;if(i){if(n+=i.byteLength,n>P)throw await t.cancel(),c.filesValueTooLarge(`File exceeds maximum size of ${P} bytes (got more than ${P})`,P);r.push(i)}}return Buffer.concat(r)}async function M(e){return Buffer.isBuffer(e)?e:typeof e=="string"?Buffer.from(e,"utf-8"):e instanceof ReadableStream?Jn(e):Buffer.from(e)}var qn={pdf:"application/pdf",csv:"text/csv",png:"image/png",jpg:"image/jpeg",jpeg:"image/jpeg",gif:"image/gif",webp:"image/webp",svg:"image/svg+xml",json:"application/json",txt:"text/plain",html:"text/html",htm:"text/html",css:"text/css",js:"application/javascript",xml:"application/xml",zip:"application/zip"},Wt="application/octet-stream";function Ee(e){let t=e.lastIndexOf(".");if(t===-1||t===e.length-1)return Wt;let r=e.slice(t+1).toLowerCase();return qn[r]??Wt}function $(){let e=w().projectRoot;if(!e)throw c.filesNotAvailable();return e}async function U(e){try{return await e()}catch(t){if(t instanceof c)throw t;let r=t?.code;throw r?c.filesCallFailed(0,`Local file storage operation failed: ${r}`):c.filesCallFailed(0,"Local file storage operation failed: unknown error")}}function xe(e,t){return{path:e,size:t.size,contentType:t.contentType,lastModified:new Date(t.lastModified),etag:t.etag}}async function Ke(e){try{let t=await er(de($(),e),"utf-8");return JSON.parse(t)}catch(t){if(t.code==="ENOENT")return null;throw t}}async function Zt(e){await Xn(Gn(e),{recursive:!0})}async function Qn(e,t){let r=fe(e,t),n;try{n=await tr(r,{withFileTypes:!0})}catch(o){if(o.code==="ENOENT")return[];throw o}return n.filter(o=>o.isFile()).map(o=>t.length===0?o.name:`${t}/${o.name}`)}async function rr(e,t){let r=fe(e,t),n;try{n=await tr(r,{withFileTypes:!0})}catch(i){if(i.code==="ENOENT")return[];throw i}let o=[];for(let i of n){let s=t.length===0?i.name:`${t}/${i.name}`;i.isDirectory()?o.push(...await rr(e,s)):i.isFile()&&o.push(s)}return o}function nr(){return{async put(e,t,r){return U(async()=>{let n=$(),o=await M(t),i=r?.contentType??Ee(e),s=Yn("sha1").update(o).digest("hex"),a=new Date,l=Q(n,e);await Zt(l),await Qt(l,o);let u={size:o.byteLength,contentType:i,lastModified:a.toISOString(),etag:s},f=de(n,e);return await Zt(f),await Qt(f,JSON.stringify(u)),xe(e,u)})},async get(e){return U(async()=>{let t=await Ke(e);return t?{data:await er(Q($(),e)),metadata:xe(e,t)}:null})},async head(e){return U(async()=>{let t=await Ke(e);return t?xe(e,t):null})},async delete(e){return U(async()=>{let t=$();await Promise.all([Q(t,e),de(t,e)].map(async r=>{try{await Wn(r)}catch(n){if(n.code!=="ENOENT")throw n}}))})},async deleteMany(e){return U(async()=>{let t=$(),r=await rr(t,e);return await Promise.all([Gt(fe(t,e),{recursive:!0,force:!0}),Gt(It(t,e),{recursive:!0,force:!0})]),{deleted:r.length}})},async list(e,t){return U(async()=>{let r=$(),n=t?.limit??100,i=(await Qn(r,e??"")).slice(0,n);return{files:(await Promise.all(i.map(async a=>{let l=await Ke(a);return l?xe(a,l):null}))).filter(a=>a!==null),cursor:null}})},async getUploadUrl(e,t){let r=w().devServerUrl;if(!r)throw c.filesNotAvailable();return{url:`${r}/_helix/files/${e}`,expiresAt:N(t?.expiresIn)}},async getDownloadUrl(e,t){let r=w().devServerUrl;if(!r)throw c.filesNotAvailable();return{url:`${r}/_helix/files/${e}`,expiresAt:N(t?.expiresIn)}}}}import{createHash as io}from"crypto";function ve(e){return D(e).hosts.api}function Zn(e){return`/private/v1/helix/files/projects/${encodeURIComponent(e)}`}function re(e,t){return`${e}${Zn(t)}`}function K(e,t,r){return`${re(e,t)}/${encodeURIComponent(r)}`}function Re(e,t,r){return`${K(e,t,r)}/upload`}function or(e,t,r){return`${K(e,t,r)}/download`}function ir(e,t,r){return`${K(e,t,r)}/signed-url`}function sr(e,t,r,n){let o=new URLSearchParams({name:n});return r&&o.set("parentFolder",r),`${re(e,t)}/file?${o.toString()}`}function ar(e,t,r,n){let o=new URLSearchParams({limit:String(n)});return r&&o.set("id",r),`${re(e,t)}?${o.toString()}`}import Ve from"ky";import{z as y}from"zod";var ze=6e4,cr=y.object({id:y.string(),workspaceId:y.string(),projectId:y.string(),parentFolder:y.string().nullable().optional(),name:y.string(),size:y.number().nullable().optional(),objectType:y.enum(["Folder","File"]),contentType:y.string().nullable().optional(),createdAt:y.string(),updatedAt:y.string()}),eo=y.object({signedURL:y.string()}),to=y.object({path:y.array(y.object({id:y.string(),name:y.string()})),elements:y.array(cr)});function Je(){let e=_(),t=T(),r=!!(e&&e.trim().length>0),n=!!(t&&t.trim().length>0);if(!r&&!n)throw c.missingExecutionCredentials();let o={Accept:"application/json"};return r&&(o[F]=e),n&&(o[R]=t),o}function lr(e){if(e!==null&&typeof e=="object"){let t=e;if(typeof t.message=="string")return t.message;if(typeof t.error=="string")return t.error}return String(e??"unknown error")}function C(e,t){throw c.filesCallFailed(e,lr(t),g(t))}function ro(e,t){return e===400&&lr(t).toLowerCase()==="resource not found"}async function no(e){let t=new Response(e),r=t.headers.get("content-type")??"multipart/form-data",n=await t.arrayBuffer();return{body:Buffer.from(n),contentType:r}}async function H(e,t,r={}){try{let n=await Ve(t,{method:e,headers:Je(),...r.json!==void 0?{json:r.json}:{},throwHttpErrors:!1,timeout:ze}),o=await j(n);return{status:n.status,body:o}}catch(n){if(n instanceof c)throw n;let o=n instanceof Error?n.message:String(n);throw c.filesCallFailed(0,o)}}function He(e,t){let r=cr.safeParse(t);if(!r.success)throw c.filesCallFailed(e,"platform returned malformed ObjectMetadata",g(t));return r.data}function ur(e){let t=ve(e.env),{projectId:r}=e;return{async createMetadata(n){let{status:o,body:i}=await H("post",re(t,r),{json:n});return(o<200||o>=300)&&C(o,i),He(o,i)},async getByName(n,o){let{status:i,body:s}=await H("get",sr(t,r,n,o));return i===404||ro(i,s)?null:((i<200||i>=300)&&C(i,s),He(i,s))},async getById(n){let{status:o,body:i}=await H("get",K(t,r,n));return o===404?null:((o<200||o>=300)&&C(o,i),He(o,i))},async listChildren(n,o){let{status:i,body:s}=await H("get",ar(t,r,n,o));(i<200||i>=300)&&C(i,s);let a=to.safeParse(s);if(!a.success)throw c.filesCallFailed(i,"platform returned malformed listing",g(s));return a.data},async uploadContent(n,o,i,s){let a=new FormData;a.append("fileUploadContentInput",new Blob([new Uint8Array(o)],{type:s}),i);let{body:l,contentType:u}=await no(a),f;try{f=await Ve(Re(t,r,n),{method:"post",headers:{...Je(),"content-type":u},body:new Uint8Array(l),throwHttpErrors:!1,timeout:ze})}catch(m){if(m instanceof c)throw m;let p=m instanceof Error?m.message:String(m);throw c.filesCallFailed(0,p)}let d=await j(f);(f.status<200||f.status>=300)&&C(f.status,d)},async downloadContent(n){let o;try{o=await Ve(or(t,r,n),{method:"get",headers:Je(),throwHttpErrors:!1,timeout:ze})}catch(s){if(s instanceof c)throw s;let a=s instanceof Error?s.message:String(s);throw c.filesCallFailed(0,a)}if(o.status<200||o.status>=300){let s=await j(o);C(o.status,s)}let i=await o.arrayBuffer();return Buffer.from(i)},async getSignedDownloadUrl(n){let{status:o,body:i}=await H("get",ir(t,r,n));(o<200||o>=300)&&C(o,i);let s=eo.safeParse(i);if(!s.success)throw c.filesCallFailed(o,"platform returned malformed signed URL response",g(i));return s.data.signedURL},async deleteById(n){let{status:o,body:i}=await H("delete",K(t,r,n));o===204||o===404||(o<200||o>=300)&&C(o,i)}}}function qe(e){return e.split("/").filter(t=>t.length>0)}function Ye(e){return e instanceof c&&e.detail.kind==="files_call_failed"&&e.detail.status===409}async function oo(e,t,r){let n=await e.getByName(t,r);if(n)return n;try{return await e.createMetadata({parentFolder:t,objectType:"Folder",name:r})}catch(o){if(Ye(o)){let i=await e.getByName(t,r);if(i)return i}throw o}}async function Xe(e,t){let r=qe(t),n=r[r.length-1],o;for(let i of r.slice(0,-1))o=(await oo(e,o,i)).id;return{parentFolder:o,name:n}}async function ne(e,t){let r=qe(t),n=r[r.length-1],o;for(let i of r.slice(0,-1)){let s=await e.getByName(o,i);if(!s||s.objectType!=="Folder")return null;o=s.id}return{parentFolder:o,name:n}}async function We(e,t){if(t.length===0)return;let r=qe(t),n;for(let o of r){let i=await e.getByName(n,o);if(!i||i.objectType!=="Folder")return null;n=i.id}return n}var so=500,ao=8;async function co(e,t,r){let n=new Array(e.length),o=0;async function i(){for(;o<e.length;){let s=o++;n[s]=await r(e[s])}}return await Promise.all(Array.from({length:Math.min(t,e.length)},i)),n}function lo(){let e=b();if(e.kind!=="provisioned")throw c.filesRequiresProvisioning();return{projectId:e.projectId,env:e.env}}function uo(e){return io("sha1").update(`${e.id}:${e.updatedAt}:${e.size??0}`).digest("hex")}function Te(e,t,r){return{path:e,size:t.size??0,contentType:t.contentType??r??"application/octet-stream",lastModified:new Date(t.updatedAt),etag:uo(t)}}async function dr(e,t,r,n){try{return await e.createMetadata({parentFolder:t,objectType:"File",contentType:n,name:r})}catch(o){if(Ye(o)){let i=await e.getByName(t,r);if(i)return i}throw o}}async function fr(e,t){let{elements:r}=await e.listChildren(t,so);return(await co(r,ao,async o=>{let i=o.objectType==="Folder"?await fr(e,o.id):1;return await e.deleteById(o.id),i})).reduce((o,i)=>o+i,0)}function mr(e){let t=lo(),r=e??ur(t),n=ve(t.env),{projectId:o}=t;return{async put(i,s,a){let{parentFolder:l,name:u}=await Xe(r,i),f=await M(s),d=a?.contentType??Ee(i),m=await r.getByName(l,u);if(m&&m.objectType!=="File")throw c.filesCallFailed(409,`A folder already exists at "${i}"`);let p=m??await dr(r,l,u,d);await r.uploadContent(p.id,f,u,d);let V=await r.getById(p.id);return Te(i,V??p,d)},async get(i){let s=await ne(r,i);if(!s)return null;let a=await r.getByName(s.parentFolder,s.name);return!a||a.objectType!=="File"?null:{data:await r.downloadContent(a.id),metadata:Te(i,a)}},async head(i){let s=await ne(r,i);if(!s)return null;let a=await r.getByName(s.parentFolder,s.name);return!a||a.objectType!=="File"?null:Te(i,a)},async delete(i){let s=await ne(r,i);if(!s)return;let a=await r.getByName(s.parentFolder,s.name);a&&await r.deleteById(a.id)},async deleteMany(i){let s=await We(r,i);if(s===null)return{deleted:0};let a=await fr(r,s);return i.length>0&&s!==void 0&&await r.deleteById(s),{deleted:a}},async list(i,s){let a=await We(r,i??"");if(a===null)return{files:[],cursor:null};let l=s?.limit??100,{elements:u}=await r.listChildren(a,l);return{files:u.filter(d=>d.objectType==="File").map(d=>Te(i?`${i}/${d.name}`:d.name,d)),cursor:null}},async getUploadUrl(i,s){let{parentFolder:a,name:l}=await Xe(r,i),f=await r.getByName(a,l)??await dr(r,a,l,s?.contentType);return{url:Re(n,o,f.id),expiresAt:N(s?.expiresIn)}},async getDownloadUrl(i,s){let a=await ne(r,i),l=a?await r.getByName(a.parentFolder,a.name):null;if(!l||l.objectType!=="File")throw c.filesCallFailed(404,`File not found: ${i}`);return{url:await r.getSignedDownloadUrl(l.id),expiresAt:N(s?.expiresIn)}}}}function Ge(e,t){let r=t?.maxPathBytes;return{async put(n,o,i){I(n,r);let s=await M(o);return Ct(s.byteLength),e.put(n,s,i)},async get(n){return I(n,r),e.get(n)},async head(n){return I(n,r),e.head(n)},async delete(n){return I(n,r),e.delete(n)},async deleteMany(n){let o=_e(n);return le(o,r),e.deleteMany(o)},async list(n,o){let i=_e(n??"");return le(i,r),e.list(i,o)},async getUploadUrl(n,o){return I(n,r),e.getUploadUrl(n,o)},async getDownloadUrl(n,o){return I(n,r),e.getDownloadUrl(n,o)}}}function fo(){return typeof __TRAY_SDK_MODE__<"u"?__TRAY_SDK_MODE__==="lambda":w().mode==="lambda"}function Oa(){if(fo())return Ge(mr());let e=w().projectRoot;return Ge(nr(),{maxPathBytes:e?kt(e):void 0})}export{mo as a,w as b,go as c,yo as d,b as e,ho as f,Et as g,Br as h,E as i,v as j,$r as k,Kr as l,x as m,Hr as n,zo as o,ni as p,si as q,Ni as r,Pn as s,Us as t,I as u,Q as v,de as w,Oa as x,At as y,A as z,Go as A,Qo as B};
|
package/dist/chunk-H4L4UWIK.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
var b=new Set(["production"]),i=new Map,m={name:"production",exposedName:"us1",displayName:"production",hosts:{api:"https://api.tray.io",broker:"https://api.tray.io/private/v1/code",ingest:"https://api.tray.io/private/v1/helix/otlp",weaver:"https://weaver.tray.io",app:"https://app.tray.io",projectHost:"helix-app.ai",dashboard:"https://app.helix.tray.ai",auth:"https://auth.tray.io"},login:{storePrefix:"PROD",appUrl:"https://app.tray.io",cookieName:"prod_tray_lid",cookieDomain:"tray.io"}};i.set(m.name,m);var v=["api","broker","ingest","weaver","app","projectHost","dashboard"],y=["auth"],h=["storePrefix","appUrl","cookieName","cookieDomain"];function w(e){if(!e.name||typeof e.name!="string")throw new Error("EnvironmentProfile.name must be a non-empty string");if(!e.exposedName||typeof e.exposedName!="string")throw new Error("EnvironmentProfile.exposedName must be a non-empty string");if(!e.displayName||typeof e.displayName!="string")throw new Error("EnvironmentProfile.displayName must be a non-empty string");if(!e.hosts||typeof e.hosts!="object")throw new Error("EnvironmentProfile.hosts must be an object");if(!e.login||typeof e.login!="object")throw new Error("EnvironmentProfile.login must be an object");for(let r of v)if(typeof e.hosts[r]!="string"||!e.hosts[r])throw new Error(`EnvironmentProfile.hosts.${r} must be a non-empty string`);for(let r of y){let n=e.hosts[r];if(n!==void 0&&(typeof n!="string"||!n))throw new Error(`EnvironmentProfile.hosts.${r} must be a non-empty string when set`)}for(let r of h)if(typeof e.login[r]!="string"||!e.login[r])throw new Error(`EnvironmentProfile.login.${r} must be a non-empty string`)}function x(e,r){return e.name===r.name&&e.exposedName===r.exposedName&&e.displayName===r.displayName&&v.every(n=>e.hosts[n]===r.hosts[n])&&y.every(n=>e.hosts[n]===r.hosts[n])&&h.every(n=>e.login[n]===r.login[n])}function j(e){w(e);let r=i.get(e.name);if(r){if(x(r,e))return;throw new Error(`EnvironmentProfile.name "${e.name}" is already registered with different values`)}for(let n of i.values())if(n.exposedName===e.exposedName)throw new Error(`EnvironmentProfile.exposedName "${e.exposedName}" is already used by "${n.name}"`);i.set(e.name,e)}function S(e){return i.has(e)}function A(e){return i.get(e)}function _(e){let r=i.get(e);if(!r)throw new Error(`Unknown environment: ${e}`);return r}function F(){return[...i.keys()]}function T(){return[...i.values()].map(e=>e.exposedName)}function R(e){for(let r of i.values())if(r.exposedName===e)return r.name}var g=Symbol.for("@trayai/helix-sdk.forcedEnvironment");function N(e){let r=globalThis;if(e===void 0||e.trim()===""){delete r[g];return}let n=e.trim(),o=R(n);if(o){r[g]=o;return}if(S(n)){r[g]=n;return}throw new Error(`Unknown environment: ${n}`)}function H(){return globalThis[g]}function V(){return[...i.values()].filter(e=>!b.has(e.name))}function L(){N(void 0),i.clear(),i.set(m.name,{...m,hosts:{...m.hosts},login:{...m.login}})}var f=class e extends Error{detail;constructor(r){super(P(r)),this.name="SdkError",this.detail=r}get kind(){return this.detail.kind}static unknownAlias(r,n){return new e({kind:"unknown_alias",alias:r,available:n})}static inputValidationFailed(r){return new e({kind:"input_validation_failed",fields:r})}static outputValidationFailed(r){return new e({kind:"output_validation_failed",fields:r})}static configLoadFailed(r){return new e({kind:"config_load_failed",cause:r})}static brokerError(r,n,o){return new e({kind:"broker_error",status:r,message:n,body:o})}static unsupportedBodyType(r){return new e({kind:"unsupported_body_type",actualType:r})}static unsupportedScheme(r){return new e({kind:"unsupported_scheme",scheme:r})}static missingExecutionCredentials(){return new e({kind:"missing_execution_credentials"})}static missingTrayToken(){return new e({kind:"missing_tray_token"})}static dbCallFailed(r,n){return new e({kind:"db_call_failed",message:r,cause:n})}static dbQueryFailed(r){return new e({kind:"db_query_failed",message:r})}static dbInvalidParameters(r){return new e({kind:"db_invalid_parameters",message:r})}static kvKeyInvalid(r){return new e({kind:"kv_key_invalid",message:r})}static kvValueInvalid(r){return new e({kind:"kv_value_invalid",message:r})}static kvValueTooLarge(r,n){return new e({kind:"kv_value_too_large",message:r,maxBytes:n})}static kvNotAvailable(){return new e({kind:"kv_not_available"})}static kvCallFailed(r,n,o){return new e({kind:"kv_call_failed",status:r,message:n,body:o})}static kvRequiresProvisioning(){return new e({kind:"kv_requires_provisioning"})}static filesPathInvalid(r){return new e({kind:"files_path_invalid",message:r})}static filesValueInvalid(r){return new e({kind:"files_value_invalid",message:r})}static filesValueTooLarge(r,n){return new e({kind:"files_value_too_large",message:r,maxBytes:n})}static filesNotAvailable(){return new e({kind:"files_not_available"})}static filesCallFailed(r,n,o){return new e({kind:"files_call_failed",status:r,message:n,body:o})}static filesRequiresProvisioning(){return new e({kind:"files_requires_provisioning"})}};function O(e){return e instanceof f}function P(e){switch(e.kind){case"unknown_alias":return`Unknown auth alias "${e.alias}". Available: ${e.available.join(", ")||"(none)"}`;case"input_validation_failed":return`Input validation failed for fields: ${e.fields.join(", ")}`;case"output_validation_failed":return`Output validation failed for fields: ${e.fields.join(", ")}`;case"config_load_failed":return`Config load failed: ${e.cause}`;case"broker_error":return`broker error: ${e.status} ${e.message}`;case"unsupported_body_type":return`unsupported body type: ${e.actualType}`;case"unsupported_scheme":return`unsupported scheme: ${e.scheme} (only https supported)`;case"missing_execution_credentials":return"missing execution credentials: at least one of internalJwt / helixExecutionJwt must be set before an authed broker/KV call";case"missing_tray_token":return"Not logged in. Run `helix login` to authenticate before making authed HTTP calls in dev.";case"db_call_failed":return`Database call failed: ${e.message}`;case"db_query_failed":return`Database query failed: ${e.message}`;case"db_invalid_parameters":return`Invalid database parameters: ${e.message}`;case"kv_key_invalid":return`Invalid KV key: ${e.message}`;case"kv_value_invalid":return e.message;case"kv_value_too_large":return e.message;case"kv_not_available":return"Key-value store is not available in this environment";case"kv_call_failed":return`KV platform error: ${e.status} ${e.message}`;case"kv_requires_provisioning":return"Key-value store requires a provisioned project (run helix project set)";case"files_path_invalid":return`Invalid file path: ${e.message}`;case"files_value_invalid":return e.message;case"files_value_too_large":return e.message;case"files_not_available":return"File storage is not available in this environment";case"files_call_failed":return`Files platform error: ${e.status} ${e.message}`;case"files_requires_provisioning":return"File storage requires a provisioned project (run helix project set)"}}var B=new Set(["proxy-authorization","x-tray-token"]);function q(e){let r=e.toLowerCase();return B.has(r)||r.startsWith("x-tray-internal-")}function $(e){let r;return e instanceof Headers?r=Array.from(e.entries()):Array.isArray(e)?r=e:r=Object.entries(e),r.filter(([n])=>!q(n)).map(([n,o])=>({name:n,value:o}))}function I(e){return typeof e=="string"?"string":e instanceof Blob?"Blob":e instanceof FormData?"FormData":e instanceof ArrayBuffer?"ArrayBuffer":e instanceof Uint8Array?"Uint8Array":typeof ReadableStream<"u"&&e instanceof ReadableStream?"ReadableStream":null}function z(e){let r=new URL(e.url);if(r.protocol!=="https:")throw f.unsupportedScheme(r.protocol.replace(/:$/,""));let n=e.body!==void 0&&e.body!==null?I(e.body):null;if(n!==null)throw f.unsupportedBodyType(n);let o=r.host,a=r.pathname,s=[];for(let[c,d]of r.searchParams.entries())s.push({name:c,value:d});if(e.query!==void 0)if(e.query instanceof URLSearchParams)for(let[c,d]of e.query.entries())s.push({name:c,value:d});else for(let[c,d]of Object.entries(e.query))if(Array.isArray(d))for(let E of d)s.push({name:c,value:E});else s.push({name:c,value:d});let l=e.headers!==void 0?$(e.headers):[],u=e.body!==void 0&&e.body!==null?{host:o,method:e.method,path:a,body:e.body,headers:l,queryParams:s}:{host:o,method:e.method,path:a,headers:l,queryParams:s};return{authenticationId:e.authenticationId,httpRequest:u}}function M(e){return _(e).hosts.broker}import{z as t}from"zod";var k=t.object({name:t.string(),value:t.string()}),D=t.object({host:t.string(),method:t.string(),path:t.string().startsWith("/"),body:t.record(t.unknown()).optional(),headers:t.array(k),queryParams:t.array(k)}),J=t.object({authenticationId:t.string().uuid(),httpRequest:D}),X=t.object({httpResponse:t.object({status:t.number(),body:t.unknown().optional(),headers:t.array(k)})});function ee(e){let{status:r,body:n,headers:o}=e.httpResponse,a={};for(let{name:s,value:l}of o){let p=s.toLowerCase(),u=a[p];u===void 0?a[p]=l:Array.isArray(u)?u.push(l):a[p]=[u,l]}return{status:r,body:n,headers:a}}export{j as a,S as b,A as c,_ as d,F as e,T as f,R as g,N as h,H as i,V as j,L as k,f as l,O as m,z as n,M as o,X as p,ee as q};
|