@zuplo/cli 6.72.9 → 6.72.11

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 (61) hide show
  1. package/node_modules/@posthog/core/dist/index.d.ts +2 -2
  2. package/node_modules/@posthog/core/dist/index.d.ts.map +1 -1
  3. package/node_modules/@posthog/core/dist/index.js +9 -0
  4. package/node_modules/@posthog/core/dist/index.mjs +2 -2
  5. package/node_modules/@posthog/core/dist/metrics/config.d.ts +9 -0
  6. package/node_modules/@posthog/core/dist/metrics/config.d.ts.map +1 -0
  7. package/node_modules/@posthog/core/dist/metrics/config.js +49 -0
  8. package/node_modules/@posthog/core/dist/metrics/config.mjs +15 -0
  9. package/node_modules/@posthog/core/dist/metrics/index.d.ts +8 -1
  10. package/node_modules/@posthog/core/dist/metrics/index.d.ts.map +1 -1
  11. package/node_modules/@posthog/core/dist/metrics/index.js +39 -19
  12. package/node_modules/@posthog/core/dist/metrics/index.mjs +36 -19
  13. package/node_modules/@posthog/core/dist/metrics/types.d.ts +1 -1
  14. package/node_modules/@posthog/core/dist/metrics/types.d.ts.map +1 -1
  15. package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts +9 -1
  16. package/node_modules/@posthog/core/dist/posthog-core-stateless.d.ts.map +1 -1
  17. package/node_modules/@posthog/core/dist/posthog-core-stateless.js +44 -1
  18. package/node_modules/@posthog/core/dist/posthog-core-stateless.mjs +44 -1
  19. package/node_modules/@posthog/core/package.json +2 -2
  20. package/node_modules/@posthog/core/src/index.ts +3 -0
  21. package/node_modules/@posthog/core/src/metrics/config.ts +23 -0
  22. package/node_modules/@posthog/core/src/metrics/index.spec.ts +49 -0
  23. package/node_modules/@posthog/core/src/metrics/index.ts +66 -24
  24. package/node_modules/@posthog/core/src/metrics/types.ts +1 -0
  25. package/node_modules/@posthog/core/src/posthog-core-stateless.ts +52 -2
  26. package/node_modules/@posthog/types/dist/posthog-config.d.ts +14 -0
  27. package/node_modules/@posthog/types/dist/posthog-config.d.ts.map +1 -1
  28. package/node_modules/@posthog/types/package.json +1 -1
  29. package/node_modules/@posthog/types/src/posthog-config.ts +15 -0
  30. package/node_modules/@zuplo/core/customer.cli.minified.js +1 -1
  31. package/node_modules/@zuplo/core/index.minified.js +1 -1
  32. package/node_modules/@zuplo/core/package.json +1 -1
  33. package/node_modules/@zuplo/graphql/package.json +1 -1
  34. package/node_modules/@zuplo/openapi-tools/package.json +1 -1
  35. package/node_modules/@zuplo/otel/package.json +1 -1
  36. package/node_modules/@zuplo/runtime/out/esm/chunk-K77Z5PRN.js +30 -0
  37. package/node_modules/@zuplo/runtime/out/esm/chunk-K77Z5PRN.js.map +1 -0
  38. package/node_modules/@zuplo/runtime/out/esm/{chunk-HKSZ4V6H.js → chunk-NIKKAYJU.js} +86 -86
  39. package/node_modules/@zuplo/runtime/out/esm/chunk-NIKKAYJU.js.map +1 -0
  40. package/node_modules/@zuplo/runtime/out/esm/index.js +1 -1
  41. package/node_modules/@zuplo/runtime/out/esm/mcp-gateway/index.js +1 -1
  42. package/node_modules/@zuplo/runtime/out/esm/sdks/aws/index.js +1 -1
  43. package/node_modules/@zuplo/runtime/out/types/index.d.ts +124 -55
  44. package/node_modules/@zuplo/runtime/package.json +1 -1
  45. package/node_modules/avvio/.github/dependabot.yml +42 -2
  46. package/node_modules/avvio/.github/workflows/ci.yml +1 -1
  47. package/node_modules/avvio/.github/workflows/lock-threads.yml +19 -0
  48. package/node_modules/avvio/LICENSE +1 -3
  49. package/node_modules/avvio/README.md +4 -4
  50. package/node_modules/avvio/{boot.js → index.js} +8 -2
  51. package/node_modules/avvio/package.json +8 -8
  52. package/node_modules/avvio/test/esm.mjs +1 -1
  53. package/node_modules/avvio/test/gh-issues/fastify-6843.test.js +48 -0
  54. package/node_modules/avvio/test/on-ready-timeout-await.test.js +1 -1
  55. package/node_modules/avvio/test/types/index.ts +1 -1
  56. package/node_modules/avvio/test/types/tsconfig.json +5 -2
  57. package/package.json +6 -6
  58. package/node_modules/@zuplo/runtime/out/esm/chunk-GBIUQ4JJ.js +0 -30
  59. package/node_modules/@zuplo/runtime/out/esm/chunk-GBIUQ4JJ.js.map +0 -1
  60. package/node_modules/@zuplo/runtime/out/esm/chunk-HKSZ4V6H.js.map +0 -1
  61. /package/node_modules/@zuplo/runtime/out/esm/{chunk-HKSZ4V6H.js.LEGAL.txt → chunk-NIKKAYJU.js.LEGAL.txt} +0 -0
