@superdurable/connectors-sdk 0.0.0-stage → 0.1.1
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/LICENSE +21 -0
- package/README.md +264 -2
- package/dist/chunk-2IDXFKMY.js +251 -0
- package/dist/chunk-2NBM7P4T.js +42 -0
- package/dist/chunk-KD5DYYSU.js +93 -0
- package/dist/chunk-SOXYPIMO.js +179 -0
- package/dist/connectormock/index.d.ts +181 -0
- package/dist/connectormock/index.js +350 -0
- package/dist/credentials-vrvW0d4j.d.ts +445 -0
- package/dist/index.d.ts +81 -0
- package/dist/index.js +376 -0
- package/dist/oauthtoken/index.d.ts +90 -0
- package/dist/oauthtoken/index.js +236 -0
- package/dist/operation-Ca8rfacf.d.ts +34 -0
- package/dist/projectconfig/index.d.ts +569 -0
- package/dist/projectconfig/index.js +1433 -0
- package/dist/providerhttp/index.d.ts +57 -0
- package/dist/providerhttp/index.js +26 -0
- package/dist/singledispatch/index.d.ts +72 -0
- package/dist/singledispatch/index.js +178 -0
- package/package.json +73 -4
package/dist/index.js
ADDED
|
@@ -0,0 +1,376 @@
|
|
|
1
|
+
import {
|
|
2
|
+
validateMutationDefinition,
|
|
3
|
+
validateQueryDefinition
|
|
4
|
+
} from "./chunk-2NBM7P4T.js";
|
|
5
|
+
import {
|
|
6
|
+
SecretString,
|
|
7
|
+
StaticCredentialProvider,
|
|
8
|
+
createCall,
|
|
9
|
+
resolveCredential,
|
|
10
|
+
resolveCredentialAfterRejection
|
|
11
|
+
} from "./chunk-KD5DYYSU.js";
|
|
12
|
+
import {
|
|
13
|
+
BranchDefinitionSchema,
|
|
14
|
+
CallIDNamespace,
|
|
15
|
+
CallIDSchema,
|
|
16
|
+
ConnectionRefSchema,
|
|
17
|
+
ConnectorConfigurationRefSchema,
|
|
18
|
+
ConnectorConfigurationUISchema,
|
|
19
|
+
ConnectorUIBindingSchema,
|
|
20
|
+
ConnectorUIUnitSchema,
|
|
21
|
+
DefectBranchID,
|
|
22
|
+
FailureKindSchema,
|
|
23
|
+
FailureSchema,
|
|
24
|
+
MutationDefinitionWireSchema,
|
|
25
|
+
MutationResultSchema,
|
|
26
|
+
OperationRefSchema,
|
|
27
|
+
QueryDefinitionWireSchema,
|
|
28
|
+
QueryResultSchema,
|
|
29
|
+
ReauthorizationRequiredError,
|
|
30
|
+
ReceiptSchema,
|
|
31
|
+
RetryError,
|
|
32
|
+
StepDefaultsWireSchema,
|
|
33
|
+
UncertainBranchID,
|
|
34
|
+
defaultConnectorStepExecuteRetryPolicy,
|
|
35
|
+
defaultIdempotencyKey,
|
|
36
|
+
deriveCallID,
|
|
37
|
+
newMutationBranch,
|
|
38
|
+
newMutationRetry,
|
|
39
|
+
newMutationUncertain,
|
|
40
|
+
newQueryBranch,
|
|
41
|
+
newQueryRetry,
|
|
42
|
+
retryPolicyToGoWire,
|
|
43
|
+
zeroReceipt
|
|
44
|
+
} from "./chunk-SOXYPIMO.js";
|
|
45
|
+
|
|
46
|
+
// src/run_operation.ts
|
|
47
|
+
async function runQuery(operation, call, input) {
|
|
48
|
+
if (!operation) return defectResult(void 0, call, "connector query is required");
|
|
49
|
+
const definition = operation.definition();
|
|
50
|
+
try {
|
|
51
|
+
validateQueryDefinition(definition);
|
|
52
|
+
} catch (error) {
|
|
53
|
+
return defectResult(definition, call, `invalid query definition: ${safeErrorMessage(error)}`);
|
|
54
|
+
}
|
|
55
|
+
const invalidCall = validateCall(call, definition.operation);
|
|
56
|
+
if (invalidCall) return defectResult(definition, call, invalidCall);
|
|
57
|
+
const attempt = await operation.invoke(call, input);
|
|
58
|
+
return resultFromAttempt(definition, call, attempt, "query");
|
|
59
|
+
}
|
|
60
|
+
async function runMutation(operation, call, input) {
|
|
61
|
+
if (!operation) return defectResult(void 0, call, "connector mutation is required");
|
|
62
|
+
const definition = operation.definition();
|
|
63
|
+
try {
|
|
64
|
+
validateMutationDefinition(definition);
|
|
65
|
+
} catch (error) {
|
|
66
|
+
return defectResult(definition, call, `invalid mutation definition: ${safeErrorMessage(error)}`);
|
|
67
|
+
}
|
|
68
|
+
const invalidCall = validateCall(call, definition.operation);
|
|
69
|
+
if (invalidCall) return defectResult(definition, call, invalidCall);
|
|
70
|
+
const chosenKey = operation.idempotencyKey(call.id, input) || call.id;
|
|
71
|
+
if (!chosenKey.trim()) return defectResult(definition, call, "mutation returned an invalid idempotency key");
|
|
72
|
+
const mutationCall = { ...call, context: call.context, idempotencyKey: chosenKey };
|
|
73
|
+
Object.defineProperty(mutationCall, "context", { value: call.context, enumerable: false });
|
|
74
|
+
for (const method of ["reportProgress", "writeText", "hasProgressStream", "hasTextStream"]) Object.defineProperty(mutationCall, method, { value: call[method], enumerable: false });
|
|
75
|
+
const attempt = await operation.invoke(mutationCall, input);
|
|
76
|
+
return resultFromAttempt(definition, mutationCall, attempt, "mutation");
|
|
77
|
+
}
|
|
78
|
+
function resultFromAttempt(definition, call, attempt, operationKind) {
|
|
79
|
+
if (!attempt || typeof attempt !== "object") return defectResult(definition, call, `${operationKind} returned an invalid attempt`);
|
|
80
|
+
if (attempt.kind === "retry") {
|
|
81
|
+
const failure = FailureSchema.safeParse(attempt.failure);
|
|
82
|
+
if (!failure.success || !Number.isSafeInteger(attempt.retryAfterMs) || attempt.retryAfterMs < 0) return defectResult(definition, call, `${operationKind} returned an invalid retry attempt`);
|
|
83
|
+
throw new RetryError(failure.data, attempt.retryAfterMs);
|
|
84
|
+
}
|
|
85
|
+
if (attempt.kind === "branch" || operationKind === "mutation" && attempt.kind === "uncertain") {
|
|
86
|
+
const branch = attempt.kind === "uncertain" ? UncertainBranchID : attempt.branch;
|
|
87
|
+
if (!definition.branches.some((declared) => declared.id === branch)) {
|
|
88
|
+
return defectResult(definition, call, attempt.kind === "uncertain" ? "mutation returned uncertainty without declaring the uncertain branch" : `${operationKind} returned an unknown branch`);
|
|
89
|
+
}
|
|
90
|
+
const failure = "failure" in attempt && attempt.failure !== void 0 ? FailureSchema.safeParse(attempt.failure) : void 0;
|
|
91
|
+
if (failure && !failure.success) return defectResult(definition, call, `${operationKind} returned an invalid failure`);
|
|
92
|
+
if (attempt.kind === "uncertain" && !failure) return defectResult(definition, call, "mutation returned an invalid uncertainty failure");
|
|
93
|
+
let receipt;
|
|
94
|
+
try {
|
|
95
|
+
receipt = completeReceipt(attempt.receipt, call);
|
|
96
|
+
} catch (error) {
|
|
97
|
+
return defectResult(definition, call, safeErrorMessage(error));
|
|
98
|
+
}
|
|
99
|
+
const result = { branch, value: attempt.value, receipt };
|
|
100
|
+
if (failure?.success) result.failure = failure.data;
|
|
101
|
+
return result;
|
|
102
|
+
}
|
|
103
|
+
return defectResult(definition, call, `${operationKind} returned an invalid attempt`);
|
|
104
|
+
}
|
|
105
|
+
function completeReceipt(draft, call) {
|
|
106
|
+
if (draft.callId && draft.callId !== call.id) throw new TypeError("operation returned a receipt for another call");
|
|
107
|
+
if (draft.idempotencyKey && draft.idempotencyKey !== call.idempotencyKey) throw new TypeError("operation returned a receipt with another idempotency key");
|
|
108
|
+
return ReceiptSchema.parse({ ...draft, callId: call.id, ...call.idempotencyKey ? { idempotencyKey: call.idempotencyKey } : {}, provider: draft.provider || call.operation.connectorId, observedAt: draft.observedAt && draft.observedAt !== "0001-01-01T00:00:00Z" ? draft.observedAt : (/* @__PURE__ */ new Date()).toISOString() });
|
|
109
|
+
}
|
|
110
|
+
function validateCall(call, operation) {
|
|
111
|
+
if (!call) return "connector call is required";
|
|
112
|
+
if (!CallIDSchema.safeParse(call.id).success) return "call ID must be a UUID";
|
|
113
|
+
if (!ConnectionRefSchema.safeParse(call.connection).success) return "connection provider and name are required";
|
|
114
|
+
if (!OperationRefSchema.safeParse(call.operation).success || call.operation.connectorId !== operation.connectorId || call.operation.operationId !== operation.operationId) return "connector call operation does not match the definition";
|
|
115
|
+
return void 0;
|
|
116
|
+
}
|
|
117
|
+
function defectResult(definition, call, message) {
|
|
118
|
+
const operation = definition?.operation;
|
|
119
|
+
const failure = { kind: "LOCAL_DEFECT", provider: operation?.connectorId || "connector", operation: operation?.operationId || "invoke", message };
|
|
120
|
+
const receipt = call && CallIDSchema.safeParse(call.id).success ? completeReceipt({}, call) : void 0;
|
|
121
|
+
return { branch: DefectBranchID, value: void 0, receipt, failure };
|
|
122
|
+
}
|
|
123
|
+
function safeErrorMessage(error) {
|
|
124
|
+
return error instanceof Error ? error.message : "invalid value";
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
// src/step.ts
|
|
128
|
+
import { StepRef, forceFail, goTo, retryAfter } from "@superdurable/dex";
|
|
129
|
+
function goToBranch(branch, target) {
|
|
130
|
+
return target ? { branch, target } : { branch };
|
|
131
|
+
}
|
|
132
|
+
function stepRef(stepType) {
|
|
133
|
+
return new StepRef(stepType);
|
|
134
|
+
}
|
|
135
|
+
var QueryStep = class {
|
|
136
|
+
inputCodec;
|
|
137
|
+
#configuration;
|
|
138
|
+
#options;
|
|
139
|
+
#ui;
|
|
140
|
+
#targets;
|
|
141
|
+
#optional;
|
|
142
|
+
#identity;
|
|
143
|
+
/** Validate static wiring before registering the Step in a Flow. */
|
|
144
|
+
constructor(configuration) {
|
|
145
|
+
if (!configuration?.operation) throw new TypeError("query operation is required");
|
|
146
|
+
const definition = configuration.operation.definition();
|
|
147
|
+
validateQueryDefinition(definition);
|
|
148
|
+
validateFactoryConfiguration(configuration);
|
|
149
|
+
const routes = validateBranchTargets(definition.branches, configuration.branches);
|
|
150
|
+
this.#configuration = configuration;
|
|
151
|
+
this.#options = mergeStepOptions(definition.stepDefaults, configuration.stepOptionsOverride);
|
|
152
|
+
this.#ui = ConnectorConfigurationUISchema.parse(configuration.configurationUI ?? { units: [] });
|
|
153
|
+
this.#targets = routes.targets;
|
|
154
|
+
this.#optional = routes.optional;
|
|
155
|
+
this.#identity = { operation: definition.operation, connection: configuration.connection };
|
|
156
|
+
if (configuration.inputCodec) this.inputCodec = configuration.inputCodec;
|
|
157
|
+
}
|
|
158
|
+
/** Stable Dex Step type. */
|
|
159
|
+
getStepType() {
|
|
160
|
+
return this.#configuration.stepType;
|
|
161
|
+
}
|
|
162
|
+
/** Isolated Execute options, including connector retry defaults. */
|
|
163
|
+
getStepOptions() {
|
|
164
|
+
return cloneStepOptions(this.#options);
|
|
165
|
+
}
|
|
166
|
+
/** Group metadata for Connector Studio. */
|
|
167
|
+
annotations() {
|
|
168
|
+
return { ...this.#configuration.annotations };
|
|
169
|
+
}
|
|
170
|
+
/** Isolated connector UI composition. */
|
|
171
|
+
configurationUI() {
|
|
172
|
+
return structuredClone(this.#ui);
|
|
173
|
+
}
|
|
174
|
+
/** Invoke, persist the optional terminal Attribute, and route the selected branch. */
|
|
175
|
+
async execute(context, input) {
|
|
176
|
+
const operationInput = this.#configuration.mapToOperationInput(input);
|
|
177
|
+
const call = createCall(context, this.#identity.connection, this.#identity.operation, {
|
|
178
|
+
...this.#configuration.progressStream ? { progressStream: this.#configuration.progressStream } : {},
|
|
179
|
+
...this.#configuration.textStream ? { textStream: this.#configuration.textStream } : {},
|
|
180
|
+
...this.#configuration.textOptions ? { textOptions: this.#configuration.textOptions } : {}
|
|
181
|
+
});
|
|
182
|
+
let result;
|
|
183
|
+
try {
|
|
184
|
+
result = await runQuery(this.#configuration.operation, call, operationInput);
|
|
185
|
+
} catch (error) {
|
|
186
|
+
throwDexRetry(error);
|
|
187
|
+
}
|
|
188
|
+
if (this.#configuration.resultAttribute) context.setAttribute(this.#configuration.resultAttribute, result);
|
|
189
|
+
return routeBranch(this.#targets, this.#optional, result, this.#identity, "query");
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
var MutationStep = class {
|
|
193
|
+
inputCodec;
|
|
194
|
+
#configuration;
|
|
195
|
+
#options;
|
|
196
|
+
#ui;
|
|
197
|
+
#targets;
|
|
198
|
+
#optional;
|
|
199
|
+
#identity;
|
|
200
|
+
/** Validate static wiring before registering the Step in a Flow. */
|
|
201
|
+
constructor(configuration) {
|
|
202
|
+
if (!configuration?.operation) throw new TypeError("mutation operation is required");
|
|
203
|
+
const definition = configuration.operation.definition();
|
|
204
|
+
validateMutationDefinition(definition);
|
|
205
|
+
validateFactoryConfiguration(configuration);
|
|
206
|
+
const routes = validateBranchTargets(definition.branches, configuration.branches);
|
|
207
|
+
this.#configuration = configuration;
|
|
208
|
+
this.#options = mergeStepOptions(definition.stepDefaults, configuration.stepOptionsOverride);
|
|
209
|
+
this.#ui = ConnectorConfigurationUISchema.parse(configuration.configurationUI ?? { units: [] });
|
|
210
|
+
this.#targets = routes.targets;
|
|
211
|
+
this.#optional = routes.optional;
|
|
212
|
+
this.#identity = { operation: definition.operation, connection: configuration.connection };
|
|
213
|
+
if (configuration.inputCodec) this.inputCodec = configuration.inputCodec;
|
|
214
|
+
}
|
|
215
|
+
/** Stable Dex Step type. */
|
|
216
|
+
getStepType() {
|
|
217
|
+
return this.#configuration.stepType;
|
|
218
|
+
}
|
|
219
|
+
/** Isolated Execute options, including connector retry defaults. */
|
|
220
|
+
getStepOptions() {
|
|
221
|
+
return cloneStepOptions(this.#options);
|
|
222
|
+
}
|
|
223
|
+
/** Group metadata for Connector Studio. */
|
|
224
|
+
annotations() {
|
|
225
|
+
return { ...this.#configuration.annotations };
|
|
226
|
+
}
|
|
227
|
+
/** Isolated connector UI composition. */
|
|
228
|
+
configurationUI() {
|
|
229
|
+
return structuredClone(this.#ui);
|
|
230
|
+
}
|
|
231
|
+
/** Invoke, persist the optional terminal Attribute, and route the selected branch. */
|
|
232
|
+
async execute(context, input) {
|
|
233
|
+
const operationInput = this.#configuration.mapToOperationInput(input);
|
|
234
|
+
const call = createCall(context, this.#identity.connection, this.#identity.operation, {
|
|
235
|
+
...this.#configuration.progressStream ? { progressStream: this.#configuration.progressStream } : {},
|
|
236
|
+
...this.#configuration.textStream ? { textStream: this.#configuration.textStream } : {},
|
|
237
|
+
...this.#configuration.textOptions ? { textOptions: this.#configuration.textOptions } : {}
|
|
238
|
+
});
|
|
239
|
+
let result;
|
|
240
|
+
try {
|
|
241
|
+
result = await runMutation(this.#configuration.operation, call, operationInput);
|
|
242
|
+
} catch (error) {
|
|
243
|
+
throwDexRetry(error);
|
|
244
|
+
}
|
|
245
|
+
if (this.#configuration.resultAttribute) context.setAttribute(this.#configuration.resultAttribute, result);
|
|
246
|
+
return routeBranch(this.#targets, this.#optional, result, this.#identity, "mutation");
|
|
247
|
+
}
|
|
248
|
+
};
|
|
249
|
+
function newQueryStep(configuration) {
|
|
250
|
+
return new QueryStep(configuration);
|
|
251
|
+
}
|
|
252
|
+
function newMutationStep(configuration) {
|
|
253
|
+
return new MutationStep(configuration);
|
|
254
|
+
}
|
|
255
|
+
function validateFactoryConfiguration(configuration) {
|
|
256
|
+
if (!configuration.stepType?.trim()) throw new TypeError("stable Step type is required");
|
|
257
|
+
if (!/^[a-z][a-z0-9-]*$/.test(configuration.annotations?.groupId ?? "") || !configuration.annotations.groupLabel?.trim() || !configuration.annotations.explanation?.trim()) throw new TypeError("Step group, group label, and explanation are required");
|
|
258
|
+
ConnectionRefSchema.parse(configuration.connection);
|
|
259
|
+
if (typeof configuration.mapToOperationInput !== "function") throw new TypeError("mapToOperationInput is required");
|
|
260
|
+
}
|
|
261
|
+
function validateBranchTargets(definitions, routes) {
|
|
262
|
+
const expected = new Map(definitions.map((branch) => [branch.id, branch]));
|
|
263
|
+
const targets = /* @__PURE__ */ new Map();
|
|
264
|
+
const optional = new Set(definitions.filter((branch) => branch.optional).map((branch) => branch.id));
|
|
265
|
+
for (const route of routes) {
|
|
266
|
+
if (!expected.has(route.branch)) throw new TypeError(`branch target ${route.branch} is not declared by the operation`);
|
|
267
|
+
if (!route.target) {
|
|
268
|
+
if (!optional.has(route.branch)) throw new TypeError(`branch target ${route.branch} must name a Step`);
|
|
269
|
+
continue;
|
|
270
|
+
}
|
|
271
|
+
if (route.target instanceof StepRef && !route.target.stepType.trim()) throw new TypeError(`branch target ${route.branch} must name a Step`);
|
|
272
|
+
if (typeof route.target === "object" && !(route.target instanceof StepRef) && !route.target.getStepType().trim()) throw new TypeError(`branch target ${route.branch} must name a Step`);
|
|
273
|
+
if (targets.has(route.branch)) throw new TypeError(`branch target ${route.branch} is duplicated`);
|
|
274
|
+
targets.set(route.branch, route.target);
|
|
275
|
+
}
|
|
276
|
+
for (const branch of definitions) if (!branch.optional && !targets.has(branch.id)) throw new TypeError(`branch target ${branch.id} is required`);
|
|
277
|
+
return { targets, optional };
|
|
278
|
+
}
|
|
279
|
+
function mergeStepOptions(defaults, override) {
|
|
280
|
+
if (override && Object.keys(override).some((key) => key.startsWith("waitFor") && override[key] !== void 0)) throw new TypeError("execute-only connector Step rejects WaitFor options");
|
|
281
|
+
const merged = {
|
|
282
|
+
...override?.executeMethodTimeoutMs || defaults.executeMethodTimeoutMs ? { executeMethodTimeoutMs: override?.executeMethodTimeoutMs || defaults.executeMethodTimeoutMs } : {},
|
|
283
|
+
...override?.heartbeatTimeoutMs || defaults.heartbeatTimeoutMs ? { heartbeatTimeoutMs: override?.heartbeatTimeoutMs || defaults.heartbeatTimeoutMs } : {},
|
|
284
|
+
executeRetry: { ...override?.executeRetry ?? defaults.executeRetry ?? defaultConnectorStepExecuteRetryPolicy() },
|
|
285
|
+
...override?.executeDurability || (defaults.executeDurability !== "default" ? defaults.executeDurability : void 0) ? { executeDurability: override?.executeDurability ?? defaults.executeDurability } : {},
|
|
286
|
+
...override?.executeFailure ? { executeFailure: override.executeFailure } : {},
|
|
287
|
+
...override?.executeLockAttributes ? { executeLockAttributes: override.executeLockAttributes } : {},
|
|
288
|
+
...override?.executeLoadAttributeMaps ? { executeLoadAttributeMaps: override.executeLoadAttributeMaps } : {},
|
|
289
|
+
...override?.executeLoadAttributeMapInstances ? { executeLoadAttributeMapInstances: override.executeLoadAttributeMapInstances } : {},
|
|
290
|
+
...override?.executeLoadChannels ? { executeLoadChannels: override.executeLoadChannels } : {},
|
|
291
|
+
...override?.executeLoadChannelMaps ? { executeLoadChannelMaps: override.executeLoadChannelMaps } : {},
|
|
292
|
+
...override?.executeLoadChannelMapInstances ? { executeLoadChannelMapInstances: override.executeLoadChannelMapInstances } : {}
|
|
293
|
+
};
|
|
294
|
+
return cloneStepOptions(merged);
|
|
295
|
+
}
|
|
296
|
+
function cloneStepOptions(options) {
|
|
297
|
+
return {
|
|
298
|
+
...options,
|
|
299
|
+
...options.executeRetry ? { executeRetry: { ...options.executeRetry } } : {},
|
|
300
|
+
...options.executeLockAttributes ? { executeLockAttributes: [...options.executeLockAttributes] } : {},
|
|
301
|
+
...options.executeLoadAttributeMaps ? { executeLoadAttributeMaps: [...options.executeLoadAttributeMaps] } : {},
|
|
302
|
+
...options.executeLoadAttributeMapInstances ? { executeLoadAttributeMapInstances: [...options.executeLoadAttributeMapInstances] } : {},
|
|
303
|
+
...options.executeLoadChannels ? { executeLoadChannels: [...options.executeLoadChannels] } : {},
|
|
304
|
+
...options.executeLoadChannelMaps ? { executeLoadChannelMaps: [...options.executeLoadChannelMaps] } : {},
|
|
305
|
+
...options.executeLoadChannelMapInstances ? { executeLoadChannelMapInstances: [...options.executeLoadChannelMapInstances] } : {}
|
|
306
|
+
};
|
|
307
|
+
}
|
|
308
|
+
function routeBranch(targets, optional, result, identity, operationKind) {
|
|
309
|
+
const target = targets.get(result.branch);
|
|
310
|
+
if (target) return goTo(target, result);
|
|
311
|
+
if (optional.has(result.branch)) {
|
|
312
|
+
let reason = `${identity.operation.connectorId} ${identity.operation.operationId} (connection ${identity.connection.name}) selected branch ${result.branch} with no target`;
|
|
313
|
+
if (result.failure) reason += `: ${result.failure.kind}: ${boundedFailureMessage(result.failure.message)}`;
|
|
314
|
+
return forceFail(reason);
|
|
315
|
+
}
|
|
316
|
+
throw new TypeError(`${operationKind} result selected unconfigured branch ${result.branch}`);
|
|
317
|
+
}
|
|
318
|
+
function boundedFailureMessage(message) {
|
|
319
|
+
const bytes = Buffer.from(message);
|
|
320
|
+
if (bytes.length <= 1024) return message;
|
|
321
|
+
let end = 1024;
|
|
322
|
+
while (end > 0 && (bytes[end] & 192) === 128) end--;
|
|
323
|
+
return `${bytes.subarray(0, end).toString("utf8")} (truncated)`;
|
|
324
|
+
}
|
|
325
|
+
function throwDexRetry(error) {
|
|
326
|
+
if (error instanceof RetryError && error.retryAfterMs >= 1e3) throw retryAfter(Math.floor(error.retryAfterMs / 1e3), error);
|
|
327
|
+
throw error;
|
|
328
|
+
}
|
|
329
|
+
export {
|
|
330
|
+
BranchDefinitionSchema,
|
|
331
|
+
CallIDNamespace,
|
|
332
|
+
CallIDSchema,
|
|
333
|
+
ConnectionRefSchema,
|
|
334
|
+
ConnectorConfigurationRefSchema,
|
|
335
|
+
ConnectorConfigurationUISchema,
|
|
336
|
+
ConnectorUIBindingSchema,
|
|
337
|
+
ConnectorUIUnitSchema,
|
|
338
|
+
DefectBranchID,
|
|
339
|
+
FailureKindSchema,
|
|
340
|
+
FailureSchema,
|
|
341
|
+
MutationDefinitionWireSchema,
|
|
342
|
+
MutationResultSchema,
|
|
343
|
+
MutationStep,
|
|
344
|
+
OperationRefSchema,
|
|
345
|
+
QueryDefinitionWireSchema,
|
|
346
|
+
QueryResultSchema,
|
|
347
|
+
QueryStep,
|
|
348
|
+
ReauthorizationRequiredError,
|
|
349
|
+
ReceiptSchema,
|
|
350
|
+
RetryError,
|
|
351
|
+
SecretString,
|
|
352
|
+
StaticCredentialProvider,
|
|
353
|
+
StepDefaultsWireSchema,
|
|
354
|
+
UncertainBranchID,
|
|
355
|
+
createCall,
|
|
356
|
+
defaultConnectorStepExecuteRetryPolicy,
|
|
357
|
+
defaultIdempotencyKey,
|
|
358
|
+
deriveCallID,
|
|
359
|
+
goToBranch,
|
|
360
|
+
newMutationBranch,
|
|
361
|
+
newMutationRetry,
|
|
362
|
+
newMutationStep,
|
|
363
|
+
newMutationUncertain,
|
|
364
|
+
newQueryBranch,
|
|
365
|
+
newQueryRetry,
|
|
366
|
+
newQueryStep,
|
|
367
|
+
resolveCredential,
|
|
368
|
+
resolveCredentialAfterRejection,
|
|
369
|
+
retryPolicyToGoWire,
|
|
370
|
+
runMutation,
|
|
371
|
+
runQuery,
|
|
372
|
+
stepRef,
|
|
373
|
+
validateMutationDefinition,
|
|
374
|
+
validateQueryDefinition,
|
|
375
|
+
zeroReceipt
|
|
376
|
+
};
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
import { KeyObject } from 'node:crypto';
|
|
2
|
+
import { _ as SecretString } from '../credentials-vrvW0d4j.js';
|
|
3
|
+
import 'zod';
|
|
4
|
+
import '@superdurable/dex';
|
|
5
|
+
|
|
6
|
+
/** Longest early-refresh window in milliseconds. */
|
|
7
|
+
declare const RefreshSkewMs = 300000;
|
|
8
|
+
/** OAuth token endpoint client authentication. */
|
|
9
|
+
type ClientAuthenticationMethod = 'client_secret_post' | 'client_secret_basic' | 'none';
|
|
10
|
+
/** OAuth client material kept outside durable Flow state. */
|
|
11
|
+
interface ClientCredentials {
|
|
12
|
+
/** Public client identifier. */ id: string;
|
|
13
|
+
/** Client secret, omitted for a public client. */ secret?: SecretString;
|
|
14
|
+
/** RFC 7591 token endpoint authentication method. */ authenticationMethod: ClientAuthenticationMethod;
|
|
15
|
+
}
|
|
16
|
+
/** Successful replacement material from one OAuth grant. */
|
|
17
|
+
declare class TokenResponse {
|
|
18
|
+
/** Replacement access token. */ readonly accessToken: SecretString;
|
|
19
|
+
/** Rotated refresh token, empty when the provider retained it. */ readonly refreshToken: SecretString;
|
|
20
|
+
/** Access lifetime in milliseconds; zero only when explicitly accepted. */ readonly expiresInMs: number;
|
|
21
|
+
/** Refresh token lifetime in milliseconds; zero when omitted. */ readonly refreshTokenExpiresInMs: number;
|
|
22
|
+
/** Returned scope string, possibly empty. */ readonly scope: string;
|
|
23
|
+
/** Returned token type, possibly empty when explicitly accepted. */ readonly tokenType: string;
|
|
24
|
+
/** Only explicitly retained non-standard response fields. */ readonly retainedFields: Readonly<Record<string, unknown>>;
|
|
25
|
+
/** Capture validated provider response fields. */
|
|
26
|
+
constructor(fields: {
|
|
27
|
+
accessToken: SecretString;
|
|
28
|
+
refreshToken: SecretString;
|
|
29
|
+
expiresInMs: number;
|
|
30
|
+
refreshTokenExpiresInMs: number;
|
|
31
|
+
scope: string;
|
|
32
|
+
tokenType: string;
|
|
33
|
+
retainedFields: Record<string, unknown>;
|
|
34
|
+
});
|
|
35
|
+
/** Keep the previous refresh token when no rotated value was returned. */
|
|
36
|
+
nextRefreshToken(prior: SecretString): SecretString;
|
|
37
|
+
}
|
|
38
|
+
/** One provider token endpoint and its declared response rules. */
|
|
39
|
+
interface TokenEndpointOptions {
|
|
40
|
+
/** Safe provider name used in errors. */ providerName: string;
|
|
41
|
+
/** Absolute HTTPS URL, or HTTP only when explicitly allowed. */ url: string;
|
|
42
|
+
/** Provider error codes that require interactive reauthorization below HTTP 500. */ terminalErrorCodes?: readonly string[];
|
|
43
|
+
/** Accepted token types, case insensitive; defaults to Bearer. */ acceptedTokenTypes?: readonly string[];
|
|
44
|
+
/** Accept a successful response without token_type. */ acceptsMissingTokenType?: boolean;
|
|
45
|
+
/** Accept a successful response without expires_in. */ acceptsMissingExpiresIn?: boolean;
|
|
46
|
+
/** Non-standard, non-secret top-level fields to retain. */ retainedResponseFields?: readonly string[];
|
|
47
|
+
/** Send JSON instead of form encoding when the provider requires it. */ usesJSONRequestBody?: boolean;
|
|
48
|
+
/** Permit a declared HTTP endpoint, including private-network identity servers. */ allowsPlainHTTP?: boolean;
|
|
49
|
+
/** Fixed non-secret grant parameters that cannot override OAuth grant fields. */ additionalRequestParameters?: Readonly<Record<string, string>>;
|
|
50
|
+
/** Caller-owned fetch implementation for a proxy or local test. */ fetch?: typeof fetch;
|
|
51
|
+
}
|
|
52
|
+
/** Provider-neutral OAuth refresh and client-credentials exchanges. */
|
|
53
|
+
declare class TokenEndpoint {
|
|
54
|
+
#private;
|
|
55
|
+
/** Capture endpoint rules without sending a request. */
|
|
56
|
+
constructor(options: TokenEndpointOptions);
|
|
57
|
+
/** Exchange a refresh token, preserving terminal-error classification. */
|
|
58
|
+
exchangeRefreshToken(client: ClientCredentials, refreshToken: SecretString, signal?: AbortSignal): Promise<TokenResponse>;
|
|
59
|
+
/** Obtain an access token with the OAuth client-credentials grant. */
|
|
60
|
+
exchangeClientCredentials(client: ClientCredentials, scopes?: readonly string[], signal?: AbortSignal): Promise<TokenResponse>;
|
|
61
|
+
/** Exchange a signed JWT bearer assertion without client credentials. */
|
|
62
|
+
exchangeJWTBearerAssertion(assertion: SecretString, signal?: AbortSignal): Promise<TokenResponse>;
|
|
63
|
+
}
|
|
64
|
+
/** Return min(five minutes, one quarter of a known positive token lifetime). */
|
|
65
|
+
declare function proportionalRefreshSkewMs(issuedAt?: Date, expiresAt?: Date): number;
|
|
66
|
+
/** Return min(one minute, one quarter of a known positive token lifetime). */
|
|
67
|
+
declare function forcedRefreshFloorMs(issuedAt?: Date, expiresAt?: Date): number;
|
|
68
|
+
/** Decide whether an absent or soon-expiring access token needs refresh. */
|
|
69
|
+
declare function isRefreshRequired(hasAccessToken: boolean, expiresAt: Date | undefined, now: Date, missingExpiryRule: 'refresh' | 'keep', issuedAt?: Date): boolean;
|
|
70
|
+
/** Decide with issue time so short-lived tokens use proportional skew. */
|
|
71
|
+
declare function isRefreshRequiredWithIssueTime(hasAccessToken: boolean, issuedAt: Date | undefined, expiresAt: Date | undefined, now: Date, missingExpiryRule: 'refresh' | 'keep'): boolean;
|
|
72
|
+
/** Check whether all required scopes appear in a returned space- or comma-separated set. */
|
|
73
|
+
declare function hasAllScopes(returnedScope: string, requiredScopes: readonly string[]): boolean;
|
|
74
|
+
/** Check set equality of returned and required scopes. */
|
|
75
|
+
declare function hasExactScopes(returnedScope: string, requiredScopes: readonly string[]): boolean;
|
|
76
|
+
/** Claims of an RS256 JWT bearer assertion. */
|
|
77
|
+
interface JWTBearerAssertion {
|
|
78
|
+
/** iss claim. */ issuer: string;
|
|
79
|
+
/** Optional sub claim. */ subject?: string;
|
|
80
|
+
/** aud claim, usually the token URL. */ audience: string;
|
|
81
|
+
/** Optional scope claim. */ scope?: string;
|
|
82
|
+
/** iat claim. */ issuedAt: Date;
|
|
83
|
+
/** Positive lifetime in milliseconds. */ lifetimeMs: number;
|
|
84
|
+
}
|
|
85
|
+
/** Parse a PKCS #1 or PKCS #8 RSA PEM key without exposing key material in errors. */
|
|
86
|
+
declare function parseRSAPrivateKeyPEM(pemText: string): KeyObject;
|
|
87
|
+
/** Sign a JWT bearer grant assertion with RS256. */
|
|
88
|
+
declare function signJWTBearerAssertion(assertion: JWTBearerAssertion, privateKey: KeyObject): SecretString;
|
|
89
|
+
|
|
90
|
+
export { type ClientAuthenticationMethod, type ClientCredentials, type JWTBearerAssertion, RefreshSkewMs, TokenEndpoint, type TokenEndpointOptions, TokenResponse, forcedRefreshFloorMs, hasAllScopes, hasExactScopes, isRefreshRequired, isRefreshRequiredWithIssueTime, parseRSAPrivateKeyPEM, proportionalRefreshSkewMs, signJWTBearerAssertion };
|