@bluelibs/runner 4.8.3 → 4.8.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (41) hide show
  1. package/dist/browser/index.cjs +531 -272
  2. package/dist/browser/index.cjs.map +1 -1
  3. package/dist/browser/index.mjs +529 -273
  4. package/dist/browser/index.mjs.map +1 -1
  5. package/dist/defs.d.ts +2 -0
  6. package/dist/edge/index.cjs +531 -272
  7. package/dist/edge/index.cjs.map +1 -1
  8. package/dist/edge/index.mjs +529 -273
  9. package/dist/edge/index.mjs.map +1 -1
  10. package/dist/globals/globalResources.d.ts +1 -1
  11. package/dist/globals/globalTags.d.ts +1 -1
  12. package/dist/globals/resources/tunnel/types.d.ts +25 -0
  13. package/dist/globals/types.d.ts +2 -0
  14. package/dist/http-fetch-tunnel.resource.d.ts +2 -24
  15. package/dist/index.d.ts +8 -6
  16. package/dist/models/MiddlewareManager.d.ts +25 -36
  17. package/dist/models/Store.d.ts +2 -2
  18. package/dist/models/TaskRunner.d.ts +1 -1
  19. package/dist/models/middleware/InterceptorRegistry.d.ts +56 -0
  20. package/dist/models/middleware/MiddlewareResolver.d.ts +31 -0
  21. package/dist/models/middleware/ResourceMiddlewareComposer.d.ts +34 -0
  22. package/dist/models/middleware/TaskMiddlewareComposer.d.ts +43 -0
  23. package/dist/models/middleware/ValidationHelper.d.ts +20 -0
  24. package/dist/models/middleware/index.d.ts +6 -0
  25. package/dist/models/middleware/types.d.ts +10 -0
  26. package/dist/node/exposure/requestContext.d.ts +1 -1
  27. package/dist/node/exposure.resource.d.ts +1 -1
  28. package/dist/node/node.cjs +541 -274
  29. package/dist/node/node.cjs.map +1 -1
  30. package/dist/node/node.d.ts +10 -7
  31. package/dist/node/node.mjs +539 -275
  32. package/dist/node/node.mjs.map +1 -1
  33. package/dist/types/asyncContext.d.ts +1 -1
  34. package/dist/types/symbols.d.ts +0 -2
  35. package/dist/types/task.d.ts +5 -1
  36. package/dist/types/utilities.d.ts +2 -2
  37. package/dist/universal/index.cjs +531 -272
  38. package/dist/universal/index.cjs.map +1 -1
  39. package/dist/universal/index.mjs +529 -273
  40. package/dist/universal/index.mjs.map +1 -1
  41. package/package.json +1 -1