@@ -139,6 +139,11 @@ export declare interface AIGatewayAuthInboundPolicyOptions {
139
139
  authScheme?: string;
140
140
  }
141
141
 
142
+ /**
143
+ * An AI Gateway capability that can have a resolved model selection.
144
+ *
145
+ * @public
146
+ */
142
147
  export declare type AIGatewayCapability =
143
148
  | "completions"
144
149
  | "embeddings"
@@ -148,9 +153,17 @@ export declare type AIGatewayCapability =
148
153
  | "audio_speech"
149
154
  | "audio_transcriptions";
150
155
 
156
+ /**
157
+ * Primary and optional fallback routing for one AI Gateway capability.
158
+ *
159
+ * @public
160
+ */
151
161
  export declare interface AIGatewayCapabilityRouting {
162
+ /** The primary provider and model. */
152
163
  model: AIGatewayModelRef;
164
+ /** The provider and model used after a retryable error or timeout. */
153
165
  fallback?: AIGatewayFallbackRef;
166
+ /** The provider and model used after a usage-limit-exceeded signal. */
154
167
  quotaFallback?: AIGatewayModelRef;
155
168
  }
156
169
 
@@ -160,6 +173,11 @@ export declare interface AIGatewayCapabilitySelection {
160
173
  quotaFallback?: AIGatewayModelCandidate;
161
174
  }
162
175
 
