@siglo/http 0.0.0-stage → 1.0.0

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 (43) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +38 -2
  3. package/dist/client/fetch.d.ts +46 -0
  4. package/dist/client/fetch.d.ts.map +1 -0
  5. package/dist/client/fetch.js +330 -0
  6. package/dist/client/fetch.js.map +1 -0
  7. package/dist/client/retry.d.ts +30 -0
  8. package/dist/client/retry.d.ts.map +1 -0
  9. package/dist/client/retry.js +82 -0
  10. package/dist/client/retry.js.map +1 -0
  11. package/dist/client/trace.d.ts +23 -0
  12. package/dist/client/trace.d.ts.map +1 -0
  13. package/dist/client/trace.js +103 -0
  14. package/dist/client/trace.js.map +1 -0
  15. package/dist/index.d.ts +10 -0
  16. package/dist/index.d.ts.map +1 -0
  17. package/dist/index.js +28 -0
  18. package/dist/index.js.map +1 -0
  19. package/dist/policy/asl-bridge.d.ts +21 -0
  20. package/dist/policy/asl-bridge.d.ts.map +1 -0
  21. package/dist/policy/asl-bridge.js +82 -0
  22. package/dist/policy/asl-bridge.js.map +1 -0
  23. package/dist/schema/validator.d.ts +14 -0
  24. package/dist/schema/validator.d.ts.map +1 -0
  25. package/dist/schema/validator.js +154 -0
  26. package/dist/schema/validator.js.map +1 -0
  27. package/dist/step.d.ts +15 -0
  28. package/dist/step.d.ts.map +1 -0
  29. package/dist/step.js +165 -0
  30. package/dist/step.js.map +1 -0
  31. package/dist/testing/index.d.ts +2 -0
  32. package/dist/testing/index.d.ts.map +1 -0
  33. package/dist/testing/index.js +18 -0
  34. package/dist/testing/index.js.map +1 -0
  35. package/dist/testing/mock-agent.d.ts +64 -0
  36. package/dist/testing/mock-agent.d.ts.map +1 -0
  37. package/dist/testing/mock-agent.js +233 -0
  38. package/dist/testing/mock-agent.js.map +1 -0
  39. package/dist/types.d.ts +60 -0
  40. package/dist/types.d.ts.map +1 -0
  41. package/dist/types.js +3 -0
  42. package/dist/types.js.map +1 -0
  43. package/package.json +60 -4