@@ -19,6 +19,8 @@ var __export = (target, all) => {
19
19
  // src/defs.ts
20
20
  var defs_exports = {};
21
21
  __export(defs_exports, {
22
+ ASYNC_CONTEXT_TYPES_LOADED: () => ASYNC_CONTEXT_TYPES_LOADED,
23
+ ERROR_TYPES_LOADED: () => ERROR_TYPES_LOADED,
22
24
  RunnerMode: () => RunnerMode,
23
25
  isOneOf: () => isOneOf,
24
26
  onAnyOf: () => onAnyOf,
@@ -38,8 +40,7 @@ __export(defs_exports, {
38
40
  symbolTagConfigured: () => symbolTagConfigured,
39
41
  symbolTask: () => symbolTask,
40
42
  symbolTaskMiddleware: () => symbolTaskMiddleware,
41
- symbolTunneledBy: () => symbolTunneledBy,
42
- symbolTunneledTask: () => symbolTunneledTask
43
+ symbolTunneledBy: () => symbolTunneledBy
43
44
  });
44
45
 
45
46
  // src/types/symbols.ts
@@ -63,9 +64,6 @@ var symbolResourceMiddleware = Symbol.for(
63
64
  var symbolMiddlewareConfigured = Symbol.for(
64
65
  "runner.middlewareConfigured"
65
66
  );
66
- var symbolTunneledTask = Symbol.for(
67
- "runner.tunneledTask"
68
- );
69
67
  var symbolTunneledBy = Symbol.for(
70
68
  "runner.tunneledBy"
71
69
  );
@@ -99,6 +97,12 @@ var RunnerMode = /* @__PURE__ */ ((RunnerMode2) => {
99
97
  RunnerMode2["PROD"] = "prod";
100
98
  return RunnerMode2;
101
99
  })(RunnerMode || {});
100
+
101
+ // src/types/asyncContext.ts
102
+ var ASYNC_CONTEXT_TYPES_LOADED = true;
103
+
104
+ // src/types/error.ts
105
+ var ERROR_TYPES_LOADED = true;
102
106
  var cacheFactoryTask = defineTask({
103
107
  id: "globals.tasks.cacheFactory",
104
108
  run: /* @__PURE__ */ __name(async (options) => {
@@ -1481,6 +1485,12 @@ function assertOkEnvelope(envelope, opts) {
1481
1485
  }
1482
1486
  __name(assertOkEnvelope, "assertOkEnvelope");
1483
1487
 
1488
+ // src/globals/resources/tunnel/error-utils.ts
1489
+ function normalizeError(input) {
1490
+ return input instanceof Error ? input : new Error(String(input));
1491
+ }
1492
+ __name(normalizeError, "normalizeError");
1493
+
1484
1494
  // src/http-fetch-tunnel.resource.ts
1485
1495
  async function postSerialized(fetchFn, url, body, headers, timeoutMs, serializer2, onRequest, contextHeaderText) {
1486
1496
  const controller = timeoutMs && timeoutMs > 0 ? new AbortController() : void 0;
@@ -2073,39 +2083,33 @@ var TaskRunner = class {
2073
2083
  }
2074
2084
  };
2075
2085
 
2076
- // src/models/MiddlewareManager.ts
2077
- var MiddlewareManager = class {
2078
- constructor(store2, eventManager, logger) {
2079
- this.store = store2;
2080
- this.eventManager = eventManager;
2081
- this.logger = logger;
2082
- // Interceptor storage
2083
- this.taskMiddlewareInterceptors = [];
2084
- this.resourceMiddlewareInterceptors = [];
2085
- // Per-middleware interceptor storage
2086
- this.perMiddlewareInterceptors = /* @__PURE__ */ new Map();
2087
- this.perResourceMiddlewareInterceptors = /* @__PURE__ */ new Map();
2088
- // Locking mechanism to prevent modifications after initialization
2086
+ // src/models/middleware/InterceptorRegistry.ts
2087
+ var InterceptorRegistry = class {
2088
+ constructor() {
2089
+ this.taskInterceptors = [];
2090
+ this.resourceInterceptors = [];
2091
+ this.perTaskMiddleware = /* @__PURE__ */ new Map();
2092
+ this.perResourceMiddleware = /* @__PURE__ */ new Map();
2089
2093
  this.#isLocked = false;
2090
2094
  }
2091
2095
  static {
2092
- __name(this, "MiddlewareManager");
2096
+ __name(this, "InterceptorRegistry");
2093
2097
  }
2094
2098
  #isLocked;
2095
2099
  /**
2096
- * Gets the current lock status of the MiddlewareManager
2100
+ * Gets the current lock status
2097
2101
  */
2098
2102
  get isLocked() {
2099
2103
  return this.#isLocked;
2100
2104
  }
2101
2105
  /**
2102
- * Locks the MiddlewareManager, preventing any further modifications to interceptors
2106
+ * Locks the registry, preventing any further modifications
2103
2107
  */
2104
2108
  lock() {
2105
2109
  this.#isLocked = true;
2106
2110
  }
2107
2111
  /**
2108
- * Throws an error if the MiddlewareManager is locked
2112
+ * Throws an error if the registry is locked
2109
2113
  */
2110
2114
  checkLock() {
2111
2115
  if (this.#isLocked) {
@@ -2113,193 +2117,288 @@ var MiddlewareManager = class {
2113
2117
  }
2114
2118
  }
2115
2119
  /**
2116
- * Adds an interceptor for task or resource middleware execution
2117
- * Interceptors are executed in the order they are added, with the ability to
2118
- * modify, log, or prevent middleware execution
2119
- *
2120
- * @param kind - The type of middleware to intercept ("task" or "resource")
2121
- * @param interceptor - The interceptor function to add
2120
+ * Adds a global task interceptor
2122
2121
  */
2123
- intercept(kind, interceptor) {
2122
+ addGlobalTaskInterceptor(interceptor) {
2124
2123
  this.checkLock();
2125
- if (kind === "task") {
2126
- this.taskMiddlewareInterceptors.push(
2127
- interceptor
2128
- );
2129
- } else {
2130
- this.resourceMiddlewareInterceptors.push(
2131
- interceptor
2132
- );
2124
+ this.taskInterceptors.push(interceptor);
2125
+ }
2126
+ /**
2127
+ * Adds a global resource interceptor
2128
+ */
2129
+ addGlobalResourceInterceptor(interceptor) {
2130
+ this.checkLock();
2131
+ this.resourceInterceptors.push(interceptor);
2132
+ }
2133
+ /**
2134
+ * Adds an interceptor for a specific task middleware instance
2135
+ */
2136
+ addTaskMiddlewareInterceptor(middlewareId, interceptor) {
2137
+ this.checkLock();
2138
+ if (!this.perTaskMiddleware.has(middlewareId)) {
2139
+ this.perTaskMiddleware.set(middlewareId, []);
2133
2140
  }
2141
+ this.perTaskMiddleware.get(middlewareId).push(interceptor);
2134
2142
  }
2135
2143
  /**
2136
- * Adds an interceptor for a specific middleware instance with better type safety
2137
- * This method automatically determines the type and provides type-safe access
2138
- *
2139
- * @param middleware - The middleware instance to intercept
2140
- * @param interceptor - The interceptor function with proper typing
2144
+ * Adds an interceptor for a specific resource middleware instance
2141
2145
  */
2142
- interceptMiddleware(middleware, interceptor) {
2146
+ addResourceMiddlewareInterceptor(middlewareId, interceptor) {
2143
2147
  this.checkLock();
2144
- if (isTaskMiddleware(middleware)) {
2145
- if (!this.perMiddlewareInterceptors.has(middleware.id)) {
2146
- this.perMiddlewareInterceptors.set(middleware.id, []);
2148
+ if (!this.perResourceMiddleware.has(middlewareId)) {
2149
+ this.perResourceMiddleware.set(middlewareId, []);
2150
+ }
2151
+ this.perResourceMiddleware.get(middlewareId).push(interceptor);
2152
+ }
2153
+ /**
2154
+ * Gets all global task interceptors
2155
+ */
2156
+ getGlobalTaskInterceptors() {
2157
+ return this.taskInterceptors;
2158
+ }
2159
+ /**
2160
+ * Gets all global resource interceptors
2161
+ */
2162
+ getGlobalResourceInterceptors() {
2163
+ return this.resourceInterceptors;
2164
+ }
2165
+ /**
2166
+ * Gets interceptors for a specific task middleware
2167
+ */
2168
+ getTaskMiddlewareInterceptors(middlewareId) {
2169
+ return this.perTaskMiddleware.get(middlewareId) || [];
2170
+ }
2171
+ /**
2172
+ * Gets interceptors for a specific resource middleware
2173
+ */
2174
+ getResourceMiddlewareInterceptors(middlewareId) {
2175
+ return this.perResourceMiddleware.get(middlewareId) || [];
2176
+ }
2177
+ };
2178
+
2179
+ // src/models/middleware/MiddlewareResolver.ts
2180
+ var MiddlewareResolver = class {
2181
+ constructor(store2) {
2182
+ this.store = store2;
2183
+ }
2184
+ static {
2185
+ __name(this, "MiddlewareResolver");
2186
+ }
2187
+ /**
2188
+ * Gets all applicable middlewares for a task (global + local, deduplicated)
2189
+ */
2190
+ getApplicableTaskMiddlewares(task2) {
2191
+ const local = task2.middleware;
2192
+ const localIds = new Set(local.map((m) => m.id));
2193
+ const global = this.getEverywhereTaskMiddlewares(task2).filter(
2194
+ (m) => !localIds.has(m.id)
2195
+ );
2196
+ return [...global, ...local];
2197
+ }
2198
+ /**
2199
+ * Gets all applicable middlewares for a resource (global + local, deduplicated)
2200
+ */
2201
+ getApplicableResourceMiddlewares(resource2) {
2202
+ const local = resource2.middleware;
2203
+ const localIds = new Set(local.map((m) => m.id));
2204
+ const global = this.getEverywhereResourceMiddlewares(resource2).filter(
2205
+ (m) => !localIds.has(m.id)
2206
+ );
2207
+ return [...global, ...local];
2208
+ }
2209
+ /**
2210
+ * Applies tunnel policy filter to middlewares if task is tunneled
2211
+ * Only allows whitelisted middlewares when tunnel policy is set
2212
+ */
2213
+ applyTunnelPolicyFilter(task2, middlewares) {
2214
+ const tDef = this.store.tasks.get(task2.id).task;
2215
+ const isLocallyTunneled = tDef.isTunneled;
2216
+ if (!isLocallyTunneled || !globalTags.tunnelPolicy.exists(tDef)) {
2217
+ return middlewares;
2218
+ }
2219
+ const cfg = globalTags.tunnelPolicy.extract(task2);
2220
+ const allowList = cfg?.client;
2221
+ if (!Array.isArray(allowList)) {
2222
+ return middlewares;
2223
+ }
2224
+ const toId = /* @__PURE__ */ __name((x) => typeof x === "string" ? x : x?.id, "toId");
2225
+ const allowed = new Set(allowList.map(toId).filter(Boolean));
2226
+ return middlewares.filter((m) => allowed.has(m.id));
2227
+ }
2228
+ /**
2229
+ * Gets all "everywhere" middlewares that apply to the given task
2230
+ */
2231
+ getEverywhereTaskMiddlewares(task2) {
2232
+ return Array.from(this.store.taskMiddlewares.values()).filter((x) => Boolean(x.middleware.everywhere)).filter((x) => {
2233
+ if (typeof x.middleware.everywhere === "function") {
2234
+ return x.middleware.everywhere(task2);
2147
2235
  }
2148
- this.perMiddlewareInterceptors.get(middleware.id).push(interceptor);
2149
- } else if (isResourceMiddleware(middleware)) {
2150
- if (!this.perResourceMiddlewareInterceptors.has(middleware.id)) {
2151
- this.perResourceMiddlewareInterceptors.set(middleware.id, []);
2236
+ return true;
2237
+ }).map((x) => x.middleware);
2238
+ }
2239
+ /**
2240
+ * Gets all "everywhere" middlewares that apply to the given resource
2241
+ */
2242
+ getEverywhereResourceMiddlewares(resource2) {
2243
+ return Array.from(this.store.resourceMiddlewares.values()).filter((x) => Boolean(x.middleware.everywhere)).filter((x) => {
2244
+ if (typeof x.middleware.everywhere === "function") {
2245
+ return x.middleware.everywhere(resource2);
2152
2246
  }
2153
- this.perResourceMiddlewareInterceptors.get(middleware.id).push(interceptor);
2154
- } else {
2155
- throw new Error("Unknown middleware type");
2247
+ return true;
2248
+ }).map((x) => x.middleware);
2249
+ }
2250
+ };
2251
+
2252
+ // src/models/middleware/ValidationHelper.ts
2253
+ var ValidationHelper = class {
2254
+ static {
2255
+ __name(this, "ValidationHelper");
2256
+ }
2257
+ /**
2258
+ * Validates input using the provided schema
2259
+ * @throws ValidationError if validation fails
2260
+ */
2261
+ static validateInput(value, schema, id2, type) {
2262
+ if (!schema) return value;
2263
+ try {
2264
+ return schema.parse(value);
2265
+ } catch (error2) {
2266
+ return validationError.throw({
2267
+ subject: `${type} input`,
2268
+ id: id2,
2269
+ originalError: error2 instanceof Error ? error2 : new Error(String(error2))
2270
+ });
2156
2271
  }
2157
2272
  }
2158
2273
  /**
2159
- * Wrap a middleware with its specific interceptors in onion style
2274
+ * Validates result using the provided schema
2275
+ * @throws ValidationError if validation fails
2160
2276
  */
2161
- wrapMiddlewareWithInterceptors(middleware, middlewareRunner, interceptors) {
2162
- if (!interceptors.length) {
2163
- return middlewareRunner;
2277
+ static validateResult(value, schema, id2, type) {
2278
+ if (!schema) return value;
2279
+ try {
2280
+ return schema.parse(value);
2281
+ } catch (error2) {
2282
+ return validationError.throw({
2283
+ subject: `${type} result`,
2284
+ id: id2,
2285
+ originalError: error2 instanceof Error ? error2 : new Error(String(error2))
2286
+ });
2164
2287
  }
2165
- const reversedInterceptors = [...interceptors].reverse();
2166
- let wrapped = middlewareRunner;
2167
- for (let i = reversedInterceptors.length - 1; i >= 0; i--) {
2168
- const interceptor = reversedInterceptors[i];
2288
+ }
2289
+ };
2290
+
2291
+ // src/models/middleware/TaskMiddlewareComposer.ts
2292
+ var TaskMiddlewareComposer = class {
2293
+ constructor(store2, interceptorRegistry, middlewareResolver) {
2294
+ this.store = store2;
2295
+ this.interceptorRegistry = interceptorRegistry;
2296
+ this.middlewareResolver = middlewareResolver;
2297
+ }
2298
+ static {
2299
+ __name(this, "TaskMiddlewareComposer");
2300
+ }
2301
+ /**
2302
+ * Composes a complete task runner with all middleware and interceptors applied
2303
+ */
2304
+ compose(task2) {
2305
+ const storeTask = this.store.tasks.get(task2.id);
2306
+ let runner = this.createBaseRunner(task2, storeTask);
2307
+ runner = this.applyLocalInterceptors(runner, storeTask);
2308
+ runner = this.applyGlobalInterceptors(runner, task2);
2309
+ runner = this.applyMiddlewares(runner, task2, storeTask);
2310
+ return runner;
2311
+ }
2312
+ /**
2313
+ * Creates the base task runner with input/result validation
2314
+ */
2315
+ createBaseRunner(task2, storeTask) {
2316
+ return async (input) => {
2317
+ const runnerTask = this.resolveTaskDefinition(task2, storeTask.task);
2318
+ const validatedInput = ValidationHelper.validateInput(
2319
+ input,
2320
+ runnerTask.inputSchema,
2321
+ runnerTask.id,
2322
+ "Task"
2323
+ );
2324
+ const rawResult = await runnerTask.run(
2325
+ validatedInput,
2326
+ storeTask.computedDependencies
2327
+ );
2328
+ return ValidationHelper.validateResult(
2329
+ rawResult,
2330
+ runnerTask.resultSchema,
2331
+ runnerTask.id,
2332
+ "Task"
2333
+ );
2334
+ };
2335
+ }
2336
+ /**
2337
+ * Determines which task definition to use for execution
2338
+ * Prefers store definition when task is tunneled (tunnel overrides apply)
2339
+ */
2340
+ resolveTaskDefinition(task2, storeTask) {
2341
+ const isLocallyTunneled = task2.isTunneled || storeTask.isTunneled;
2342
+ return isLocallyTunneled ? storeTask : task2;
2343
+ }
2344
+ /**
2345
+ * Applies local per-task interceptors (closest to the task)
2346
+ */
2347
+ applyLocalInterceptors(runner, storeTask) {
2348
+ if (!storeTask.interceptors || storeTask.interceptors.length === 0) {
2349
+ return runner;
2350
+ }
2351
+ let wrapped = runner;
2352
+ for (let i = storeTask.interceptors.length - 1; i >= 0; i--) {
2353
+ const interceptor = storeTask.interceptors[i];
2169
2354
  const nextFunction = wrapped;
2170
- wrapped = /* @__PURE__ */ __name(async (input) => {
2171
- const executionInput = {
2172
- task: {
2173
- definition: null,
2174
- // Will be filled by middleware.run
2175
- input
2176
- },
2177
- next: nextFunction
2178
- };
2179
- const wrappedNext = /* @__PURE__ */ __name((i2) => {
2180
- return nextFunction(i2.task.input);
2181
- }, "wrappedNext");
2182
- return interceptor(wrappedNext, executionInput);
2183
- }, "wrapped");
2355
+ wrapped = /* @__PURE__ */ __name(async (input) => interceptor(nextFunction, input), "wrapped");
2184
2356
  }
2185
2357
  return wrapped;
2186
2358
  }
2187
2359
  /**
2188
- * Wrap a resource middleware with its specific interceptors in onion style
2360
+ * Applies global task middleware interceptors
2189
2361
  */
2190
- wrapResourceMiddlewareWithInterceptors(middleware, middlewareRunner, interceptors) {
2191
- if (!interceptors.length) {
2192
- return middlewareRunner;
2362
+ applyGlobalInterceptors(runner, task2) {
2363
+ const interceptors = this.interceptorRegistry.getGlobalTaskInterceptors();
2364
+ if (interceptors.length === 0) {
2365
+ return runner;
2193
2366
  }
2194
2367
  const reversedInterceptors = [...interceptors].reverse();
2195
- let wrapped = middlewareRunner;
2368
+ const createExecutionInput = /* @__PURE__ */ __name((input, nextFunc) => ({
2369
+ task: {
2370
+ definition: task2,
2371
+ input
2372
+ },
2373
+ next: nextFunc
2374
+ }), "createExecutionInput");
2375
+ let currentNext = runner;
2196
2376
  for (let i = reversedInterceptors.length - 1; i >= 0; i--) {
2197
2377
  const interceptor = reversedInterceptors[i];
2198
- const nextFunction = wrapped;
2199
- wrapped = /* @__PURE__ */ __name(async (config) => {
2200
- const executionInput = {
2201
- resource: {
2202
- definition: null,
2203
- // Will be filled by middleware.run
2204
- config
2205
- },
2206
- next: nextFunction
2207
- };
2208
- const wrappedNext = /* @__PURE__ */ __name((input) => {
2209
- return nextFunction(input.resource.config);
2378
+ const nextFunction = currentNext;
2379
+ currentNext = /* @__PURE__ */ __name(async (input) => {
2380
+ const executionInput = createExecutionInput(input, nextFunction);
2381
+ const wrappedNext = /* @__PURE__ */ __name((i2) => {
2382
+ return nextFunction(i2.task.input);
2210
2383
  }, "wrappedNext");
2211
2384
  return interceptor(wrappedNext, executionInput);
2212
- }, "wrapped");
2385
+ }, "currentNext");
2213
2386
  }
2214
- return wrapped;
2387
+ return currentNext;
2215
2388
  }
2216
2389
  /**
2217
- * Compose a runner for a task with its local interceptors and applicable middlewares.
2218
- * Returns a function that accepts the task input and resolves to the task output.
2390
+ * Applies task middleware layers (global first, then local)
2219
2391
  */
2220
- composeTaskRunner(task2) {
2221
- const storeTask = this.store.tasks.get(task2.id);
2222
- const tDef = storeTask.task;
2223
- let next = /* @__PURE__ */ __name(async (input) => {
2224
- let rawInput = input;
2225
- const isLocallyTunneled = task2[symbolTunneledTask] === "client" || tDef[symbolTunneledTask] === "client";
2226
- const runnerTask = isLocallyTunneled ? tDef : task2;
2227
- if (runnerTask.inputSchema) {
2228
- try {
2229
- rawInput = runnerTask.inputSchema.parse(rawInput);
2230
- } catch (error2) {
2231
- validationError.throw({
2232
- subject: "Task input",
2233
- id: runnerTask.id,
2234
- originalError: error2 instanceof Error ? error2 : new Error(String(error2))
2235
- });
2236
- }
2237
- }
2238
- const deps = storeTask.computedDependencies;
2239
- const rawResult = await runnerTask.run.call(null, rawInput, deps);
2240
- if (runnerTask.resultSchema) {
2241
- try {
2242
- return runnerTask.resultSchema.parse(rawResult);
2243
- } catch (error2) {
2244
- validationError.throw({
2245
- subject: "Task result",
2246
- id: runnerTask.id,
2247
- originalError: error2
2248
- });
2249
- }
2250
- }
2251
- return rawResult;
2252
- }, "next");
2253
- if (storeTask.interceptors && storeTask.interceptors.length > 0) {
2254
- for (let i = storeTask.interceptors.length - 1; i >= 0; i--) {
2255
- const interceptor = storeTask.interceptors[i];
2256
- const nextFunction = next;
2257
- next = /* @__PURE__ */ __name(async (input) => interceptor(nextFunction, input), "next");
2258
- }
2259
- }
2260
- if (this.taskMiddlewareInterceptors.length > 0) {
2261
- const reversedInterceptors = [
2262
- ...this.taskMiddlewareInterceptors
2263
- ].reverse();
2264
- const createExecutionInput = /* @__PURE__ */ __name((input, nextFunc) => ({
2265
- task: {
2266
- definition: task2,
2267
- input
2268
- },
2269
- next: nextFunc
2270
- }), "createExecutionInput");
2271
- let currentNext = next;
2272
- for (let i = reversedInterceptors.length - 1; i >= 0; i--) {
2273
- const interceptor = reversedInterceptors[i];
2274
- const nextFunction = currentNext;
2275
- currentNext = /* @__PURE__ */ __name(async (input) => {
2276
- const executionInput = createExecutionInput(input, nextFunction);
2277
- const wrappedNext = /* @__PURE__ */ __name((i2) => {
2278
- return nextFunction(i2.task.input);
2279
- }, "wrappedNext");
2280
- return interceptor(wrappedNext, executionInput);
2281
- }, "currentNext");
2282
- }
2283
- next = currentNext;
2284
- }
2285
- let createdMiddlewares = this.getApplicableTaskMiddlewares(task2);
2286
- const isLocallyTunneledPolicy = task2[symbolTunneledTask] === "client" || tDef[symbolTunneledTask] === "client";
2287
- if (isLocallyTunneledPolicy && globalTags.tunnelPolicy.exists(tDef)) {
2288
- const cfg = globalTags.tunnelPolicy.extract(task2);
2289
- const allowList = cfg?.client || void 0;
2290
- if (Array.isArray(allowList)) {
2291
- const toId = /* @__PURE__ */ __name((x) => typeof x === "string" ? x : x?.id, "toId");
2292
- const allowed = new Set(allowList.map(toId).filter(Boolean));
2293
- createdMiddlewares = createdMiddlewares.filter(
2294
- (m) => allowed.has(m.id)
2295
- );
2296
- }
2297
- }
2298
- if (createdMiddlewares.length === 0) {
2299
- return next;
2300
- }
2301
- for (let i = createdMiddlewares.length - 1; i >= 0; i--) {
2302
- const middleware = createdMiddlewares[i];
2392
+ applyMiddlewares(runner, task2, storeTask) {
2393
+ storeTask.task;
2394
+ let middlewares = this.middlewareResolver.getApplicableTaskMiddlewares(task2);
2395
+ middlewares = this.middlewareResolver.applyTunnelPolicyFilter(task2, middlewares);
2396
+ if (middlewares.length === 0) {
2397
+ return runner;
2398
+ }
2399
+ let next = runner;
2400
+ for (let i = middlewares.length - 1; i >= 0; i--) {
2401
+ const middleware = middlewares[i];
2303
2402
  const storeMiddleware = this.store.taskMiddlewares.get(middleware.id);
2304
2403
  const nextFunction = next;
2305
2404
  const baseMiddlewareRunner = /* @__PURE__ */ __name(async (input) => {
@@ -2315,51 +2414,96 @@ var MiddlewareManager = class {
2315
2414
  middleware.config
2316
2415
  );
2317
2416
  }, "baseMiddlewareRunner");
2318
- const middlewareInterceptors = this.perMiddlewareInterceptors.get(middleware.id) || [];
2319
- const wrappedMiddleware = this.wrapMiddlewareWithInterceptors(
2320
- middleware,
2417
+ const middlewareInterceptors = this.interceptorRegistry.getTaskMiddlewareInterceptors(middleware.id);
2418
+ next = this.wrapWithInterceptors(
2321
2419
  baseMiddlewareRunner,
2322
2420
  middlewareInterceptors
2323
2421
  );
2324
- next = wrappedMiddleware;
2325
2422
  }
2326
2423
  return next;
2327
2424
  }
2328
2425
  /**
2329
- * Run a resource init wrapped with its applicable middlewares.
2426
+ * Wraps a middleware runner with its specific interceptors in onion style
2330
2427
  */
2331
- async runResourceInit(resource2, config, dependencies, context) {
2332
- let next = /* @__PURE__ */ __name(async (cfg) => {
2333
- if (!resource2.init) return void 0;
2334
- const rawValue = await resource2.init.call(
2335
- null,
2336
- cfg,
2337
- dependencies,
2338
- context
2339
- );
2340
- if (resource2.resultSchema) {
2341
- try {
2342
- return resource2.resultSchema.parse(rawValue);
2343
- } catch (error2) {
2344
- validationError.throw({
2345
- subject: "Resource result",
2346
- id: resource2.id,
2347
- originalError: error2
2348
- });
2349
- }
2428
+ wrapWithInterceptors(middlewareRunner, interceptors) {
2429
+ if (interceptors.length === 0) {
2430
+ return middlewareRunner;
2431
+ }
2432
+ const reversedInterceptors = [...interceptors].reverse();
2433
+ let wrapped = middlewareRunner;
2434
+ for (let i = reversedInterceptors.length - 1; i >= 0; i--) {
2435
+ const interceptor = reversedInterceptors[i];
2436
+ const nextFunction = wrapped;
2437
+ wrapped = /* @__PURE__ */ __name(async (input) => {
2438
+ const executionInput = {
2439
+ task: {
2440
+ definition: null,
2441
+ input
2442
+ },
2443
+ next: nextFunction
2444
+ };
2445
+ const wrappedNext = /* @__PURE__ */ __name((i2) => {
2446
+ return nextFunction(i2.task.input);
2447
+ }, "wrappedNext");
2448
+ return interceptor(wrappedNext, executionInput);
2449
+ }, "wrapped");
2450
+ }
2451
+ return wrapped;
2452
+ }
2453
+ };
2454
+
2455
+ // src/models/middleware/ResourceMiddlewareComposer.ts
2456
+ var ResourceMiddlewareComposer = class {
2457
+ constructor(store2, interceptorRegistry, middlewareResolver) {
2458
+ this.store = store2;
2459
+ this.interceptorRegistry = interceptorRegistry;
2460
+ this.middlewareResolver = middlewareResolver;
2461
+ }
2462
+ static {
2463
+ __name(this, "ResourceMiddlewareComposer");
2464
+ }
2465
+ /**
2466
+ * Runs resource initialization with all middleware and interceptors applied
2467
+ */
2468
+ async runInit(resource2, config, dependencies, context) {
2469
+ let runner = this.createBaseInitRunner(resource2, dependencies, context);
2470
+ runner = this.applyMiddlewares(runner, resource2);
2471
+ runner = this.applyGlobalInterceptors(runner, resource2);
2472
+ return runner(config);
2473
+ }
2474
+ /**
2475
+ * Creates the base resource init runner with result validation
2476
+ */
2477
+ createBaseInitRunner(resource2, dependencies, context) {
2478
+ return async (config) => {
2479
+ if (!resource2.init) {
2480
+ return void 0;
2350
2481
  }
2351
- return rawValue;
2352
- }, "next");
2353
- const createdMiddlewares = this.getApplicableResourceMiddlewares(resource2);
2354
- for (let i = createdMiddlewares.length - 1; i >= 0; i--) {
2355
- const middleware = createdMiddlewares[i];
2356
- const storeMiddleware = this.store.resourceMiddlewares.get(
2357
- middleware.id
2482
+ const rawValue = await resource2.init(config, dependencies, context);
2483
+ return ValidationHelper.validateResult(
2484
+ rawValue,
2485
+ resource2.resultSchema,
2486
+ resource2.id,
2487
+ "Resource"
2358
2488
  );
2489
+ };
2490
+ }
2491
+ /**
2492
+ * Applies resource middleware layers
2493
+ */
2494
+ applyMiddlewares(runner, resource2) {
2495
+ const middlewares = this.middlewareResolver.getApplicableResourceMiddlewares(resource2);
2496
+ if (middlewares.length === 0) {
2497
+ return runner;
2498
+ }
2499
+ let next = runner;
2500
+ for (let i = middlewares.length - 1; i >= 0; i--) {
2501
+ const middleware = middlewares[i];
2502
+ const storeMiddleware = this.store.resourceMiddlewares.get(middleware.id);
2359
2503
  const nextFunction = next;
2360
2504
  const baseMiddlewareRunner = /* @__PURE__ */ __name(async (cfg) => {
2361
2505
  try {
2362
- const result = await storeMiddleware.middleware.run(
2506
+ return await storeMiddleware.middleware.run(
2363
2507
  {
2364
2508
  resource: {
2365
2509
  definition: resource2,
@@ -2370,7 +2514,6 @@ var MiddlewareManager = class {
2370
2514
  storeMiddleware.computedDependencies,
2371
2515
  middleware.config
2372
2516
  );
2373
- return result;
2374
2517
  } catch (error2) {
2375
2518
  try {
2376
2519
  await this.store.onUnhandledError({
@@ -2383,79 +2526,192 @@ var MiddlewareManager = class {
2383
2526
  throw error2;
2384
2527
  }
2385
2528
  }, "baseMiddlewareRunner");
2386
- const middlewareInterceptors = this.perResourceMiddlewareInterceptors.get(middleware.id) || [];
2387
- const wrappedMiddleware = this.wrapResourceMiddlewareWithInterceptors(
2388
- middleware,
2529
+ const middlewareInterceptors = this.interceptorRegistry.getResourceMiddlewareInterceptors(middleware.id);
2530
+ next = this.wrapWithInterceptors(
2389
2531
  baseMiddlewareRunner,
2390
2532
  middlewareInterceptors
2391
2533
  );
2392
- next = wrappedMiddleware;
2393
- }
2394
- if (this.resourceMiddlewareInterceptors.length > 0) {
2395
- const reversedInterceptors = [
2396
- ...this.resourceMiddlewareInterceptors
2397
- ].reverse();
2398
- const createExecutionInput = /* @__PURE__ */ __name((config2, nextFunc) => ({
2399
- resource: {
2400
- definition: resource2,
2401
- config: config2
2402
- },
2403
- next: nextFunc
2404
- }), "createExecutionInput");
2405
- let currentNext = next;
2406
- for (let i = reversedInterceptors.length - 1; i >= 0; i--) {
2407
- const interceptor = reversedInterceptors[i];
2408
- const nextFunction = currentNext;
2409
- currentNext = /* @__PURE__ */ __name(async (cfg) => {
2410
- const executionInput = createExecutionInput(cfg, nextFunction);
2411
- const wrappedNext = /* @__PURE__ */ __name((input) => {
2412
- return nextFunction(input.resource.config);
2413
- }, "wrappedNext");
2414
- return interceptor(wrappedNext, executionInput);
2415
- }, "currentNext");
2416
- }
2417
- next = currentNext;
2418
2534
  }
2419
- return next(config);
2535
+ return next;
2420
2536
  }
2421
- getApplicableTaskMiddlewares(task2) {
2422
- const existingMiddlewares = task2.middleware;
2423
- const existingMiddlewareIds = existingMiddlewares.map((x) => x.id);
2424
- const globalMiddlewares2 = this.getEverywhereMiddlewareForTasks(task2).filter(
2425
- (x) => !existingMiddlewareIds.includes(x.id)
2537
+ /**
2538
+ * Applies global resource middleware interceptors
2539
+ */
2540
+ applyGlobalInterceptors(runner, resource2) {
2541
+ const interceptors = this.interceptorRegistry.getGlobalResourceInterceptors();
2542
+ if (interceptors.length === 0) {
2543
+ return runner;
2544
+ }
2545
+ const reversedInterceptors = [...interceptors].reverse();
2546
+ const createExecutionInput = /* @__PURE__ */ __name((config, nextFunc) => ({
2547
+ resource: {
2548
+ definition: resource2,
2549
+ config
2550
+ },
2551
+ next: nextFunc
2552
+ }), "createExecutionInput");
2553
+ let currentNext = runner;
2554
+ for (let i = reversedInterceptors.length - 1; i >= 0; i--) {
2555
+ const interceptor = reversedInterceptors[i];
2556
+ const nextFunction = currentNext;
2557
+ currentNext = /* @__PURE__ */ __name(async (cfg) => {
2558
+ const executionInput = createExecutionInput(cfg, nextFunction);
2559
+ const wrappedNext = /* @__PURE__ */ __name((input) => {
2560
+ return nextFunction(input.resource.config);
2561
+ }, "wrappedNext");
2562
+ return interceptor(wrappedNext, executionInput);
2563
+ }, "currentNext");
2564
+ }
2565
+ return currentNext;
2566
+ }
2567
+ /**
2568
+ * Wraps a middleware runner with its specific interceptors in onion style
2569
+ */
2570
+ wrapWithInterceptors(middlewareRunner, interceptors) {
2571
+ if (interceptors.length === 0) {
2572
+ return middlewareRunner;
2573
+ }
2574
+ const reversedInterceptors = [...interceptors].reverse();
2575
+ let wrapped = middlewareRunner;
2576
+ for (let i = reversedInterceptors.length - 1; i >= 0; i--) {
2577
+ const interceptor = reversedInterceptors[i];
2578
+ const nextFunction = wrapped;
2579
+ wrapped = /* @__PURE__ */ __name(async (config) => {
2580
+ const executionInput = {
2581
+ resource: {
2582
+ definition: null,
2583
+ config
2584
+ },
2585
+ next: nextFunction
2586
+ };
2587
+ const wrappedNext = /* @__PURE__ */ __name((input) => {
2588
+ return nextFunction(input.resource.config);
2589
+ }, "wrappedNext");
2590
+ return interceptor(wrappedNext, executionInput);
2591
+ }, "wrapped");
2592
+ }
2593
+ return wrapped;
2594
+ }
2595
+ };
2596
+
2597
+ // src/models/MiddlewareManager.ts
2598
+ var MiddlewareManager = class {
2599
+ constructor(store2, eventManager, logger) {
2600
+ this.store = store2;
2601
+ this.eventManager = eventManager;
2602
+ this.logger = logger;
2603
+ this.interceptorRegistry = new InterceptorRegistry();
2604
+ this.middlewareResolver = new MiddlewareResolver(store2);
2605
+ this.taskComposer = new TaskMiddlewareComposer(
2606
+ store2,
2607
+ this.interceptorRegistry,
2608
+ this.middlewareResolver
2609
+ );
2610
+ this.resourceComposer = new ResourceMiddlewareComposer(
2611
+ store2,
2612
+ this.interceptorRegistry,
2613
+ this.middlewareResolver
2426
2614
  );
2427
- return [...globalMiddlewares2, ...existingMiddlewares];
2428
2615
  }
2429
- getApplicableResourceMiddlewares(resource2) {
2430
- const existingMiddlewares = resource2.middleware;
2431
- const existingMiddlewareIds = existingMiddlewares.map((x) => x.id);
2432
- const globalMiddlewares2 = this.getEverywhereMiddlewareForResources(
2433
- resource2
2434
- ).filter((x) => !existingMiddlewareIds.includes(x.id));
2435
- return [...globalMiddlewares2, ...existingMiddlewares];
2616
+ static {
2617
+ __name(this, "MiddlewareManager");
2436
2618
  }
2437
2619
  /**
2438
- * @param task
2439
- * @returns
2620
+ * @internal
2621
+ */
2622
+ get taskMiddlewareInterceptors() {
2623
+ return this.interceptorRegistry.getGlobalTaskInterceptors();
2624
+ }
2625
+ /**
2626
+ * @internal
2627
+ */
2628
+ get resourceMiddlewareInterceptors() {
2629
+ return this.interceptorRegistry.getGlobalResourceInterceptors();
2630
+ }
2631
+ /**
2632
+ * Gets the current lock status of the MiddlewareManager
2633
+ */
2634
+ get isLocked() {
2635
+ return this.interceptorRegistry.isLocked;
2636
+ }
2637
+ /**
2638
+ * Locks the MiddlewareManager, preventing any further modifications to interceptors
2639
+ */
2640
+ lock() {
2641
+ this.interceptorRegistry.lock();
2642
+ }
2643
+ /**
2644
+ * Adds an interceptor for task or resource middleware execution
2645
+ * Interceptors are executed in the order they are added, with the ability to
2646
+ * modify, log, or prevent middleware execution
2647
+ *
2648
+ * @param kind - The type of middleware to intercept ("task" or "resource")
2649
+ * @param interceptor - The interceptor function to add
2650
+ */
2651
+ intercept(kind, interceptor) {
2652
+ if (kind === "task") {
2653
+ this.interceptorRegistry.addGlobalTaskInterceptor(
2654
+ interceptor
2655
+ );
2656
+ } else {
2657
+ this.interceptorRegistry.addGlobalResourceInterceptor(
2658
+ interceptor
2659
+ );
2660
+ }
2661
+ }
2662
+ /**
2663
+ * Adds an interceptor for a specific middleware instance with better type safety
2664
+ * This method automatically determines the type and provides type-safe access
2665
+ *
2666
+ * @param middleware - The middleware instance to intercept
2667
+ * @param interceptor - The interceptor function with proper typing
2668
+ */
2669
+ interceptMiddleware(middleware, interceptor) {
2670
+ if (isTaskMiddleware(middleware)) {
2671
+ this.interceptorRegistry.addTaskMiddlewareInterceptor(
2672
+ middleware.id,
2673
+ interceptor
2674
+ );
2675
+ } else if (isResourceMiddleware(middleware)) {
2676
+ this.interceptorRegistry.addResourceMiddlewareInterceptor(
2677
+ middleware.id,
2678
+ interceptor
2679
+ );
2680
+ } else {
2681
+ throw new Error("Unknown middleware type");
2682
+ }
2683
+ }
2684
+ /**
2685
+ * Compose a runner for a task with its local interceptors and applicable middlewares.
2686
+ * Returns a function that accepts the task input and resolves to the task output.
2687
+ */
2688
+ composeTaskRunner(task2) {
2689
+ return this.taskComposer.compose(task2);
2690
+ }
2691
+ /**
2692
+ * Run a resource init wrapped with its applicable middlewares.
2693
+ */
2694
+ async runResourceInit(resource2, config, dependencies, context) {
2695
+ return this.resourceComposer.runInit(
2696
+ resource2,
2697
+ config,
2698
+ dependencies,
2699
+ context
2700
+ );
2701
+ }
2702
+ /**
2703
+ * Gets all "everywhere" middlewares that apply to the given task
2704
+ * @deprecated Internal method exposed for testing - may be removed in future versions
2440
2705
  */
2441
2706
  getEverywhereMiddlewareForTasks(task2) {
2442
- return Array.from(this.store.taskMiddlewares.values()).filter((x) => Boolean(x.middleware.everywhere)).filter((x) => {
2443
- if (typeof x.middleware.everywhere === "function") {
2444
- return x.middleware.everywhere(task2);
2445
- }
2446
- return true;
2447
- }).map((x) => x.middleware);
2707
+ return this.middlewareResolver.getEverywhereTaskMiddlewares(task2);
2448
2708
  }
2449
2709
  /**
2450
- * Returns all global middleware for resource, which do not depend on the target resource.
2710
+ * Gets all "everywhere" middlewares that apply to the given resource
2711
+ * @deprecated Internal method exposed for testing - may be removed in future versions
2451
2712
  */
2452
- getEverywhereMiddlewareForResources(target) {
2453
- return Array.from(this.store.resourceMiddlewares.values()).filter((x) => Boolean(x.middleware.everywhere)).filter((x) => {
2454
- if (typeof x.middleware.everywhere === "function") {
2455
- return x.middleware.everywhere(target);
2456
- }
2457
- return true;
2458
- }).map((x) => x.middleware);
2713
+ getEverywhereMiddlewareForResources(resource2) {
2714
+ return this.middlewareResolver.getEverywhereResourceMiddlewares(resource2);
2459
2715
  }
2460
2716
  };
2461
2717
 
@@ -4204,7 +4460,7 @@ var tunnelResourceMiddleware = defineResourceMiddleware({
4204
4460
  t.run = (async (input) => {
4205
4461
  return value.run(t, input);
4206
4462
  });
4207
- t[symbolTunneledTask] = "client";
4463
+ t.isTunneled = true;
4208
4464
  t[symbolTunneledBy] = resourceId;
4209
4465
  }
4210
4466
  if (events.length > 0) {
@@ -6100,6 +6356,8 @@ exports.asyncContext = defineAsyncContext;
6100
6356
  exports.bindProcessErrorHandler = bindProcessErrorHandler;
6101
6357
  exports.createContext = createContext2;
6102
6358
  exports.createDefaultUnhandledError = createDefaultUnhandledError;
6359
+ exports.createExposureFetch = createExposureFetch;
6360
+ exports.createHttpClient = createHttpClient;
6103
6361
  exports.createTestResource = createTestResource;
6104
6362
  exports.debug = debug;
6105
6363
  exports.debugLevels = debugLevels;
@@ -6110,6 +6368,7 @@ exports.globals = globals;
6110
6368
  exports.hook = defineHook;
6111
6369
  exports.levelNormal = levelNormal;
6112
6370
  exports.levelVerbose = levelVerbose;
6371
+ exports.normalizeError = normalizeError;
6113
6372
  exports.override = defineOverride;
6114
6373
  exports.r = r;
6115
6374
  exports.resource = defineResource;