176
+ /**
177
+ * A model used after a retryable primary-provider failure or timeout.
178
+ *
179
+ * @public
180
+ */
163
181
  export declare interface AIGatewayFallbackRef extends AIGatewayModelRef {
164
182
  /**
165
183
  * Bounds the primary call before failing over. Defaults to 60 seconds and is
@@ -196,7 +214,7 @@ export declare function aiGatewayHandler(
196
214
 
197
215
  /**
198
216
  * Routes AI requests using the model selection stored in the request context.
199
- * Attach the `ai-gateway-models-inbound` policy before this handler runs. To
217
+ * Attach the `ai-gateway-model-routing-v2-inbound` policy before this handler runs. To
200
218
  * compute routing per request, set that policy's `routingFunction` option to
201
219
  * a module export.
202
220
  *
@@ -214,7 +232,7 @@ export declare function aiGatewayHandler(
214
232
  * "module": "$import(@zuplo/runtime)"
215
233
  * },
216
234
  * "policies": {
217
- * "inbound": ["ai-gateway-models"]
235
+ * "inbound": ["ai-gateway-model-routing-v2-inbound"]
218
236
  * }
219
237
  * }
220
238
  * ```
@@ -328,27 +346,60 @@ export declare interface AIGatewayModelCandidate {
328
346
  apiKey?: string;
329
347
  }
330
348
 
349
+ /**
350
+ * Catalog information about a model that a routing function can inspect.
351
+ *
352
+ * Model catalog membership does not indicate that the project has credentials
353
+ * for the model's provider. The policy resolves credentials only after the
354
+ * routing function returns a provider and model.
355
+ *
356
+ * @public
357
+ */
358
+ export declare interface AIGatewayModelInfo {
359
+ /** The provider-specific model identifier to return in model routing. */
360
+ model: string;
361
+ /** The AI Gateway capability supported by the model. */
362
+ capability: "completions" | "embeddings";
363
+ /** Whether the model is available for new routing or has been deprecated. */
364
+ status: "active" | "deprecated";
365
+ /** The catalog's normalized price in USD for one input token. */
366
+ inputCostPerToken: number;
367
+ /** The catalog's normalized price in USD for one output token. */
368
+ outputCostPerToken: number;
369
+ }
370
+
371
+ /**
372
+ * Identifies a provider and model in routing configuration.
373
+ *
374
+ * @public
375
+ */
331
376
  export declare interface AIGatewayModelRef {
377
+ /** The case-insensitive provider identifier, such as `openai`. */
332
378
  provider: string;
379
+ /** The provider-specific model identifier, such as `gpt-5`. */
333
380
  model: string;
334
381
  }
335
382
 
383
+ /**
384
+ * Routing returned by an {@link AIGatewayRoutingFunction}.
385
+ *
386
+ * Omitted capabilities keep no implicit value. Return `undefined` from the
387
+ * function, rather than an empty object, to preserve the policy's static
388
+ * routing unchanged.
389
+ *
390
+ * @public
391
+ */
336
392
  export declare interface AIGatewayModelRouting {
337
- providers: AIGatewayProviderCredential[];
393
+ /** Routing for chat completions, Responses, and Anthropic Messages. */
338
394
  completions?: AIGatewayCapabilityRouting;
395
+ /** Routing for embedding requests. */
339
396
  embeddings?: AIGatewayCapabilityRouting;
340
397
  }
341
398
 
342
- export declare interface AIGatewayModelSelection {
343
- byCapability: Partial<
344
- Record<AIGatewayCapability, AIGatewayCapabilitySelection>
345
- >;
346
- }
347
-
348
399
  /**
349
- * Selects AI Gateway models and fallbacks for each configured capability.
400
+ * Selects AI Gateway models and fallbacks for the current request's capability.
350
401
  *
351
- * @title AI Gateway Models
402
+ * @title AI Gateway Model Routing (v2)
352
403
  * @beta
353
404
  * @product ai-gateway
354
405
  * @hidden
@@ -359,15 +410,22 @@ export declare interface AIGatewayModelSelection {
359
410
  * @param policyName - The name of the policy as set in policies.json
360
411
  * @returns The request with the model selection stored in context
361
412
  */
362
- export declare class AIGatewayModelsInboundPolicy extends InboundPolicy<AIGatewayModelsInboundPolicyOptions> {
413
+ export declare class AIGatewayModelRoutingV2InboundPolicy extends InboundPolicy<AIGatewayModelRoutingV2InboundPolicyOptions> {
363
414
  #private;
364
- static readonly policyType = "ai-gateway-models";
415
+ static readonly policyType = "ai-gateway-model-routing-v2";
365
416
  /* Excluded from this release type: setModelSelection */
366
417
  /** Get the model selection for the current request. */
367
418
  static getModelSelection(
368
419
  context: ZuploContext
369
420
  ): AIGatewayModelSelection | undefined;
370
- constructor(options: AIGatewayModelsInboundPolicyOptions, policyName: string);
421
+ /** Get the provider catalog loaded for the current request. */
422
+ static getProviders(
423
+ context: ZuploContext
424
+ ): AIGatewayProviderInfo[] | undefined;
425
+ constructor(
426
+ options: AIGatewayModelRoutingV2InboundPolicyOptions,
427
+ policyName: string
428
+ );
371
429
  handler(
372
430
  request: ZuploRequest,
373
431
  context: ZuploContext
@@ -375,14 +433,21 @@ export declare class AIGatewayModelsInboundPolicy extends InboundPolicy<AIGatewa
375
433
  }
376
434
 
377
435
  /**
378
- * Options for provider credentials and per-capability AI model routing.
436
+ * Options for per-capability AI model routing. Provider credentials are resolved from the project's AI provider configuration or environment-variable conventions.
379
437
  * @public
380
438
  */
381
- export declare interface AIGatewayModelsInboundPolicyOptions {
382
- providers?: Providers;
439
+ export declare type AIGatewayModelRoutingV2InboundPolicyOptions = {
440
+ [k: string]: unknown;
441
+ } & {
383
442
  completions?: CompletionsRouting;
384
443
  routingFunction?: RoutingFunction;
385
444
  embeddings?: EmbeddingsRouting;
445
+ };
446
+
447
+ export declare interface AIGatewayModelSelection {
448
+ byCapability: Partial<
449
+ Record<AIGatewayCapability, AIGatewayCapabilitySelection>
450
+ >;
386
451
  }
387
452
 
388
453
  /**
@@ -407,19 +472,43 @@ export declare const AIGatewayOpenAIToAnthropicOutboundPolicy: OutboundPolicyHan
407
472
  */
408
473
  export declare interface AIGatewayOpenAIToAnthropicOutboundPolicyOptions {}
409
474
 
410
- export declare interface AIGatewayProviderCredential {
411
- provider: string;
412
- apiKey: string;
475
+ /**
476
+ * Provider metadata and models supplied to a routing function.
477
+ *
478
+ * Credentials and environment-variable names are never exposed to customer
479
+ * code. A provider can appear in this catalog without a key configured for the
480
+ * project, so routing functions should restrict candidates to providers that
481
+ * the project is configured to use.
482
+ *
483
+ * @public
484
+ */
485
+ export declare interface AIGatewayProviderInfo {
486
+ /** The case-insensitive provider identifier used in model routing. */
487
+ name: string;
488
+ /** The provider's human-readable display name, when available. */
489
+ label?: string;
490
+ /** The provider's request base URL, when supplied by the catalog. */
491
+ baseUrl?: string;
492
+ /** Whether this provider was defined by the customer. */
493
+ isCustom?: boolean;
494
+ /** Models currently listed for this provider in the live catalog. */
495
+ models: AIGatewayModelInfo[];
413
496
  }
414
497
 
415
498
  /**
416
- * Computes model routing for a request. Set as the models policy's
499
+ * Computes model routing for a request. Set as the model-routing policy's
417
500
  * `routingFunction` option. The returned routing is validated exactly like the
418
501
  * static policy options and replaces them for the request. Return undefined to
419
502
  * use `options.defaultRouting` unchanged. The function owns merge semantics:
420
503
  * return the defaults as-is, a modified copy, or entirely new routing. The
421
504
  * request is an isolated clone, so reading its body does not consume the request
422
505
  * used by later policies or the route handler.
506
+ *
507
+ * @param request - An isolated clone of the incoming gateway request.
508
+ * @param context - The current Zuplo request context.
509
+ * @param options - Static defaults, the live provider catalog, and policy name.
510
+ * @returns Per-request model routing, or undefined to keep the static defaults.
511
+ * @public
423
512
  */
424
513
  export declare type AIGatewayRoutingFunction = (
425
514
  request: ZuploRequest,
@@ -432,6 +521,8 @@ export declare type AIGatewayRoutingFunction = (
432
521
 
433
522
  /**
434
523
  * Options passed to an {@link AIGatewayRoutingFunction}.
524
+ *
525
+ * @public
435
526
  */
436
527
  export declare interface AIGatewayRoutingFunctionOptions {
437
528
  /**
@@ -440,7 +531,14 @@ export declare interface AIGatewayRoutingFunctionOptions {
440
531
  */
441
532
  defaultRouting: AIGatewayModelRouting | undefined;
442
533
  /**
443
- * The name of the models policy as set in policies.json.
534
+ * The live provider catalog, including model pricing and lifecycle status.
535
+ * Catalog membership does not guarantee that the project has credentials for
536
+ * a provider. Credentials and their environment-variable names are not
537
+ * exposed to the routing function.
538
+ */
539
+ providers: AIGatewayProviderInfo[];
540
+ /**
541
+ * The name of the model-routing policy as set in policies.json.
444
542
  */
445
543
  policyName: string;
446
544
  }
@@ -719,7 +817,7 @@ export declare function AkamaiAIFirewallInboundPolicy(
719
817
  */
720
818
  export declare interface AkamaiAIFirewallPolicyOptions {
721
819
  configurationId: ConfigurationID;
722
- "api-key": APIKey_2;
820
+ "api-key": APIKey;
723
821
  applicationId?: ApplicationID;
724
822
  streamingAccumulation?: StreamingAccumulationSettings;
725
823
  }
@@ -759,7 +857,7 @@ export declare function AkamaiAIFirewallV2InboundPolicy(
759
857
  */
760
858
  export declare interface AkamaiAIFirewallV2PolicyOptions {
761
859
  configurationId: ConfigurationID_2;
762
- "api-key": APIKey_3;
860
+ "api-key": APIKey_2;
763
861
  applicationId?: ApplicationID_2;
764
862
  streamingAccumulation?: StreamingAccumulationSettings_2;
765
863
  endpoints?: ApplicableEndpoints_2;
@@ -1118,7 +1216,7 @@ export declare interface ApiAuthKeyInboundPolicyOptions {
1118
1216
  }
1119
1217
 
1120
1218
  /**
1121
- * The API key itself. Use $env(MY_KEY) to substitute an environment variable at build time.
1219
+ * The API key for the AI Firewall.
1122
1220
  * @public
1123
1221
  */
1124
1222
  declare type APIKey = string;
@@ -1129,12 +1227,6 @@ declare type APIKey = string;
1129
1227
  */
1130
1228
  declare type APIKey_2 = string;
1131
1229
 
1132
- /**
1133
- * The API key for the AI Firewall.
1134
- * @public
1135
- */
1136
- declare type APIKey_3 = string;
1137
-
1138
1230
  /**
1139
1231
  * Represents a consumer in the API Key service.
1140
1232
  * @public
@@ -11696,29 +11788,6 @@ export declare interface PropelAuthJwtInboundPolicyOptions {
11696
11788
  oAuthResourceMetadataEnabled?: boolean;
11697
11789
  }
11698
11790
 
11699
- /**
11700
- * The provider registry key, such as openai, anthropic, or a custom provider name.
11701
- * @public
11702
- */
11703
- declare type Provider = string;
11704
-
11705
- /**
11706
- * Provider credentials used by model routing. Each entry must define apiKey.
11707
- *
11708
- * @minItems 1
11709
- * @public
11710
- */
11711
- declare type Providers = [
11712
- {
11713
- provider: Provider;
11714
- apiKey: APIKey;
11715
- },
11716
- ...{
11717
- provider: Provider;
11718
- apiKey: APIKey;
11719
- }[],
11720
- ];
11721
-
11722
11791
  /**
11723
11792
  * Extracts a query parameter and sets it as a header in the request.
11724
11793
  *
@@ -13537,7 +13606,7 @@ export declare interface RouteHandler<T = unknown> {
13537
13606
  /* Excluded from this release type: Router */
13538
13607
 
13539
13608
  /**
13540
- * Custom function that computes model routing for each request. The export must be an AIGatewayRoutingFunction. It receives the policy's parsed static routing (if any) as defaultRouting; its return value is validated like the static options and replaces the routing for the request. Returning undefined keeps the defaults unchanged.
13609
+ * Custom function that computes model routing for each request. It receives defaultRouting and the project's provider catalog, including pricing. Returning undefined keeps the defaults unchanged.
13541
13610
  * @public
13542
13611
  */
13543
13612
  declare interface RoutingFunction {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@zuplo/runtime",
3
3
  "type": "module",
4
- "version": "6.72.9",
4
+ "version": "6.72.11",
5
5
  "repository": "https://github.com/zuplo/zuplo",
6
6
  "author": "Zuplo, Inc.",
7
7
  "exports": {
@@ -2,12 +2,52 @@ version: 2
2
2
  updates:
3
3
  - package-ecosystem: "github-actions"
4
4
  directory: "/"
5
+ commit-message:
6
+ # Prefix all commit messages with "chore: "
7
+ prefix: "chore"
5
8
  schedule:
6
- interval: "monthly"
9
+ interval: "weekly"
10
+ cooldown:
11
+ default-days: 7
12
+ allow:
13
+ - dependency-name: "*"
14
+ update-types:
15
+ - "version-update:semver-major"
7
16
  open-pull-requests-limit: 10
8
17
 
9
18
  - package-ecosystem: "npm"
10
19
  directory: "/"
20
+ commit-message:
21
+ # Prefix all commit messages with "chore: "
22
+ prefix: "chore"
11
23
  schedule:
12
- interval: "monthly"
24
+ interval: "weekly"
25
+ cooldown:
26
+ default-days: 7
27
+ versioning-strategy: "increase-if-necessary"
28
+ allow:
29
+ - dependency-name: "*"
30
+ update-types:
31
+ - "version-update:semver-major"
32
+ ignore:
33
+ # TODO: remove ignore until neostandard support ESLint 10
34
+ - dependency-name: "eslint"
35
+ - dependency-name: "neostandard"
36
+ - dependency-name: "@stylistic/*"
13
37
  open-pull-requests-limit: 10
38
+ groups:
39
+ # Production dependencies with breaking changes
40
+ dependencies:
41
+ dependency-type: "production"
42
+ # ESLint related dependencies
43
+ dev-dependencies-eslint:
44
+ patterns:
45
+ - "eslint"
46
+ - "neostandard"
47
+ - "@stylistic/*"
48
+ # TypeScript related dependencies
49
+ dev-dependencies-typescript:
50
+ patterns:
51
+ - "@types/*"
52
+ - "tstyche"
53
+ - "typescript"
@@ -27,7 +27,7 @@ jobs:
27
27
  permissions:
28
28
  contents: write
29
29
  pull-requests: write
30
- uses: fastify/workflows/.github/workflows/plugins-ci.yml@v5
30
+ uses: fastify/workflows/.github/workflows/plugins-ci.yml@v6
31
31
  with:
32
32
  license-check: true
33
33
  lint: true
@@ -0,0 +1,19 @@
1
+ name: Lock Threads
2
+
3
+ on:
4
+ schedule:
5
+ - cron: '0 0 1 * *'
6
+ workflow_dispatch:
7
+
8
+ concurrency:
9
+ group: lock
10
+
11
+ permissions:
12
+ contents: read
13
+
14
+ jobs:
15
+ lock-threads:
16
+ permissions:
17
+ issues: write
18
+ pull-requests: write
19
+ uses: fastify/workflows/.github/workflows/lock-threads.yml@v6
@@ -1,9 +1,7 @@
1
1
  MIT License
2
2
 
3
3
  Copyright (c) 2016-2020 Matteo Collina
4
- Copyright (c) 2020-present The Fastify team
5
-
6
- The Fastify team members are listed at https://github.com/fastify/fastify#team.
4
+ Copyright (c) 2020-present The Fastify team <https://github.com/fastify/fastify#team>
7
5
 
8
6
  Permission is hereby granted, free of charge, to any person obtaining a copy
9
7
  of this software and associated documentation files (the "Software"), to deal
@@ -584,7 +584,7 @@ app.close()
584
584
 
585
585
  <a name="symbol-asyncdispose"></a>
586
586
 
587
- ### app[Symbol.asyncDispose]()
587
+ ### app\[Symbol.asyncDispose\]()
588
588
 
589
589
  This method is an alias for [`app.close()`](#close) and is used to support the [ECMAScript Explicit Resource Management](https://tc39.es/proposal-explicit-resource-management/) proposal. It allows you to use the `await using` syntax to automatically close the avvio instance when it goes out of scope.
590
590
 
@@ -595,14 +595,14 @@ Example:
595
595
  ```js
596
596
  test('my test', async () => {
597
597
  await using app = avvio()
598
-
598
+
599
599
  app.use(function (server, opts, done) {
600
600
  // Your plugin code
601
601
  done()
602
602
  })
603
-
603
+
604
604
  await app.ready()
605
-
605
+
606
606
  // app.close() will be called automatically when exiting this scope
607
607
  })
608
608
  ```
@@ -476,9 +476,14 @@ function callWithCbOrNextTick (func, cb) {
476
476
  executeWithThenable(func, [err], cb)
477
477
  } else {
478
478
  if (this._opts.timeout === 0) {
479
+ let completed = false
479
480
  const wrapCb = (err) => {
481
+ if (completed) {
482
+ return
483
+ }
484
+ completed = true
480
485
  this._error = err
481
- cb(this._error)
486
+ process.nextTick(cb, this._error)
482
487
  }
483
488
 
484
489
  if (func.length === 2) {
@@ -513,8 +518,9 @@ function timeoutCall (func, rootErr, context, cb) {
513
518
  function timeoutCb (err) {
514
519
  if (timer) {
515
520
  clearTimeout(timer)
521
+ timer = null
516
522
  this._error = err
517
- cb(this._error)
523
+ process.nextTick(cb, this._error)
518
524
  } else {
519
525
  // timeout has been triggered
520
526
  // can not call cb twice
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "avvio",
3
- "version": "9.2.0",
3
+ "version": "9.3.0",
4
4
  "description": "Asynchronous bootstrapping of Node applications",
5
- "main": "boot.js",
5
+ "main": "index.js",
6
6
  "type": "commonjs",
7
7
  "types": "index.d.ts",
8
8
  "scripts": {
@@ -27,7 +27,7 @@
27
27
  "contributors": [
28
28
  {
29
29
  "name": "Tomas Della Vedova",
30
- "url": "http://delved.org"
30
+ "url": "https://delvedor.dev"
31
31
  },
32
32
  {
33
33
  "name": "Manuel Spigolon",
@@ -60,12 +60,12 @@
60
60
  ],
61
61
  "devDependencies": {
62
62
  "@jsumners/line-reporter": "^1.0.1",
63
- "@types/node": "^25.0.3",
64
- "borp": "^0.21.0",
65
- "c8": "^10.1.3",
63
+ "@types/node": "^26.0.0",
64
+ "borp": "^1.0.0",
65
+ "c8": "^11.0.0",
66
66
  "eslint": "^9.17.0",
67
- "neostandard": "^0.12.0",
68
- "typescript": "~5.9.2"
67
+ "neostandard": "^0.13.0",
68
+ "typescript": "~6.0.2"
69
69
  },
70
70
  "dependencies": {
71
71
  "@fastify/error": "^4.0.0",
@@ -1,5 +1,5 @@
1
1
  import { test } from 'node:test'
2
- import boot from '../boot.js'
2
+ import boot from '../index.js'
3
3
 
4
4
  await test('support import', async (t) => {
5
5
  const app = boot()
@@ -0,0 +1,48 @@
1
+ 'use strict'
2
+
3
+ const { test } = require('node:test')
4
+ const boot = require('../..')
5
+
6
+ for (const timeout of [0, 10000]) {
7
+ test(`synchronous ready callbacks do not overflow the stack with a ${timeout} ms timeout`, async (t) => {
8
+ const app = boot({}, { timeout })
9
+ const total = 10000
10
+ let completed = 0
11
+
12
+ app.use((server, options, done) => done())
13
+
14
+ for (let i = 0; i < total; i++) {
15
+ app.ready((err, context, done) => {
16
+ if (err) {
17
+ done(err)
18
+ return
19
+ }
20
+
21
+ completed++
22
+
23
+ // Fastify wraps callback-style hooks this way so that thrown hook
24
+ // errors are forwarded to Avvio.
25
+ try {
26
+ done()
27
+ } catch (error) {
28
+ done(error)
29
+ }
30
+ })
31
+ }
32
+
33
+ await app.ready()
34
+
35
+ t.assert.strictEqual(completed, total)
36
+ })
37
+
38
+ test(`ready callbacks complete only once with a ${timeout} ms timeout`, async () => {
39
+ const app = boot({}, { timeout })
40
+
41
+ app.ready((err, context, done) => {
42
+ done(err)
43
+ done(new Error('should be ignored'))
44
+ })
45
+
46
+ await app.ready()
47
+ })
48
+ }
@@ -3,7 +3,7 @@
3
3
  /* eslint no-prototype-builtins: off */
4
4
 
5
5
  const { test } = require('node:test')
6
- const boot = require('../boot')
6
+ const boot = require('..')
7
7
 
8
8
  test('onReadyTimeout', async (t) => {
9
9
  const app = boot({}, {
@@ -1,5 +1,5 @@
1
1
  /* eslint-disable @typescript-eslint/no-unused-expressions */
2
- import * as avvio from '../../'
2
+ import avvio from '../../'
3
3
 
4
4
  {
5
5
  // avvio with no argument
@@ -1,7 +1,10 @@
1
1
  {
2
2
  "compilerOptions": {
3
- "target": "es6",
4
- "module": "commonjs",
3
+ "target": "es2022",
4
+ "module": "node16",
5
+ "moduleResolution": "node16",
6
+ "lib": ["es2022", "esnext.disposable"],
7
+ "types": ["node"],
5
8
  "noEmit": true,
6
9
  "strict": true
7
10
  },
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zuplo/cli",
3
- "version": "6.72.9",
3
+ "version": "6.72.11",
4
4
  "repository": "https://github.com/zuplo/zuplo",
5
5
  "author": "Zuplo, Inc.",
6
6
  "type": "module",
@@ -27,10 +27,10 @@
27
27
  "@opentelemetry/api": "1.9.0",
28
28
  "@opentelemetry/api-logs": "0.201.1",
29
29
  "@swc/core": "1.10.18",
30
- "@zuplo/core": "6.72.9",
30
+ "@zuplo/core": "6.72.11",
31
31
  "@zuplo/editor": "1.0.20821740935",
32
- "@zuplo/openapi-tools": "6.72.9",
33
- "@zuplo/runtime": "6.72.9",
32
+ "@zuplo/openapi-tools": "6.72.11",
33
+ "@zuplo/runtime": "6.72.11",
34
34
  "chalk": "5.4.1",
35
35
  "chokidar": "3.5.3",
36
36
  "cookie": "1.0.2",
@@ -61,8 +61,8 @@
61
61
  "workerd": "1.20241230.0",
62
62
  "yargs": "17.7.2",
63
63
  "zod": "3.25.76",
64
- "@zuplo/graphql": "6.72.9",
65
- "@zuplo/otel": "6.72.9"
64
+ "@zuplo/graphql": "6.72.11",
65
+ "@zuplo/otel": "6.72.11"
66
66
  },
67
67
  "bundleDependencies": [
68
68
  "@inquirer/prompts",