@@ -0,0 +1,103 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.injectTraceHeaders = injectTraceHeaders;
4
+ exports.recordRequestSpanAttributes = recordRequestSpanAttributes;
5
+ exports.recordResponseSpanAttributes = recordResponseSpanAttributes;
6
+ exports.getActiveTraceId = getActiveTraceId;
7
+ const api_1 = require("@opentelemetry/api");
8
+ /**
9
+ * Injects W3C distributed trace context (traceparent and tracestate) into request headers
10
+ * from the active OpenTelemetry span and context.
11
+ */
12
+ function injectTraceHeaders(carrier = {}, customSpan) {
13
+ const activeCtx = api_1.context.active();
14
+ try {
15
+ api_1.propagation.inject(activeCtx, carrier, api_1.defaultTextMapSetter);
16
+ }
17
+ catch {
18
+ // If propagation fails, continue to spanContext fallback
19
+ }
20
+ const targetSpan = customSpan || api_1.trace.getActiveSpan();
21
+ if (targetSpan) {
22
+ try {
23
+ const spanCtx = typeof targetSpan.spanContext === 'function'
24
+ ? targetSpan.spanContext()
25
+ : targetSpan.spanContext;
26
+ if (spanCtx && spanCtx.traceId && !carrier['traceparent']) {
27
+ const flags = (spanCtx.traceFlags ?? 0).toString(16).padStart(2, '0');
28
+ const spanId = spanCtx.spanId || '0000000000000000';
29
+ carrier['traceparent'] = `00-${spanCtx.traceId}-${spanId}-${flags}`;
30
+ if (spanCtx.traceState) {
31
+ carrier['tracestate'] =
32
+ typeof spanCtx.traceState.serialize === 'function'
33
+ ? spanCtx.traceState.serialize()
34
+ : String(spanCtx.traceState);
35
+ }
36
+ }
37
+ }
38
+ catch {
39
+ // Ignore span context extraction error
40
+ }
41
+ }
42
+ return carrier;
43
+ }
44
+ /**
45
+ * Attaches standard HTTP semantic convention attributes to the active OpenTelemetry span.
46
+ */
47
+ function recordRequestSpanAttributes(method, url, serverAddress, customSpan) {
48
+ const activeSpan = customSpan || api_1.trace.getActiveSpan();
49
+ if (activeSpan && typeof activeSpan.setAttribute === 'function') {
50
+ try {
51
+ activeSpan.setAttribute('http.request.method', method.toUpperCase());
52
+ activeSpan.setAttribute('url.full', url);
53
+ activeSpan.setAttribute('server.address', serverAddress);
54
+ }
55
+ catch {
56
+ // Ignore attribute recording errors
57
+ }
58
+ }
59
+ }
60
+ /**
61
+ * Attaches standard response semantic convention attributes to the active OpenTelemetry span.
62
+ */
63
+ function recordResponseSpanAttributes(statusCode, customSpan) {
64
+ const activeSpan = customSpan || api_1.trace.getActiveSpan();
65
+ if (activeSpan && typeof activeSpan.setAttribute === 'function') {
66
+ try {
67
+ activeSpan.setAttribute('http.response.status_code', statusCode);
68
+ if (statusCode >= 400 && typeof activeSpan.setStatus === 'function') {
69
+ activeSpan.setStatus({
70
+ code: api_1.SpanStatusCode.ERROR,
71
+ message: `HTTP error status ${statusCode}`
72
+ });
73
+ }
74
+ }
75
+ catch {
76
+ // Ignore attribute recording errors
77
+ }
78
+ }
79
+ }
80
+ /**
81
+ * Extracts current active traceId if present.
82
+ */
83
+ function getActiveTraceId(customSpan) {
84
+ const activeSpan = customSpan || api_1.trace.getActiveSpan();
85
+ if (activeSpan) {
86
+ try {
87
+ if (typeof activeSpan.spanContext === 'function') {
88
+ return activeSpan.spanContext()?.traceId;
89
+ }
90
+ if (activeSpan.spanContext && typeof activeSpan.spanContext === 'object') {
91
+ return activeSpan.spanContext.traceId;
92
+ }
93
+ if (activeSpan.traceId) {
94
+ return activeSpan.traceId;
95
+ }
96
+ }
97
+ catch {
98
+ return undefined;
99
+ }
100
+ }
101
+ return undefined;
102
+ }
103
+ //# sourceMappingURL=trace.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trace.js","sourceRoot":"","sources":["../../src/client/trace.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import { httpStep, HttpStep } from './step';
2
+ export { httpStep, HttpStep };
3
+ export default httpStep;
4
+ export * from './types';
5
+ export * from './client/retry';
6
+ export * from './client/trace';
7
+ export * from './client/fetch';
8
+ export * from './policy/asl-bridge';
9
+ export * from './schema/validator';
10
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,QAAQ,CAAC;AAE5C,OAAO,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;AAC9B,eAAe,QAAQ,CAAC;AAExB,cAAc,SAAS,CAAC;AACxB,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,gBAAgB,CAAC;AAC/B,cAAc,qBAAqB,CAAC;AACpC,cAAc,oBAAoB,CAAC"}
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __exportStar = (this && this.__exportStar) || function(m, exports) {
14
+ for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
15
+ };
16
+ Object.defineProperty(exports, "__esModule", { value: true });
17
+ exports.HttpStep = exports.httpStep = void 0;
18
+ const step_1 = require("./step");
19
+ Object.defineProperty(exports, "httpStep", { enumerable: true, get: function () { return step_1.httpStep; } });
20
+ Object.defineProperty(exports, "HttpStep", { enumerable: true, get: function () { return step_1.HttpStep; } });
21
+ exports.default = step_1.httpStep;
22
+ __exportStar(require("./types"), exports);
23
+ __exportStar(require("./client/retry"), exports);
24
+ __exportStar(require("./client/trace"), exports);
25
+ __exportStar(require("./client/fetch"), exports);
26
+ __exportStar(require("./policy/asl-bridge"), exports);
27
+ __exportStar(require("./schema/validator"), exports);
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;AAAA,iCAA4C;AAEnC,yFAFA,eAAQ,OAEA;AAAE,yFAFA,eAAQ,OAEA;AAC3B,kBAAe,eAAQ,CAAC;AAExB,0CAAwB;AACxB,iDAA+B;AAC/B,iDAA+B;AAC/B,iDAA+B;AAC/B,sDAAoC;AACpC,qDAAmC"}
@@ -0,0 +1,21 @@
1
+ export interface HostInfo {
2
+ hostname: string;
3
+ host: string;
4
+ port?: string;
5
+ }
6
+ /**
7
+ * Safely parses the destination hostname, host with port, and port from a target URL string.
8
+ */
9
+ export declare function extractHostInfo(targetUrl: string): HostInfo;
10
+ /**
11
+ * Verifies that the resolved URL's hostname is permitted by the active AsyncLocalStorage
12
+ * network egress perimeter policy.
13
+ *
14
+ * If blocked, throws a non-retryable NetworkPolicyViolationException tagged with `phase: 'before'`.
15
+ */
16
+ export declare function assertNetworkPolicy(stepName: string, resolvedUrl: string, host: string, port?: string | number, fallbackPolicy?: any): void;
17
+ /**
18
+ * Extracts a static hostname from a URL option if it is provided as a static string.
19
+ */
20
+ export declare function extractStaticHostname(urlOption: unknown): string | undefined;
21
+ //# sourceMappingURL=asl-bridge.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asl-bridge.d.ts","sourceRoot":"","sources":["../../src/policy/asl-bridge.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,QAAQ;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf;AAED;;GAEG;AACH,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,QAAQ,CA2B3D;AAED;;;;;GAKG;AACH,wBAAgB,mBAAmB,CACjC,QAAQ,EAAE,MAAM,EAChB,WAAW,EAAE,MAAM,EACnB,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,MAAM,GAAG,MAAM,EACtB,cAAc,CAAC,EAAE,GAAG,GACnB,IAAI,CA4BN;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAU5E"}
@@ -0,0 +1,82 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.extractHostInfo = extractHostInfo;
4
+ exports.assertNetworkPolicy = assertNetworkPolicy;
5
+ exports.extractStaticHostname = extractStaticHostname;
6
+ const core_1 = require("@siglo/core");
7
+ /**
8
+ * Safely parses the destination hostname, host with port, and port from a target URL string.
9
+ */
10
+ function extractHostInfo(targetUrl) {
11
+ try {
12
+ const urlToParse = targetUrl.includes('://') ? targetUrl : `http://${targetUrl}`;
13
+ const parsed = new URL(urlToParse);
14
+ return {
15
+ hostname: parsed.hostname,
16
+ host: parsed.host,
17
+ port: parsed.port || undefined
18
+ };
19
+ }
20
+ catch {
21
+ // Fallback if URL constructor still fails on malformed input
22
+ const withoutProto = targetUrl.replace(/^[a-z]+:\/\//, '');
23
+ const slashIdx = withoutProto.indexOf('/');
24
+ const hostPart = slashIdx !== -1 ? withoutProto.slice(0, slashIdx) : withoutProto;
25
+ const colonIdx = hostPart.lastIndexOf(':');
26
+ if (colonIdx !== -1) {
27
+ return {
28
+ hostname: hostPart.slice(0, colonIdx),
29
+ host: hostPart,
30
+ port: hostPart.slice(colonIdx + 1)
31
+ };
32
+ }
33
+ return {
34
+ hostname: hostPart,
35
+ host: hostPart
36
+ };
37
+ }
38
+ }
39
+ /**
40
+ * Verifies that the resolved URL's hostname is permitted by the active AsyncLocalStorage
41
+ * network egress perimeter policy.
42
+ *
43
+ * If blocked, throws a non-retryable NetworkPolicyViolationException tagged with `phase: 'before'`.
44
+ */
45
+ function assertNetworkPolicy(stepName, resolvedUrl, host, port, fallbackPolicy) {
46
+ const activeStore = core_1.networkPolicyStorage.getStore() || fallbackPolicy;
47
+ if (!activeStore || activeStore.enabled === false) {
48
+ return;
49
+ }
50
+ const allowed = (0, core_1.isHostAllowed)(resolvedUrl, host, activeStore, port);
51
+ if (!allowed) {
52
+ const allowedHosts = activeStore.allowedHosts || [];
53
+ const exception = new core_1.NetworkPolicyViolationException(stepName, resolvedUrl, host, allowedHosts, {
54
+ phase: 'before',
55
+ retryable: false
56
+ });
57
+ // Explicitly guarantee phase: 'before' and retryable: false as specified in roadmap
58
+ Object.defineProperty(exception, 'phase', {
59
+ get: () => 'before',
60
+ set: () => { },
61
+ configurable: true
62
+ });
63
+ exception.retryable = false;
64
+ throw exception;
65
+ }
66
+ }
67
+ /**
68
+ * Extracts a static hostname from a URL option if it is provided as a static string.
69
+ */
70
+ function extractStaticHostname(urlOption) {
71
+ if (typeof urlOption !== 'string') {
72
+ return undefined;
73
+ }
74
+ try {
75
+ const parsed = new URL(urlOption);
76
+ return parsed.hostname;
77
+ }
78
+ catch {
79
+ return undefined;
80
+ }
81
+ }
82
+ //# sourceMappingURL=asl-bridge.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"asl-bridge.js","sourceRoot":"","sources":["../../src/policy/asl-bridge.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,14 @@
1
+ import { ValidationErrorDetail } from '@siglo/core';
2
+ export interface ValidationResult<T = any> {
3
+ success: boolean;
4
+ data?: T;
5
+ errors?: ValidationErrorDetail[];
6
+ }
7
+ /**
8
+ * Validates a payload against a Standard Schema (~standard), Zod, Valibot, ArkType,
9
+ * or standard parsing validator.
10
+ *
11
+ * If validation fails, throws a Siglo ValidationException tagged with the provided phase.
12
+ */
13
+ export declare function validatePayload<T = any>(schema: any, data: unknown, phase: 'validation' | 'action', stepName?: string): Promise<T>;
14
+ //# sourceMappingURL=validator.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.d.ts","sourceRoot":"","sources":["../../src/schema/validator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAuB,qBAAqB,EAAE,MAAM,aAAa,CAAC;AAEzE,MAAM,WAAW,gBAAgB,CAAC,CAAC,GAAG,GAAG;IACvC,OAAO,EAAE,OAAO,CAAC;IACjB,IAAI,CAAC,EAAE,CAAC,CAAC;IACT,MAAM,CAAC,EAAE,qBAAqB,EAAE,CAAC;CAClC;AAED;;;;;GAKG;AACH,wBAAsB,eAAe,CAAC,CAAC,GAAG,GAAG,EAC3C,MAAM,EAAE,GAAG,EACX,IAAI,EAAE,OAAO,EACb,KAAK,EAAE,YAAY,GAAG,QAAQ,EAC9B,QAAQ,CAAC,EAAE,MAAM,GAChB,OAAO,CAAC,CAAC,CAAC,CAwJZ"}
@@ -0,0 +1,154 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.validatePayload = validatePayload;
4
+ const core_1 = require("@siglo/core");
5
+ /**
6
+ * Validates a payload against a Standard Schema (~standard), Zod, Valibot, ArkType,
7
+ * or standard parsing validator.
8
+ *
9
+ * If validation fails, throws a Siglo ValidationException tagged with the provided phase.
10
+ */
11
+ async function validatePayload(schema, data, phase, stepName) {
12
+ if (!schema) {
13
+ return data;
14
+ }
15
+ // 1. Standard Schema specification (~standard v1)
16
+ if (typeof schema === 'object' && schema !== null && schema['~standard']) {
17
+ const standard = schema['~standard'];
18
+ const result = await standard.validate(data);
19
+ if (result && result.issues) {
20
+ const details = result.issues.map((issue) => ({
21
+ field: issue.path && issue.path.length > 0
22
+ ? issue.path.map((segment) => String(typeof segment === 'object' && segment !== null ? segment.key : segment)).join('.')
23
+ : '$root$',
24
+ message: issue.message || 'Validation failed',
25
+ error: issue
26
+ }));
27
+ const exception = new core_1.ValidationException(details, { phase, stepName, retryable: false });
28
+ Object.defineProperty(exception, 'phase', {
29
+ get: () => phase,
30
+ set: () => { },
31
+ configurable: true
32
+ });
33
+ throw exception;
34
+ }
35
+ if (!result || !('value' in result)) {
36
+ throw new TypeError('Standard Schema validator must return value or issues');
37
+ }
38
+ return result.value;
39
+ }
40
+ // 2. safeParse (Zod, Valibot, etc.)
41
+ if (typeof schema.safeParse === 'function') {
42
+ const result = await schema.safeParse(data);
43
+ if (!result.success) {
44
+ const issues = result.error?.issues;
45
+ const details = Array.isArray(issues) && issues.length > 0
46
+ ? issues.map((i) => ({
47
+ field: i.path && i.path.length > 0 ? i.path.join('.') : '$root$',
48
+ message: i.message || 'Validation failed',
49
+ error: i
50
+ }))
51
+ : [
52
+ {
53
+ field: '$root$',
54
+ message: result.error?.message || 'Schema validation failed',
55
+ error: result.error
56
+ }
57
+ ];
58
+ const exception = new core_1.ValidationException(details, { phase, stepName, retryable: false });
59
+ Object.defineProperty(exception, 'phase', {
60
+ get: () => phase,
61
+ set: () => { },
62
+ configurable: true
63
+ });
64
+ throw exception;
65
+ }
66
+ return result.data;
67
+ }
68
+ // 3. parse() method (Zod synchronous/asynchronous parser)
69
+ if (typeof schema.parse === 'function') {
70
+ try {
71
+ const parsed = await schema.parse(data);
72
+ return (parsed !== undefined ? parsed : data);
73
+ }
74
+ catch (err) {
75
+ const issues = err?.issues;
76
+ const details = Array.isArray(issues) && issues.length > 0
77
+ ? issues.map((i) => ({
78
+ field: i.path && i.path.length > 0 ? i.path.join('.') : '$root$',
79
+ message: i.message || 'Validation failed',
80
+ error: i
81
+ }))
82
+ : [
83
+ {
84
+ field: '$root$',
85
+ message: err?.message || 'Schema validation failed',
86
+ error: err
87
+ }
88
+ ];
89
+ const exception = new core_1.ValidationException(details, { phase, stepName, retryable: false });
90
+ Object.defineProperty(exception, 'phase', {
91
+ get: () => phase,
92
+ set: () => { },
93
+ configurable: true
94
+ });
95
+ throw exception;
96
+ }
97
+ }
98
+ // 4. validate() method (Joi, Yup, etc.)
99
+ if (typeof schema.validate === 'function') {
100
+ try {
101
+ const result = await schema.validate(data);
102
+ // Yup returns parsed data, Joi returns { error, value }
103
+ if (result && typeof result === 'object' && 'error' in result && result.error) {
104
+ const details = Array.isArray(result.error.details)
105
+ ? result.error.details.map((d) => ({
106
+ field: d.path ? (Array.isArray(d.path) ? d.path.join('.') : String(d.path)) : '$root$',
107
+ message: d.message || 'Validation failed',
108
+ error: d
109
+ }))
110
+ : [{ field: '$root$', message: result.error.message || 'Validation failed', error: result.error }];
111
+ const exception = new core_1.ValidationException(details, { phase, stepName, retryable: false });
112
+ Object.defineProperty(exception, 'phase', {
113
+ get: () => phase,
114
+ set: () => { },
115
+ configurable: true
116
+ });
117
+ throw exception;
118
+ }
119
+ return (result && 'value' in result ? result.value : result);
120
+ }
121
+ catch (err) {
122
+ if (err instanceof core_1.ValidationException)
123
+ throw err;
124
+ const exception = new core_1.ValidationException([{ field: '$root$', message: err?.message || 'Validation failed', error: err }], { phase, stepName, retryable: false });
125
+ Object.defineProperty(exception, 'phase', {
126
+ get: () => phase,
127
+ set: () => { },
128
+ configurable: true
129
+ });
130
+ throw exception;
131
+ }
132
+ }
133
+ // 5. Function validator (custom predicate / mapper)
134
+ if (typeof schema === 'function') {
135
+ try {
136
+ const result = await schema(data);
137
+ if (result === false) {
138
+ throw new Error('Custom validation function returned false');
139
+ }
140
+ return (result !== true && result !== undefined ? result : data);
141
+ }
142
+ catch (err) {
143
+ const exception = new core_1.ValidationException([{ field: '$root$', message: err?.message || 'Validation failed', error: err }], { phase, stepName, retryable: false });
144
+ Object.defineProperty(exception, 'phase', {
145
+ get: () => phase,
146
+ set: () => { },
147
+ configurable: true
148
+ });
149
+ throw exception;
150
+ }
151
+ }
152
+ return data;
153
+ }
154
+ //# sourceMappingURL=validator.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"validator.js","sourceRoot":"","sources":["../../src/schema/validator.ts"],"names":[],"mappings":"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"}
package/dist/step.d.ts ADDED
@@ -0,0 +1,15 @@
1
+ import { Step } from '@siglo/core';
2
+ import { HttpStepOptions, HttpStepResult, CompensationHttpConfig, HttpStepInstance } from './types';
3
+ export declare class HttpStep<TInput = any, TOutput = Record<string, any>, TName extends string = string> extends Step<TInput, HttpStepResult<TOutput>, TName> implements HttpStepInstance<TInput, TOutput, TName> {
4
+ private httpOptions;
5
+ constructor(name: TName, options: HttpStepOptions<TInput, TOutput>);
6
+ /**
7
+ * Declarative saga rollback compensation via HTTP request.
8
+ */
9
+ compensateWithHttp(config: CompensationHttpConfig<TInput, TOutput>): this;
10
+ }
11
+ /**
12
+ * Creates a resilient, W3C-traced HTTP client step for Siglo workflows.
13
+ */
14
+ export declare function httpStep<const TName extends string, TInput = any, TOutput = Record<string, any>>(name: TName, options: HttpStepOptions<TInput, TOutput>): HttpStep<TInput, TOutput, TName>;
15
+ //# sourceMappingURL=step.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"step.d.ts","sourceRoot":"","sources":["../src/step.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,IAAI,EAAsC,MAAM,aAAa,CAAC;AACvE,OAAO,EAEL,eAAe,EACf,cAAc,EACd,sBAAsB,EACtB,gBAAgB,EACjB,MAAM,SAAS,CAAC;AAKjB,qBAAa,QAAQ,CAAC,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAAE,KAAK,SAAS,MAAM,GAAG,MAAM,CAC9F,SAAQ,IAAI,CAAC,MAAM,EAAE,cAAc,CAAC,OAAO,CAAC,EAAE,KAAK,CACnD,YAAW,gBAAgB,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC;IAEnD,OAAO,CAAC,WAAW,CAAmC;gBAE1C,IAAI,EAAE,KAAK,EAAE,OAAO,EAAE,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC;IA4IlE;;OAEG;IACH,kBAAkB,CAAC,MAAM,EAAE,sBAAsB,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,IAAI;CA+B1E;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,CAAC,KAAK,SAAS,MAAM,EAAE,MAAM,GAAG,GAAG,EAAE,OAAO,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,EAC9F,IAAI,EAAE,KAAK,EACX,OAAO,EAAE,eAAe,CAAC,MAAM,EAAE,OAAO,CAAC,GACxC,QAAQ,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,CAAC,CAElC"}
package/dist/step.js ADDED
@@ -0,0 +1,165 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.HttpStep = void 0;
4
+ exports.httpStep = httpStep;
5
+ const core_1 = require("@siglo/core");
6
+ const asl_bridge_1 = require("./policy/asl-bridge");
7
+ const validator_1 = require("./schema/validator");
8
+ const fetch_1 = require("./client/fetch");
9
+ class HttpStep extends core_1.Step {
10
+ httpOptions;
11
+ constructor(name, options) {
12
+ const action = async (ctx) => {
13
+ // 1. Resolve parameters dynamically from context
14
+ const resolvedUrl = typeof options.url === 'function' ? options.url(ctx) : options.url;
15
+ const { hostname, port } = (0, asl_bridge_1.extractHostInfo)(resolvedUrl);
16
+ // Asserts hostname against active AsyncLocalStorage (ASL) network policy
17
+ (0, asl_bridge_1.assertNetworkPolicy)(name, resolvedUrl, hostname, port);
18
+ const resolvedHeaders = typeof options.headers === 'function' ? options.headers(ctx) : (options.headers || {});
19
+ const resolvedQuery = typeof options.query === 'function' ? options.query(ctx) : options.query;
20
+ const resolvedBody = typeof options.body === 'function' ? options.body(ctx) : options.body;
21
+ // 2. VALIDATION Phase: Validate outgoing request payload before touching the network
22
+ if (options.requestSchema && resolvedBody !== undefined) {
23
+ await (0, validator_1.validatePayload)(options.requestSchema, resolvedBody, 'validation', name);
24
+ }
25
+ // 3. ACTION Phase: Network Execution via executeHttpRequest
26
+ const res = await (0, fetch_1.executeHttpRequest)({
27
+ capture: options.capture,
28
+ stepName: name,
29
+ url: resolvedUrl,
30
+ method: options.method || 'GET',
31
+ headers: resolvedHeaders,
32
+ query: resolvedQuery,
33
+ body: resolvedBody,
34
+ responseType: options.responseType || 'json',
35
+ retryOnStatus: options.retryOnStatus,
36
+ maxRetries: options.maxRetries,
37
+ allowNotFound: options.allowNotFound,
38
+ timeoutMs: options.timeoutMs,
39
+ signal: ctx?.$signal || ctx?.signal,
40
+ span: ctx?.span || ctx?.$span,
41
+ clock: options.clock,
42
+ sleep: options.sleep
43
+ });
44
+ // Handle 404 when allowNotFound is true
45
+ if (res.notFound) {
46
+ const notFoundPayload = {
47
+ notFound: true,
48
+ data: null,
49
+ $httpMetadata: res.metadata,
50
+ httpMetadata: res.metadata
51
+ };
52
+ return notFoundPayload;
53
+ }
54
+ // 4. Validate incoming response payload if responseSchema is defined
55
+ let validatedData = res.data;
56
+ if (options.responseSchema) {
57
+ validatedData = await (0, validator_1.validatePayload)(options.responseSchema, res.data, 'action', name);
58
+ }
59
+ // 5. Attach $httpMetadata and construct return object
60
+ if (typeof validatedData === 'object' &&
61
+ validatedData !== null &&
62
+ !Array.isArray(validatedData) &&
63
+ typeof validatedData.then !== 'function' &&
64
+ !(typeof Blob !== 'undefined' && validatedData instanceof Blob) &&
65
+ !(typeof ArrayBuffer !== 'undefined' && validatedData instanceof ArrayBuffer)) {
66
+ return {
67
+ ...validatedData,
68
+ data: validatedData,
69
+ $httpMetadata: res.metadata,
70
+ httpMetadata: res.metadata
71
+ };
72
+ }
73
+ const wrappedResult = {
74
+ data: validatedData,
75
+ $httpMetadata: res.metadata,
76
+ httpMetadata: res.metadata
77
+ };
78
+ return wrappedResult;
79
+ };
80
+ super(name, ((ctx) => (0, core_1.observeEcosystem)({ version: 1, kind: 'http', outcome: 'failure',
81
+ method: options.method || 'GET', url: typeof options.url === 'string' ? options.url : undefined }, () => action(ctx), result => ({ ...result.$httpMetadata, policy: 'allowed' }))));
82
+ this.httpOptions = options;
83
+ // Static host assertion for graph inspection
84
+ const staticHost = (0, asl_bridge_1.extractStaticHostname)(options.url);
85
+ if (staticHost) {
86
+ this.allowNetwork([staticHost]);
87
+ }
88
+ // 1. BEFORE Phase: Validate ASL Network Egress Perimeter early
89
+ this.onBefore(async (ctx) => {
90
+ try {
91
+ const resolvedUrl = typeof options.url === 'function' ? options.url(ctx) : options.url;
92
+ const { hostname, port } = (0, asl_bridge_1.extractHostInfo)(resolvedUrl);
93
+ // Asserts hostname against active AsyncLocalStorage (ASL) network policy
94
+ (0, asl_bridge_1.assertNetworkPolicy)(name, resolvedUrl, hostname, port);
95
+ }
96
+ catch (error) {
97
+ (0, core_1.recordInspection)({ version: 1, kind: 'http', outcome: 'failure', method: options.method || 'GET',
98
+ url: typeof options.url === 'string' ? options.url : undefined,
99
+ policy: error?.name === 'NetworkPolicyViolationException' ? 'denied' : 'unknown' });
100
+ throw error;
101
+ }
102
+ return true;
103
+ });
104
+ // 4. AFTER Phase: Safely attach telemetry if context is extensible
105
+ this.onAfter(async (output, ctx) => {
106
+ try {
107
+ if (output && output.$httpMetadata && ctx && typeof ctx === 'object') {
108
+ if (!Object.isFrozen(ctx) && Object.isExtensible(ctx)) {
109
+ if (!ctx.$steps) {
110
+ ctx.$steps = {};
111
+ }
112
+ if (!ctx.$steps[name]) {
113
+ ctx.$steps[name] = {};
114
+ }
115
+ ctx.$steps[name].httpMetadata = output.$httpMetadata;
116
+ }
117
+ }
118
+ }
119
+ catch {
120
+ // Ignore if context is immutable or sealed
121
+ }
122
+ return output;
123
+ });
124
+ // 5. COMPENSATION Phase: Register declarative saga compensation if configured
125
+ if (options.compensate) {
126
+ this.compensateWithHttp(options.compensate);
127
+ }
128
+ }
129
+ /**
130
+ * Declarative saga rollback compensation via HTTP request.
131
+ */
132
+ compensateWithHttp(config) {
133
+ this.compensate(async (res, ctx) => {
134
+ const compUrl = typeof config.url === 'function' ? config.url(ctx, res) : config.url;
135
+ const compMethod = config.method || 'DELETE';
136
+ const compHeaders = typeof config.headers === 'function' ? config.headers(ctx, res) : (config.headers || {});
137
+ const compQuery = typeof config.query === 'function' ? config.query(ctx, res) : config.query;
138
+ const compBody = typeof config.body === 'function' ? config.body(ctx, res) : config.body;
139
+ // Verify ASL network policy for compensation endpoint
140
+ const { hostname, port } = (0, asl_bridge_1.extractHostInfo)(compUrl);
141
+ (0, asl_bridge_1.assertNetworkPolicy)(`${this.name}:compensate`, compUrl, hostname, port);
142
+ await (0, fetch_1.executeHttpRequest)({
143
+ stepName: `${this.name}:compensate`,
144
+ url: compUrl,
145
+ method: compMethod,
146
+ headers: compHeaders,
147
+ query: compQuery,
148
+ body: compBody,
149
+ clock: this.httpOptions.clock,
150
+ sleep: this.httpOptions.sleep,
151
+ retryOnStatus: this.httpOptions.retryOnStatus,
152
+ maxRetries: this.httpOptions.maxRetries
153
+ });
154
+ });
155
+ return this;
156
+ }
157
+ }
158
+ exports.HttpStep = HttpStep;
159
+ /**
160
+ * Creates a resilient, W3C-traced HTTP client step for Siglo workflows.
161
+ */
162
+ function httpStep(name, options) {
163
+ return new HttpStep(name, options);
164
+ }
165
+ //# sourceMappingURL=step.js.map