@whooshbang/contract-mock 1.0.0-rc.16
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 +141 -0
- package/LICENSE +21 -0
- package/README.md +173 -0
- package/dist/app.d.ts +8 -0
- package/dist/app.js +16 -0
- package/dist/app.js.map +1 -0
- package/dist/cli.d.ts +26 -0
- package/dist/cli.js +249 -0
- package/dist/cli.js.map +1 -0
- package/dist/control-surface.d.ts +13 -0
- package/dist/control-surface.js +158 -0
- package/dist/control-surface.js.map +1 -0
- package/dist/core.d.ts +33 -0
- package/dist/core.js +3459 -0
- package/dist/core.js.map +1 -0
- package/dist/index.d.ts +4 -0
- package/dist/index.js +4 -0
- package/dist/index.js.map +1 -0
- package/dist/interaction-control.d.ts +6 -0
- package/dist/interaction-control.js +76 -0
- package/dist/interaction-control.js.map +1 -0
- package/dist/scenarios.d.ts +14 -0
- package/dist/scenarios.js +73 -0
- package/dist/scenarios.js.map +1 -0
- package/dist/types.d.ts +203 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/worker.d.ts +9 -0
- package/dist/worker.js +10 -0
- package/dist/worker.js.map +1 -0
- package/package.json +67 -0
- package/scenarios/v1/manifest.json +31 -0
package/dist/types.d.ts
ADDED
|
@@ -0,0 +1,203 @@
|
|
|
1
|
+
import type { AccountProjection, ApiCredential, CustomerEndpoint, Environment, InteractionEvent, MachineClient, MachineCredential, MachineEventAckDisposition, Message, WhooshBangEventV1ContractDocument, Project, SubscriptionLink } from "@whooshbang/contracts";
|
|
2
|
+
export type ContractMockScenarioName = "nominal" | "repeated-idempotent-message" | "idempotency-conflict" | "unbound-subscriber" | "retryable-provider-failure" | "terminal-provider-rejection" | "ambiguous-provider-outcome" | "cancellation-before-send" | "cancellation-too-late" | "interaction-confirm" | "interaction-select" | "interaction-input" | "interaction-duplicate" | "interaction-stale" | "interaction-expired" | "interaction-unauthorized" | "machine-event-replay" | "machine-cursor-contiguous" | "machine-poison-quarantine" | "cross-machine-rejection" | "cross-machine-answer-origin" | "signed-webhook-success" | "signed-webhook-retry" | "signed-webhook-terminal" | "rate-limited";
|
|
3
|
+
export type ProjectScope = "subscriptions:write" | "subscriptions:read" | "messages:write" | "messages:read" | "machine-clients:write" | "machine-clients:read" | "capabilities:read";
|
|
4
|
+
/**
|
|
5
|
+
* The account-level vocabulary, which only an OAuth grant or a human session
|
|
6
|
+
* can hold. A project credential lives inside one project environment and can
|
|
7
|
+
* never create or enumerate its siblings.
|
|
8
|
+
*/
|
|
9
|
+
export type AccountScope = "projects:write" | "projects:read";
|
|
10
|
+
export type OAuthScope = AccountScope | ProjectScope;
|
|
11
|
+
export type MachineScope = "machine-messages:write" | "machine-messages:read" | "machine-events:read" | "machine-events:ack";
|
|
12
|
+
interface CredentialBase {
|
|
13
|
+
readonly accountId: string;
|
|
14
|
+
readonly environment: Environment;
|
|
15
|
+
readonly projectId: string;
|
|
16
|
+
readonly token: string;
|
|
17
|
+
}
|
|
18
|
+
export interface ContractMockHumanCredential {
|
|
19
|
+
readonly accountId: string;
|
|
20
|
+
readonly kind: "human";
|
|
21
|
+
readonly role: AccountProjection["membership"]["role"];
|
|
22
|
+
readonly token: string;
|
|
23
|
+
}
|
|
24
|
+
export interface ContractMockProjectCredential extends CredentialBase {
|
|
25
|
+
readonly credentialId?: ApiCredential["id"];
|
|
26
|
+
/**
|
|
27
|
+
* Environment identifier used in environment-scoped paths.
|
|
28
|
+
*
|
|
29
|
+
* Omission derives a deterministic identifier from the project and
|
|
30
|
+
* environment kind, which keeps existing fixture credentials valid.
|
|
31
|
+
*/
|
|
32
|
+
readonly environmentId?: string;
|
|
33
|
+
readonly kind: "project";
|
|
34
|
+
readonly scopes: readonly ProjectScope[];
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* An account-scoped OAuth grant.
|
|
38
|
+
*
|
|
39
|
+
* It names an account and its scopes but never a project: a request names the
|
|
40
|
+
* project and environment in its path, and the mock checks that pair against
|
|
41
|
+
* this account exactly as the service checks it against the granting person's
|
|
42
|
+
* membership.
|
|
43
|
+
*/
|
|
44
|
+
export interface ContractMockGrantCredential {
|
|
45
|
+
readonly accountId: string;
|
|
46
|
+
readonly kind: "grant";
|
|
47
|
+
readonly scopes: readonly OAuthScope[];
|
|
48
|
+
readonly token: string;
|
|
49
|
+
}
|
|
50
|
+
export interface ContractMockMachineCredential extends CredentialBase {
|
|
51
|
+
readonly bindingId: string;
|
|
52
|
+
readonly credentialId?: string;
|
|
53
|
+
readonly kind: "machine";
|
|
54
|
+
readonly machineClientId: string;
|
|
55
|
+
readonly machineId: string;
|
|
56
|
+
readonly notifierId: string;
|
|
57
|
+
readonly scopes: readonly MachineScope[];
|
|
58
|
+
readonly status: "active" | "revoked";
|
|
59
|
+
readonly subscriberId: string;
|
|
60
|
+
}
|
|
61
|
+
export type ContractMockCredential = ContractMockHumanCredential | ContractMockGrantCredential | ContractMockProjectCredential | ContractMockMachineCredential;
|
|
62
|
+
export interface ContractMockClock {
|
|
63
|
+
now(): Date;
|
|
64
|
+
}
|
|
65
|
+
export type ContractMockIdKind = "account" | "api_credential" | "binding" | "customer_endpoint" | "customer_endpoint_attempt" | "diagnostic" | "environment" | "event" | "interaction" | "machine_client" | "message" | "notifier" | "project" | "request" | "subscription_link";
|
|
66
|
+
export type ContractMockIdGenerator = (kind: ContractMockIdKind) => string;
|
|
67
|
+
export type ProviderOutcome = {
|
|
68
|
+
readonly kind: "accepted";
|
|
69
|
+
} | {
|
|
70
|
+
readonly kind: "retryable";
|
|
71
|
+
readonly retryAfterSeconds?: number;
|
|
72
|
+
} | {
|
|
73
|
+
readonly kind: "terminal";
|
|
74
|
+
} | {
|
|
75
|
+
readonly kind: "ambiguous";
|
|
76
|
+
};
|
|
77
|
+
export interface ProviderAttemptContext {
|
|
78
|
+
readonly attempt: number;
|
|
79
|
+
readonly messageId: string;
|
|
80
|
+
readonly scenario: ContractMockScenarioName;
|
|
81
|
+
}
|
|
82
|
+
export type ProviderOutcomeScript = (context: ProviderAttemptContext) => ProviderOutcome | Promise<ProviderOutcome>;
|
|
83
|
+
export interface MachineEventSeed {
|
|
84
|
+
readonly event: InteractionEvent;
|
|
85
|
+
readonly machineClientId: string;
|
|
86
|
+
readonly quarantinable?: boolean;
|
|
87
|
+
readonly signatureValid?: boolean;
|
|
88
|
+
readonly streamIdentityValid?: boolean;
|
|
89
|
+
}
|
|
90
|
+
export type MachineEventDeliveryScript = () => readonly MachineEventSeed[];
|
|
91
|
+
export type WebhookReceiver = (request: Request) => Promise<Response>;
|
|
92
|
+
export type InteractionPollWait = (delayMilliseconds: number, signal: AbortSignal) => Promise<void>;
|
|
93
|
+
export interface WhooshBangContractMockOptions {
|
|
94
|
+
readonly clock?: ContractMockClock;
|
|
95
|
+
readonly credentials?: readonly ContractMockCredential[];
|
|
96
|
+
readonly currentSigningSecret?: string;
|
|
97
|
+
readonly idGenerator?: ContractMockIdGenerator;
|
|
98
|
+
readonly interactionPollWait?: InteractionPollWait;
|
|
99
|
+
readonly machineEventDeliveryScript?: MachineEventDeliveryScript;
|
|
100
|
+
readonly previousSigningSecret?: string;
|
|
101
|
+
readonly providerOutcomeScript?: ProviderOutcomeScript;
|
|
102
|
+
readonly scenario?: ContractMockScenarioName;
|
|
103
|
+
readonly webhookReceiver?: WebhookReceiver;
|
|
104
|
+
}
|
|
105
|
+
export interface ProviderAttemptSnapshot {
|
|
106
|
+
readonly attempt: number;
|
|
107
|
+
readonly at: string;
|
|
108
|
+
readonly messageId: string;
|
|
109
|
+
readonly outcome: ProviderOutcome["kind"];
|
|
110
|
+
}
|
|
111
|
+
export interface LogicalOperationSnapshot {
|
|
112
|
+
readonly idempotencyResult: "new" | "replayed" | "conflict";
|
|
113
|
+
readonly operation: string;
|
|
114
|
+
readonly resourceId?: string;
|
|
115
|
+
}
|
|
116
|
+
export interface LogicalEventSnapshot {
|
|
117
|
+
readonly eventId: string;
|
|
118
|
+
readonly resourceId?: string;
|
|
119
|
+
readonly type: WhooshBangEventV1ContractDocument["type"];
|
|
120
|
+
}
|
|
121
|
+
export interface CursorCommitSnapshot {
|
|
122
|
+
readonly committedCursor: string | null;
|
|
123
|
+
readonly disposition: MachineEventAckDisposition;
|
|
124
|
+
readonly eventId: string;
|
|
125
|
+
readonly machineClientId: string;
|
|
126
|
+
}
|
|
127
|
+
export interface WebhookAttemptSnapshot {
|
|
128
|
+
readonly action: "accepted" | "retry" | "terminal";
|
|
129
|
+
readonly attempt: number;
|
|
130
|
+
readonly eventId: string;
|
|
131
|
+
readonly reason: string;
|
|
132
|
+
readonly retryAfterSeconds?: number;
|
|
133
|
+
readonly signatureCount: number;
|
|
134
|
+
readonly status?: number;
|
|
135
|
+
readonly timestamp: number;
|
|
136
|
+
}
|
|
137
|
+
export interface DiagnosticSnapshot {
|
|
138
|
+
readonly environment?: Environment;
|
|
139
|
+
readonly idempotencyResult?: "new" | "replayed" | "conflict";
|
|
140
|
+
readonly operation: string;
|
|
141
|
+
readonly projectId?: string;
|
|
142
|
+
readonly requestId: string;
|
|
143
|
+
readonly resourceId?: string;
|
|
144
|
+
readonly scenario: ContractMockScenarioName;
|
|
145
|
+
readonly stateTransition?: string;
|
|
146
|
+
}
|
|
147
|
+
export interface ContractMockSnapshot {
|
|
148
|
+
readonly accounts: readonly AccountProjection[];
|
|
149
|
+
readonly apiCredentials: readonly ApiCredential[];
|
|
150
|
+
readonly contractVersion: "1.0.0-rc.13";
|
|
151
|
+
readonly cursorCommits: readonly CursorCommitSnapshot[];
|
|
152
|
+
readonly customerEndpoints: readonly CustomerEndpoint[];
|
|
153
|
+
readonly diagnostics: readonly DiagnosticSnapshot[];
|
|
154
|
+
readonly links: readonly SubscriptionLink[];
|
|
155
|
+
readonly logicalEvents: readonly LogicalEventSnapshot[];
|
|
156
|
+
readonly logicalOperations: readonly LogicalOperationSnapshot[];
|
|
157
|
+
readonly machineClients: readonly MachineClient[];
|
|
158
|
+
readonly machineCredentials: readonly MachineCredential[];
|
|
159
|
+
readonly messages: readonly Message[];
|
|
160
|
+
readonly providerAttempts: readonly ProviderAttemptSnapshot[];
|
|
161
|
+
readonly projects: readonly Project[];
|
|
162
|
+
readonly scenario: ContractMockScenarioName;
|
|
163
|
+
readonly scenarioVersion: "contract-mock-scenarios.v1";
|
|
164
|
+
readonly webhookAttempts: readonly WebhookAttemptSnapshot[];
|
|
165
|
+
}
|
|
166
|
+
export type InteractionControlOutcome = "authorized" | "duplicate" | "stale" | "expired" | "unauthorized";
|
|
167
|
+
export interface InteractionControlInput {
|
|
168
|
+
readonly messageId: string;
|
|
169
|
+
readonly outcome?: InteractionControlOutcome;
|
|
170
|
+
readonly response: {
|
|
171
|
+
readonly type: "confirm";
|
|
172
|
+
readonly value: boolean;
|
|
173
|
+
} | {
|
|
174
|
+
readonly type: "select";
|
|
175
|
+
readonly value: string;
|
|
176
|
+
} | {
|
|
177
|
+
readonly type: "input";
|
|
178
|
+
readonly value: string;
|
|
179
|
+
};
|
|
180
|
+
}
|
|
181
|
+
export interface InteractionControlResult {
|
|
182
|
+
readonly eventCreated: boolean;
|
|
183
|
+
readonly outcome: InteractionControlOutcome;
|
|
184
|
+
}
|
|
185
|
+
export interface ContractMockControl {
|
|
186
|
+
enqueueMachineEvent(seed: MachineEventSeed): void;
|
|
187
|
+
reset(scenario?: ContractMockScenarioName): Promise<void>;
|
|
188
|
+
runPending(): Promise<void>;
|
|
189
|
+
setProviderOutcomes(outcomes: readonly ProviderOutcome[]): void;
|
|
190
|
+
setWebhookResponses(responses: readonly (number | "network_failure")[]): void;
|
|
191
|
+
submitInteraction(input: InteractionControlInput): Promise<InteractionControlResult>;
|
|
192
|
+
}
|
|
193
|
+
export interface WhooshBangContractMock {
|
|
194
|
+
readonly control: ContractMockControl;
|
|
195
|
+
fetch(request: Request): Promise<Response>;
|
|
196
|
+
inspect(): ContractMockSnapshot;
|
|
197
|
+
}
|
|
198
|
+
export interface ContractMockScenarioDescriptor {
|
|
199
|
+
readonly description: string;
|
|
200
|
+
readonly name: ContractMockScenarioName;
|
|
201
|
+
readonly version: "contract-mock-scenarios.v1";
|
|
202
|
+
}
|
|
203
|
+
export {};
|
package/dist/types.js
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.js","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":""}
|
package/dist/worker.d.ts
ADDED
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
import type { WhooshBangContractMockOptions } from "./types.js";
|
|
2
|
+
export interface WhooshBangContractMockWorker {
|
|
3
|
+
fetch(request: Request): Promise<Response>;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Fetch-only compatibility entry point. It does not import the Node listener
|
|
7
|
+
* or the token-authenticated HTTP control router and never exposes control.
|
|
8
|
+
*/
|
|
9
|
+
export declare function createWhooshBangContractMockWorker(options?: WhooshBangContractMockOptions): WhooshBangContractMockWorker;
|
package/dist/worker.js
ADDED
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import { createWhooshBangContractMockCore } from "./core.js";
|
|
2
|
+
/**
|
|
3
|
+
* Fetch-only compatibility entry point. It does not import the Node listener
|
|
4
|
+
* or the token-authenticated HTTP control router and never exposes control.
|
|
5
|
+
*/
|
|
6
|
+
export function createWhooshBangContractMockWorker(options = {}) {
|
|
7
|
+
const mock = createWhooshBangContractMockCore(options);
|
|
8
|
+
return { fetch: (request) => mock.fetch(request) };
|
|
9
|
+
}
|
|
10
|
+
//# sourceMappingURL=worker.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"worker.js","sourceRoot":"","sources":["../src/worker.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gCAAgC,EAAE,MAAM,WAAW,CAAC;AAQ7D;;;GAGG;AACH,MAAM,UAAU,kCAAkC,CAChD,UAAyC,EAAE;IAE3C,MAAM,IAAI,GAAG,gCAAgC,CAAC,OAAO,CAAC,CAAC;IACvD,OAAO,EAAE,KAAK,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,IAAI,CAAC,KAAK,CAAC,OAAO,CAAC,EAAE,CAAC;AACrD,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,67 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@whooshbang/contract-mock",
|
|
3
|
+
"version": "1.0.0-rc.16",
|
|
4
|
+
"description": "Deterministic local executable mock for WhooshBang V1",
|
|
5
|
+
"private": false,
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"type": "module",
|
|
8
|
+
"sideEffects": false,
|
|
9
|
+
"homepage": "https://whooshbang.com",
|
|
10
|
+
"repository": {
|
|
11
|
+
"type": "git",
|
|
12
|
+
"url": "git+https://github.com/flowxo/whooshbang.git",
|
|
13
|
+
"directory": "apps/contract-mock"
|
|
14
|
+
},
|
|
15
|
+
"keywords": [
|
|
16
|
+
"whooshbang",
|
|
17
|
+
"notifications",
|
|
18
|
+
"telegram",
|
|
19
|
+
"mock",
|
|
20
|
+
"cli"
|
|
21
|
+
],
|
|
22
|
+
"publishConfig": {
|
|
23
|
+
"access": "public",
|
|
24
|
+
"tag": "next"
|
|
25
|
+
},
|
|
26
|
+
"bin": {
|
|
27
|
+
"whooshbang-contract-mock": "dist/cli.js"
|
|
28
|
+
},
|
|
29
|
+
"files": [
|
|
30
|
+
"CHANGELOG.md",
|
|
31
|
+
"LICENSE",
|
|
32
|
+
"README.md",
|
|
33
|
+
"dist",
|
|
34
|
+
"scenarios"
|
|
35
|
+
],
|
|
36
|
+
"exports": {
|
|
37
|
+
".": {
|
|
38
|
+
"types": "./dist/index.d.ts",
|
|
39
|
+
"import": "./dist/index.js",
|
|
40
|
+
"default": "./dist/index.js"
|
|
41
|
+
},
|
|
42
|
+
"./worker": {
|
|
43
|
+
"types": "./dist/worker.d.ts",
|
|
44
|
+
"import": "./dist/worker.js",
|
|
45
|
+
"default": "./dist/worker.js"
|
|
46
|
+
},
|
|
47
|
+
"./scenarios/v1/manifest.json": "./scenarios/v1/manifest.json",
|
|
48
|
+
"./package.json": "./package.json"
|
|
49
|
+
},
|
|
50
|
+
"scripts": {
|
|
51
|
+
"build": "tsx scripts/clean-dist.ts && tsc -p tsconfig.build.json",
|
|
52
|
+
"lint": "eslint scripts src test --max-warnings=0",
|
|
53
|
+
"test": "vitest run --no-file-parallelism",
|
|
54
|
+
"type-check": "tsc --noEmit -p tsconfig.json"
|
|
55
|
+
},
|
|
56
|
+
"dependencies": {
|
|
57
|
+
"@whooshbang/contracts": "1.0.0-rc.13",
|
|
58
|
+
"hono": "4.12.34"
|
|
59
|
+
},
|
|
60
|
+
"devDependencies": {
|
|
61
|
+
"@whooshbang/mcp": "1.0.0-rc.4",
|
|
62
|
+
"@whooshbang/sdk": "1.0.0-rc.14"
|
|
63
|
+
},
|
|
64
|
+
"engines": {
|
|
65
|
+
"node": ">=22.13.0 <23"
|
|
66
|
+
}
|
|
67
|
+
}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
{
|
|
2
|
+
"schema": "contract-mock-scenarios.v1",
|
|
3
|
+
"contract_version": "1.0.0-rc.13",
|
|
4
|
+
"scenarios": [
|
|
5
|
+
"nominal",
|
|
6
|
+
"repeated-idempotent-message",
|
|
7
|
+
"idempotency-conflict",
|
|
8
|
+
"unbound-subscriber",
|
|
9
|
+
"retryable-provider-failure",
|
|
10
|
+
"terminal-provider-rejection",
|
|
11
|
+
"ambiguous-provider-outcome",
|
|
12
|
+
"cancellation-before-send",
|
|
13
|
+
"cancellation-too-late",
|
|
14
|
+
"interaction-confirm",
|
|
15
|
+
"interaction-select",
|
|
16
|
+
"interaction-input",
|
|
17
|
+
"interaction-duplicate",
|
|
18
|
+
"interaction-stale",
|
|
19
|
+
"interaction-expired",
|
|
20
|
+
"interaction-unauthorized",
|
|
21
|
+
"machine-event-replay",
|
|
22
|
+
"machine-cursor-contiguous",
|
|
23
|
+
"machine-poison-quarantine",
|
|
24
|
+
"cross-machine-rejection",
|
|
25
|
+
"cross-machine-answer-origin",
|
|
26
|
+
"signed-webhook-success",
|
|
27
|
+
"signed-webhook-retry",
|
|
28
|
+
"signed-webhook-terminal",
|
|
29
|
+
"rate-limited"
|
|
30
|
+
]
|
|
31
|
+
}
|