@trayai/helix-sdk 0.89.0 → 0.90.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 +19 -1
- package/README.md +1 -1
- package/dist/chunk-WUCX7RZO.js +1 -0
- package/dist/index.d.ts +4 -4
- package/dist/index.js +1 -1
- package/dist/internal/index.js +1 -1
- package/dist/testing/index.d.ts +7 -4
- package/dist/testing/index.js +1 -1
- package/dist/{types-CoD3x7L-.d.ts → types-D01XG3C4.d.ts} +46 -25
- package/package.json +1 -1
- package/dist/chunk-L6J5L3JQ.js +0 -1
package/CHANGELOG.md
CHANGED
|
@@ -11,9 +11,27 @@ released together and share a version — install matching versions.
|
|
|
11
11
|
|
|
12
12
|
## 0.89.0
|
|
13
13
|
|
|
14
|
+
### Changed
|
|
15
|
+
|
|
16
|
+
- **`getContext()` now returns `PlatformContext`.** It previously returned `TrayContext`;
|
|
17
|
+
it now returns the canonical execution context, ahead of execution kinds that are not
|
|
18
|
+
yet generally available. The members present in every execution (`http`, `db()`,
|
|
19
|
+
`kv()`, `files()`, `log`, `config`, `state`, `executionId`, `deploymentId`, `traceId`)
|
|
20
|
+
are unchanged. Request-specific fields (`input`, `method`, `path`, `headers`,
|
|
21
|
+
`request`, `status()`, `error()`, `userId`, `identity`) are now optional — check the
|
|
22
|
+
field you read, e.g. `const ctx = getContext(); if (ctx.method !== undefined) { ctx.method; }`.
|
|
23
|
+
Handler parameters are unaffected: `defineFunction` handlers still receive the exact
|
|
24
|
+
`TrayContext`.
|
|
25
|
+
- **`runWithContext` mocks mirror production for optional fields.** Accessing an unset
|
|
26
|
+
optional `PlatformContext` field in a mock now returns `undefined` (so presence-guard
|
|
27
|
+
code is testable) instead of throwing; unset always-present fields still throw the
|
|
28
|
+
descriptive error.
|
|
29
|
+
- The error thrown when `getContext()` is called outside an execution now reads
|
|
30
|
+
"getContext() called outside of a Helix function execution…".
|
|
31
|
+
|
|
14
32
|
### Removed
|
|
15
33
|
|
|
16
|
-
- **`ctx.trigger.isRetry` for scheduled functions
|
|
34
|
+
- **`ctx.trigger.isRetry` for scheduled functions.** The flag was reserved and
|
|
17
35
|
always `false`: no platform signal reliably distinguishes a retried *execution* from a
|
|
18
36
|
redelivered *message* (SQS's receive count measures deliveries, not runs, and can under-
|
|
19
37
|
as well as over-report), so rather than promise a boolean the platform cannot honestly
|
package/README.md
CHANGED
|
@@ -210,7 +210,7 @@ const result = await runWithContext({ input: { name: 'Ada' } }, async () => {
|
|
|
210
210
|
});
|
|
211
211
|
```
|
|
212
212
|
|
|
213
|
-
The mock context is a Proxy:
|
|
213
|
+
The mock context is a Proxy: touching an always-present field (`http`, `db`, `log`, `executionId`, …) you didn't provide throws a descriptive error, so tests fail loudly — as does touching a field that isn't part of the context at all. Fields that aren't guaranteed on every execution (for example `userId` and `identity`) instead return `undefined` when unset, just as they can at runtime.
|
|
214
214
|
|
|
215
215
|
## Entry points
|
|
216
216
|
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{AsyncLocalStorage as e}from"async_hooks";var o=new e;function r(){let t=o.getStore();if(!t)throw new Error("getContext() called outside of a Helix function execution. It is available only while a defineFunction or defineSchedule invocation is executing \u2014 from any code the handler calls.");return t}export{o as a,r as b};
|
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,
|
|
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, U as UnvalidatedInput } from './types-
|
|
3
|
+
import { F as FunctionHandler, D as DefineFunctionOptions, a as DefineScheduleConfig, S as ScheduleDefinition, P as PlatformContext } from './types-D01XG3C4.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-D01XG3C4.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';
|
|
@@ -75,7 +75,7 @@ declare function runWithinAppSpan<T extends {
|
|
|
75
75
|
};
|
|
76
76
|
} | null>(args: RunWithinAppSpanArgs, serve: () => Promise<T>): Promise<T>;
|
|
77
77
|
|
|
78
|
-
declare function getContext():
|
|
78
|
+
declare function getContext(): PlatformContext;
|
|
79
79
|
|
|
80
80
|
/**
|
|
81
81
|
* Type-level helper for helix.config.ts — provides autocomplete in the editor.
|
|
@@ -134,4 +134,4 @@ interface ConfigService {
|
|
|
134
134
|
*/
|
|
135
135
|
declare function createConfigService(options: CreateConfigServiceOptions): Promise<ConfigService>;
|
|
136
136
|
|
|
137
|
-
export { type ConfigService, type CreateConfigServiceOptions, DefineFunctionOptions, DefineScheduleConfig, FunctionHandler, LoadedTrayConfig, type RunWithinAppSpanArgs, SCHEDULE_DEFINITION_KIND, ScheduleConfigError, ScheduleDefinition, TrayConfig,
|
|
137
|
+
export { type ConfigService, type CreateConfigServiceOptions, DefineFunctionOptions, DefineScheduleConfig, FunctionHandler, LoadedTrayConfig, PlatformContext, type RunWithinAppSpanArgs, SCHEDULE_DEFINITION_KIND, ScheduleConfigError, ScheduleDefinition, TrayConfig, WatchErrorPhase, createConfigService, defineConfig, defineFunction, defineSchedule, getContext, isScheduleDefinition, runWithinAppSpan };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import{a as B,b as me}from"./chunk-L6J5L3JQ.js";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{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-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}
|
|
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.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{B as
|
|
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-3SDUCOAT.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-H4L4UWIK.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
|
@@ -1,13 +1,16 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { P as PlatformContext } from '../types-D01XG3C4.js';
|
|
2
2
|
import 'h3';
|
|
3
3
|
import 'ky';
|
|
4
4
|
import 'zod';
|
|
5
5
|
import 'unstorage';
|
|
6
6
|
|
|
7
7
|
/**
|
|
8
|
-
* Run code within a mock
|
|
9
|
-
*
|
|
8
|
+
* Run code within a mock PlatformContext — for unit testing shared code that
|
|
9
|
+
* calls getContext(). Unset core fields throw on access via Proxy, as does
|
|
10
|
+
* anything that isn't a context field at all (typo protection); unset
|
|
11
|
+
* optional fields (request surface, trigger) return undefined, as in a real
|
|
12
|
+
* execution of a kind that doesn't carry them.
|
|
10
13
|
*/
|
|
11
|
-
declare function runWithContext<T>(partial: Partial<
|
|
14
|
+
declare function runWithContext<T>(partial: Partial<PlatformContext>, fn: () => T | Promise<T>): Promise<T>;
|
|
12
15
|
|
|
13
16
|
export { runWithContext };
|
package/dist/testing/index.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{a as
|
|
1
|
+
import{a as n}from"../chunk-WUCX7RZO.js";var f={http:!0,db:!0,kv:!0,files:!0,log:!0,config:!0,state:!0,executionId:!0,deploymentId:!0,traceId:!0},d={input:!0,method:!0,path:!0,headers:!0,status:!0,error:!0,request:!0,userId:!0,identity:!0,trigger:!0};async function l(o,i){let u=new Proxy(o,{get(e,t,r){if(typeof t=="symbol"||t==="then"||t==="toJSON"||t in e)return Reflect.get(e,t,r);if(!(t in d))throw t in f?new Error(`Accessed unset context field "${String(t)}" in test. Provide it via runWithContext({ ${String(t)}: ... }, fn).`):new Error(`Accessed unknown context field "${String(t)}" in test \u2014 not a PlatformContext member.`)}});return n.run(u,i)}export{l as runWithContext};
|
|
@@ -123,23 +123,31 @@ interface BrokerAuthedClient {
|
|
|
123
123
|
interface HttpClient extends KyInstance {
|
|
124
124
|
authed(alias: string): BrokerAuthedClient;
|
|
125
125
|
}
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
126
|
+
/**
|
|
127
|
+
* Members present in every execution kind (defineFunction, defineSchedule):
|
|
128
|
+
* platform clients, project config, and execution identity. Not readonly —
|
|
129
|
+
* define-function stamps ctx.traceId after the root span exists.
|
|
130
|
+
*/
|
|
131
|
+
interface ContextCore {
|
|
131
132
|
http: HttpClient;
|
|
132
133
|
db(alias: string): DbClient;
|
|
133
134
|
kv(): KeyValueStore;
|
|
134
135
|
files(): FileSystemClient;
|
|
135
136
|
log: Logger;
|
|
136
137
|
config: Record<string, unknown>;
|
|
137
|
-
status(code: number): void;
|
|
138
|
-
error(code: number, message: string): never;
|
|
139
138
|
state: Record<string, unknown>;
|
|
140
|
-
request: H3Event;
|
|
141
139
|
executionId: string;
|
|
142
140
|
deploymentId: string | null;
|
|
141
|
+
traceId: string;
|
|
142
|
+
}
|
|
143
|
+
interface TrayContext<T = Record<string, unknown>> extends ContextCore {
|
|
144
|
+
input: T;
|
|
145
|
+
method: string;
|
|
146
|
+
path: string;
|
|
147
|
+
headers: Record<string, string | undefined>;
|
|
148
|
+
status(code: number): void;
|
|
149
|
+
error(code: number, message: string): never;
|
|
150
|
+
request: H3Event;
|
|
143
151
|
userId: string | null;
|
|
144
152
|
/**
|
|
145
153
|
* Minimal user identity context (spec 15). Production currently carries
|
|
@@ -152,7 +160,6 @@ interface TrayContext<T = Record<string, unknown>> {
|
|
|
152
160
|
id: string;
|
|
153
161
|
};
|
|
154
162
|
} | null;
|
|
155
|
-
traceId: string;
|
|
156
163
|
}
|
|
157
164
|
|
|
158
165
|
/** Sentinel type — skip input validation when only output validation is desired */
|
|
@@ -173,24 +180,38 @@ interface ScheduleTrigger {
|
|
|
173
180
|
isManual: boolean;
|
|
174
181
|
}
|
|
175
182
|
/**
|
|
176
|
-
* Context for scheduled handlers: the
|
|
177
|
-
*
|
|
178
|
-
*
|
|
179
|
-
*
|
|
183
|
+
* Context for scheduled handlers: the core platform surface with every
|
|
184
|
+
* request-derived field (input, method, path, headers, status, error,
|
|
185
|
+
* request) structurally absent — scheduled runs have no request and no user,
|
|
186
|
+
* so those fields are omitted rather than null.
|
|
180
187
|
*/
|
|
181
|
-
interface ScheduleContext {
|
|
182
|
-
http: HttpClient;
|
|
183
|
-
db(alias: string): DbClient;
|
|
184
|
-
kv(): KeyValueStore;
|
|
185
|
-
files(): FileSystemClient;
|
|
186
|
-
log: Logger;
|
|
187
|
-
config: Record<string, unknown>;
|
|
188
|
-
state: Record<string, unknown>;
|
|
189
|
-
executionId: string;
|
|
190
|
-
deploymentId: string | null;
|
|
191
|
-
traceId: string;
|
|
188
|
+
interface ScheduleContext extends ContextCore {
|
|
192
189
|
trigger: ScheduleTrigger;
|
|
193
190
|
}
|
|
191
|
+
/**
|
|
192
|
+
* The canonical execution context — what contextStore holds and getContext()
|
|
193
|
+
* returns. Every execution kind populates the core; the optional fields are
|
|
194
|
+
* present per kind (request surface for functions, trigger for schedules).
|
|
195
|
+
* Handlers receive the exact subtypes (TrayContext, ScheduleContext), both
|
|
196
|
+
* structurally assignable to this canonical view; shared code checks field
|
|
197
|
+
* presence (e.g. `if (ctx.request)`, `if (ctx.trigger)`) before use.
|
|
198
|
+
*/
|
|
199
|
+
interface PlatformContext extends ContextCore {
|
|
200
|
+
input?: Record<string, unknown>;
|
|
201
|
+
method?: string;
|
|
202
|
+
path?: string;
|
|
203
|
+
headers?: Record<string, string | undefined>;
|
|
204
|
+
status?(code: number): void;
|
|
205
|
+
error?(code: number, message: string): never;
|
|
206
|
+
request?: H3Event;
|
|
207
|
+
userId?: string | null;
|
|
208
|
+
identity?: {
|
|
209
|
+
user: {
|
|
210
|
+
id: string;
|
|
211
|
+
};
|
|
212
|
+
} | null;
|
|
213
|
+
trigger?: ScheduleTrigger;
|
|
214
|
+
}
|
|
194
215
|
type ScheduleHandler = (ctx: ScheduleContext) => Promise<void> | void;
|
|
195
216
|
interface DefineScheduleConfig {
|
|
196
217
|
/** 5-field standard cron (minute hour day-of-month month day-of-week). */
|
|
@@ -218,4 +239,4 @@ interface ScheduleDefinition {
|
|
|
218
239
|
handler: ScheduleHandler;
|
|
219
240
|
}
|
|
220
241
|
|
|
221
|
-
export type { DefineFunctionOptions as D, FunctionHandler as F, HttpClient as H, KeyValueStore as K, Logger as L, ScheduleDefinition as S, TrayContext as T, UnvalidatedInput as U, DefineScheduleConfig as a, DbCallParameters as b, DbClient as c, FileSystemClient as d, ScheduleContext as e, ScheduleHandler as f, ScheduleTrigger as g, SqlBuilder as h };
|
|
242
|
+
export type { DefineFunctionOptions as D, FunctionHandler as F, HttpClient as H, KeyValueStore as K, Logger as L, PlatformContext as P, ScheduleDefinition as S, TrayContext as T, UnvalidatedInput as U, DefineScheduleConfig as a, DbCallParameters as b, DbClient as c, FileSystemClient as d, ScheduleContext as e, ScheduleHandler as f, ScheduleTrigger as g, SqlBuilder as h };
|
package/package.json
CHANGED
package/dist/chunk-L6J5L3JQ.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{AsyncLocalStorage as e}from"async_hooks";var o=new e;function r(){let t=o.getStore();if(!t)throw new Error("getContext() called outside of a defineFunction handler. Ensure this code runs inside a function wrapped with defineFunction().");return t}export{o as a,r as b};
|