@apifuse/provider-sdk 2.2.0-beta.37 → 2.2.0-beta.38

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.
@@ -1,7 +1,7 @@
1
1
  import { z } from "zod";
2
2
  export declare const ConnectionModeSchema: z.ZodEnum<{
3
- none: "none";
4
3
  credentials: "credentials";
4
+ none: "none";
5
5
  oauth2: "oauth2";
6
6
  "platform-managed": "platform-managed";
7
7
  oauth2_proxied: "oauth2_proxied";
@@ -9,8 +9,8 @@ export declare const ConnectionModeSchema: z.ZodEnum<{
9
9
  export declare const OperationConnectionSchema: z.ZodObject<{
10
10
  id: z.ZodString;
11
11
  mode: z.ZodEnum<{
12
- none: "none";
13
12
  credentials: "credentials";
13
+ none: "none";
14
14
  oauth2: "oauth2";
15
15
  "platform-managed": "platform-managed";
16
16
  oauth2_proxied: "oauth2_proxied";
@@ -27,8 +27,8 @@ export declare const OperationRequestSchema: z.ZodObject<{
27
27
  connection: z.ZodOptional<z.ZodObject<{
28
28
  id: z.ZodString;
29
29
  mode: z.ZodEnum<{
30
- none: "none";
31
30
  credentials: "credentials";
31
+ none: "none";
32
32
  oauth2: "oauth2";
33
33
  "platform-managed": "platform-managed";
34
34
  oauth2_proxied: "oauth2_proxied";
@@ -118,8 +118,8 @@ export declare const AuthFlowRequestSchema: z.ZodObject<{
118
118
  connection: z.ZodOptional<z.ZodObject<{
119
119
  id: z.ZodString;
120
120
  mode: z.ZodEnum<{
121
- none: "none";
122
121
  credentials: "credentials";
122
+ none: "none";
123
123
  oauth2: "oauth2";
124
124
  "platform-managed": "platform-managed";
125
125
  oauth2_proxied: "oauth2_proxied";
package/dist/types.d.ts CHANGED
@@ -1,4 +1,5 @@
1
1
  import type ms from "ms";
2
+ import type { HealthScenario } from "./health-scenario.js";
2
3
  import type { SerializedCookieJar } from "tough-cookie";
3
4
  import type { infer as ZodInfer, ZodType } from "zod";
4
5
  /** Minimal Standard Schema v1 shape accepted by provider operations. */
@@ -549,7 +550,7 @@ export interface HealthJourneyRunResult {
549
550
  label?: string;
550
551
  metadata?: Record<string, unknown>;
551
552
  }
552
- export interface HealthJourneyDefinition {
553
+ interface HealthJourneyDefinitionBase {
553
554
  id: string;
554
555
  title?: string;
555
556
  description?: string;
@@ -561,14 +562,14 @@ export interface HealthJourneyDefinition {
561
562
  requiredSecrets?: readonly string[];
562
563
  manualTrigger?: HealthJourneyManualTriggerPolicy;
563
564
  steps: readonly [HealthJourneyStep, ...HealthJourneyStep[]];
564
- /**
565
- * Required: a journey always declares `coversOperations`, and the health
566
- * monitor reports a run-less journey as `journey_run_missing`. Declaration
567
- * validation rejects a missing `run` (`health-journey-executable`), so this
568
- * is typed required to fail at compile time rather than at boot.
569
- */
570
- run: (ctx: HealthJourneyRunContext) => Promise<HealthJourneyRunResult | undefined>;
571
565
  }
566
+ export type HealthJourneyDefinition = HealthJourneyDefinitionBase & ({
567
+ run: (ctx: HealthJourneyRunContext) => Promise<HealthJourneyRunResult | undefined>;
568
+ scenario?: never;
569
+ } | {
570
+ scenario: HealthScenario;
571
+ run?: never;
572
+ });
572
573
  /**
573
574
  * Health-check authoring surface owned by `@apifuse/provider-sdk`.
574
575
  *
@@ -2051,3 +2052,4 @@ export interface ProviderDefinition {
2051
2052
  healthProbe?: ProviderHealthProbeConfig;
2052
2053
  healthJourneys?: readonly HealthJourneyDefinition[];
2053
2054
  }
2055
+ export {};
package/package.json CHANGED
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "2.2.0-beta.37",
2
+ "version": "2.2.0-beta.38",
3
3
  "name": "@apifuse/provider-sdk",
4
4
  "private": false,
5
5
  "type": "module",
@@ -1,5 +1,6 @@
1
1
  import { describeSchema } from "./contract-serialization.js";
2
2
  import { ProviderError } from "./errors.js";
3
+ import { HealthScenarioSchema } from "./health-scenario.js";
3
4
  import type {
4
5
  HealthJourneyDefinition,
5
6
  ProviderDefinition,
@@ -12,6 +13,8 @@ export const DECLARATION_INVALID_CODE = "DECLARATION_INVALID";
12
13
  export const DECLARATION_RULE_IDS = {
13
14
  challengeShape: "credentials-challenge-shape",
14
15
  journeyExecutable: "health-journey-executable",
16
+ journeyRunScenarioExclusive: "health-journey-run-scenario-exclusive",
17
+ journeyScenarioValid: "health-journey-scenario-valid",
15
18
  schemaSerializable: "operation-schema-serializable",
16
19
  proxyExplicitPolicy: "proxy-explicit-policy",
17
20
  proxyVendorExclusive: "proxy-vendor-fields-exclusive",
@@ -62,15 +65,39 @@ function validateHealthDeclaration(
62
65
  ): void {
63
66
  for (const [index, journey] of (provider.healthJourneys ?? []).entries()) {
64
67
  if (!journey || typeof journey !== "object") continue;
65
- if (typeof journey.run !== "function") {
68
+ const hasRun = journey.run !== undefined;
69
+ const hasScenario = journey.scenario !== undefined;
70
+ if (hasRun && hasScenario) {
71
+ const journeyPath = healthJourneyPath(journey, index);
72
+ violations.push({
73
+ ruleId: DECLARATION_RULE_IDS.journeyRunScenarioExclusive,
74
+ path: journeyPath,
75
+ message: "A health journey must declare exactly one of run or scenario, not both.",
76
+ fix: `Remove either ${journeyPath}.run or ${journeyPath}.scenario.`,
77
+ });
78
+ }
79
+ if (!hasRun && !hasScenario) {
66
80
  const journeyPath = healthJourneyPath(journey, index);
67
81
  violations.push({
68
82
  ruleId: DECLARATION_RULE_IDS.journeyExecutable,
69
83
  path: `${journeyPath}.run`,
70
- message: "coversOperations cannot provide health coverage without executable run logic.",
71
- fix: `Add an async run(ctx) implementation to ${journeyPath}.`,
84
+ message:
85
+ "coversOperations cannot provide health coverage without run or a declarative scenario.",
86
+ fix: `Add an async run(ctx) implementation or a valid scenario to ${journeyPath}.`,
72
87
  });
73
88
  }
89
+ if (hasScenario) {
90
+ const parsed = HealthScenarioSchema.safeParse(journey.scenario);
91
+ if (!parsed.success) {
92
+ const journeyPath = healthJourneyPath(journey, index);
93
+ violations.push({
94
+ ruleId: DECLARATION_RULE_IDS.journeyScenarioValid,
95
+ path: `${journeyPath}.scenario`,
96
+ message: "scenario must conform to HealthScenario.",
97
+ fix: "Build the scenario with defineHealthScenario().",
98
+ });
99
+ }
100
+ }
74
101
  }
75
102
 
76
103
  // NOTE: healthCheck.cases[].enabled is intentionally NOT validated here.
package/src/define.ts CHANGED
@@ -2132,6 +2132,7 @@ const HEALTH_JOURNEY_FIELDS = new Set([
2132
2132
  "manualTrigger",
2133
2133
  "steps",
2134
2134
  "run",
2135
+ "scenario",
2135
2136
  ]);
2136
2137
  const HEALTH_JOURNEY_SCHEDULE_FIELDS = new Set(["kind", "interval", "jitter", "randomize"]);
2137
2138
  const HEALTH_JOURNEY_STEP_FIELDS = new Set([
@@ -2667,6 +2668,14 @@ function validateHealthJourneys(
2667
2668
  }
2668
2669
  if (journey.manualTrigger !== undefined)
2669
2670
  validateHealthJourneyManualTrigger(providerId, journey.id, journey.manualTrigger);
2671
+ if (journey.scenario !== undefined && journey.smsMatchers !== undefined)
2672
+ throw new ValidationError(
2673
+ `Provider "${providerId}" healthJourneys.${journey.id}.smsMatchers is not allowed on declarative scenarios.`,
2674
+ );
2675
+ if (journey.scenario !== undefined && journey.requiredSecrets !== undefined)
2676
+ throw new ValidationError(
2677
+ `Provider "${providerId}" healthJourneys.${journey.id}.requiredSecrets is not allowed on declarative scenarios.`,
2678
+ );
2670
2679
  if (journey.timeout !== undefined)
2671
2680
  assertIsoDuration(
2672
2681
  journey.timeout,