@livon/schema 0.27.0-rc.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/PROMPT.md +21 -0
- package/README.md +13 -0
- package/SCHEMA.md +13 -0
- package/dist/SchemaValidationError.cjs +41 -0
- package/dist/SchemaValidationError.d.ts +20 -0
- package/dist/SchemaValidationError.js +7 -0
- package/dist/SchemaValidationError.spec.cjs +65 -0
- package/dist/SchemaValidationError.spec.d.ts +1 -0
- package/dist/SchemaValidationError.spec.js +59 -0
- package/dist/after.cjs +36 -0
- package/dist/after.d.ts +30 -0
- package/dist/after.js +2 -0
- package/dist/after.spec.cjs +54 -0
- package/dist/after.spec.d.ts +1 -0
- package/dist/after.spec.js +48 -0
- package/dist/and.cjs +36 -0
- package/dist/and.d.ts +26 -0
- package/dist/and.js +2 -0
- package/dist/and.spec.cjs +57 -0
- package/dist/and.spec.d.ts +1 -0
- package/dist/and.spec.js +51 -0
- package/dist/api.cjs +317 -0
- package/dist/api.d.ts +107 -0
- package/dist/api.js +277 -0
- package/dist/api.spec.cjs +512 -0
- package/dist/api.spec.d.ts +1 -0
- package/dist/api.spec.js +506 -0
- package/dist/array.cjs +74 -0
- package/dist/array.d.ts +25 -0
- package/dist/array.js +40 -0
- package/dist/array.spec.cjs +167 -0
- package/dist/array.spec.d.ts +1 -0
- package/dist/array.spec.js +161 -0
- package/dist/before.cjs +36 -0
- package/dist/before.d.ts +30 -0
- package/dist/before.js +2 -0
- package/dist/before.spec.cjs +54 -0
- package/dist/before.spec.d.ts +1 -0
- package/dist/before.spec.js +48 -0
- package/dist/binary.cjs +53 -0
- package/dist/binary.d.ts +24 -0
- package/dist/binary.js +19 -0
- package/dist/binary.spec.cjs +107 -0
- package/dist/binary.spec.d.ts +1 -0
- package/dist/binary.spec.js +101 -0
- package/dist/boolean.cjs +53 -0
- package/dist/boolean.d.ts +24 -0
- package/dist/boolean.js +19 -0
- package/dist/boolean.spec.cjs +96 -0
- package/dist/boolean.spec.d.ts +1 -0
- package/dist/boolean.spec.js +90 -0
- package/dist/context.cjs +125 -0
- package/dist/context.d.ts +101 -0
- package/dist/context.js +76 -0
- package/dist/context.spec.cjs +244 -0
- package/dist/context.spec.d.ts +1 -0
- package/dist/context.spec.js +238 -0
- package/dist/date.cjs +53 -0
- package/dist/date.d.ts +24 -0
- package/dist/date.js +19 -0
- package/dist/date.spec.cjs +97 -0
- package/dist/date.spec.d.ts +1 -0
- package/dist/date.spec.js +91 -0
- package/dist/doc.cjs +54 -0
- package/dist/doc.d.ts +25 -0
- package/dist/doc.js +17 -0
- package/dist/doc.spec.cjs +99 -0
- package/dist/doc.spec.d.ts +1 -0
- package/dist/doc.spec.js +93 -0
- package/dist/enumeration.cjs +74 -0
- package/dist/enumeration.d.ts +50 -0
- package/dist/enumeration.js +40 -0
- package/dist/enumeration.spec.cjs +110 -0
- package/dist/enumeration.spec.d.ts +1 -0
- package/dist/enumeration.spec.js +104 -0
- package/dist/hydrate.cjs +18 -0
- package/dist/hydrate.d.ts +1 -0
- package/dist/hydrate.js +0 -0
- package/dist/index.cjs +145 -0
- package/dist/index.d.ts +34 -0
- package/dist/index.js +24 -0
- package/dist/index.spec.cjs +43 -0
- package/dist/index.spec.d.ts +1 -0
- package/dist/index.spec.js +37 -0
- package/dist/literal.cjs +55 -0
- package/dist/literal.d.ts +25 -0
- package/dist/literal.js +21 -0
- package/dist/literal.spec.cjs +93 -0
- package/dist/literal.spec.d.ts +1 -0
- package/dist/literal.spec.js +87 -0
- package/dist/number.cjs +89 -0
- package/dist/number.d.ts +84 -0
- package/dist/number.js +55 -0
- package/dist/number.spec.cjs +155 -0
- package/dist/number.spec.d.ts +1 -0
- package/dist/number.spec.js +149 -0
- package/dist/object.cjs +66 -0
- package/dist/object.d.ts +37 -0
- package/dist/object.js +32 -0
- package/dist/object.spec.cjs +171 -0
- package/dist/object.spec.d.ts +1 -0
- package/dist/object.spec.js +165 -0
- package/dist/operation.cjs +182 -0
- package/dist/operation.d.ts +197 -0
- package/dist/operation.js +133 -0
- package/dist/operation.spec.cjs +454 -0
- package/dist/operation.spec.d.ts +1 -0
- package/dist/operation.spec.js +448 -0
- package/dist/or.cjs +85 -0
- package/dist/or.d.ts +37 -0
- package/dist/or.js +51 -0
- package/dist/or.spec.cjs +204 -0
- package/dist/or.spec.d.ts +1 -0
- package/dist/or.spec.js +198 -0
- package/dist/schema.cjs +285 -0
- package/dist/schema.d.ts +132 -0
- package/dist/schema.js +233 -0
- package/dist/schema.spec.cjs +587 -0
- package/dist/schema.spec.d.ts +1 -0
- package/dist/schema.spec.js +581 -0
- package/dist/schemaFactory.cjs +125 -0
- package/dist/schemaFactory.d.ts +97 -0
- package/dist/schemaFactory.js +88 -0
- package/dist/schemaFactory.spec.cjs +197 -0
- package/dist/schemaFactory.spec.d.ts +1 -0
- package/dist/schemaFactory.spec.js +191 -0
- package/dist/schemaModule.cjs +280 -0
- package/dist/schemaModule.d.ts +97 -0
- package/dist/schemaModule.js +243 -0
- package/dist/schemaModule.spec.cjs +355 -0
- package/dist/schemaModule.spec.d.ts +1 -0
- package/dist/schemaModule.spec.js +349 -0
- package/dist/string.cjs +93 -0
- package/dist/string.d.ts +85 -0
- package/dist/string.js +59 -0
- package/dist/string.spec.cjs +158 -0
- package/dist/string.spec.d.ts +1 -0
- package/dist/string.spec.js +152 -0
- package/dist/testing/mocks/assertions.mock.cjs +48 -0
- package/dist/testing/mocks/assertions.mock.d.ts +5 -0
- package/dist/testing/mocks/assertions.mock.js +14 -0
- package/dist/testing/mocks/index.cjs +52 -0
- package/dist/testing/mocks/index.d.ts +4 -0
- package/dist/testing/mocks/index.js +3 -0
- package/dist/testing/mocks/schema.mock.cjs +120 -0
- package/dist/testing/mocks/schema.mock.d.ts +37 -0
- package/dist/testing/mocks/schema.mock.js +74 -0
- package/dist/tuple.cjs +58 -0
- package/dist/tuple.d.ts +33 -0
- package/dist/tuple.js +24 -0
- package/dist/tuple.spec.cjs +162 -0
- package/dist/tuple.spec.d.ts +1 -0
- package/dist/tuple.spec.js +156 -0
- package/dist/typeGuards.cjs +60 -0
- package/dist/typeGuards.d.ts +93 -0
- package/dist/typeGuards.js +8 -0
- package/dist/typeGuards.spec.cjs +101 -0
- package/dist/typeGuards.spec.d.ts +1 -0
- package/dist/typeGuards.spec.js +95 -0
- package/dist/types.cjs +18 -0
- package/dist/types.d.ts +289 -0
- package/dist/types.js +0 -0
- package/dist/union.cjs +74 -0
- package/dist/union.d.ts +33 -0
- package/dist/union.js +40 -0
- package/dist/union.spec.cjs +159 -0
- package/dist/union.spec.d.ts +1 -0
- package/dist/union.spec.js +153 -0
- package/package.json +47 -0
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __webpack_require__ = {};
|
|
3
|
+
(()=>{
|
|
4
|
+
__webpack_require__.d = (exports1, definition)=>{
|
|
5
|
+
for(var key in definition)if (__webpack_require__.o(definition, key) && !__webpack_require__.o(exports1, key)) Object.defineProperty(exports1, key, {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: definition[key]
|
|
8
|
+
});
|
|
9
|
+
};
|
|
10
|
+
})();
|
|
11
|
+
(()=>{
|
|
12
|
+
__webpack_require__.o = (obj, prop)=>Object.prototype.hasOwnProperty.call(obj, prop);
|
|
13
|
+
})();
|
|
14
|
+
(()=>{
|
|
15
|
+
__webpack_require__.r = (exports1)=>{
|
|
16
|
+
if ("u" > typeof Symbol && Symbol.toStringTag) Object.defineProperty(exports1, Symbol.toStringTag, {
|
|
17
|
+
value: 'Module'
|
|
18
|
+
});
|
|
19
|
+
Object.defineProperty(exports1, '__esModule', {
|
|
20
|
+
value: true
|
|
21
|
+
});
|
|
22
|
+
};
|
|
23
|
+
})();
|
|
24
|
+
var __webpack_exports__ = {};
|
|
25
|
+
__webpack_require__.r(__webpack_exports__);
|
|
26
|
+
__webpack_require__.d(__webpack_exports__, {
|
|
27
|
+
operation: ()=>operation,
|
|
28
|
+
withOperationName: ()=>withOperationName,
|
|
29
|
+
runOperation: ()=>runOperation,
|
|
30
|
+
withFieldOperationName: ()=>withFieldOperationName,
|
|
31
|
+
runFieldOperation: ()=>runFieldOperation,
|
|
32
|
+
fieldOperation: ()=>fieldOperation
|
|
33
|
+
});
|
|
34
|
+
const external_context_cjs_namespaceObject = require("./context.cjs");
|
|
35
|
+
const external_object_cjs_namespaceObject = require("./object.cjs");
|
|
36
|
+
const isSchema = (value)=>'object' == typeof value && null !== value && 'parse' in value && 'ast' in value;
|
|
37
|
+
const normalizeDependsOn = (dependsOn, name)=>isSchema(dependsOn) ? dependsOn : (0, external_object_cjs_namespaceObject.object)({
|
|
38
|
+
name: name ?? 'dependsOn',
|
|
39
|
+
shape: dependsOn
|
|
40
|
+
});
|
|
41
|
+
function operation(input) {
|
|
42
|
+
const output = 'output' in input ? input.output : void 0;
|
|
43
|
+
return {
|
|
44
|
+
type: 'operation',
|
|
45
|
+
input: input.input,
|
|
46
|
+
output,
|
|
47
|
+
exec: input.exec,
|
|
48
|
+
publish: input.publish,
|
|
49
|
+
rooms: input.rooms,
|
|
50
|
+
ack: input.ack,
|
|
51
|
+
doc: input.doc
|
|
52
|
+
};
|
|
53
|
+
}
|
|
54
|
+
function fieldOperation(input) {
|
|
55
|
+
const dependsOnSchema = normalizeDependsOn(input.dependsOn, 'dependsOn');
|
|
56
|
+
const inputSchema = input.input ? normalizeDependsOn(input.input, 'input') : void 0;
|
|
57
|
+
const output = 'output' in input ? input.output : void 0;
|
|
58
|
+
return {
|
|
59
|
+
type: 'field',
|
|
60
|
+
dependsOn: dependsOnSchema,
|
|
61
|
+
input: inputSchema,
|
|
62
|
+
output,
|
|
63
|
+
exec: input.exec,
|
|
64
|
+
doc: input.doc
|
|
65
|
+
};
|
|
66
|
+
}
|
|
67
|
+
const withOperationName = ({ name, operation: op })=>({
|
|
68
|
+
...op,
|
|
69
|
+
name
|
|
70
|
+
});
|
|
71
|
+
const withFieldOperationName = ({ name, operation: op })=>({
|
|
72
|
+
...op,
|
|
73
|
+
name
|
|
74
|
+
});
|
|
75
|
+
const logPublishError = (error, info, ctx)=>{
|
|
76
|
+
try {
|
|
77
|
+
const logger = ctx?.request?.logger ?? ctx?.getRequestContext()?.logger;
|
|
78
|
+
if (logger?.error) return void logger.error('publish failed', info, error);
|
|
79
|
+
globalThis.console?.error?.('publish failed', info ?? {}, error);
|
|
80
|
+
} catch {}
|
|
81
|
+
};
|
|
82
|
+
const runPublishHooks = async (publish, output, ctx, rooms, operationInput, ack)=>{
|
|
83
|
+
if (!publish) return;
|
|
84
|
+
const publisher = ctx.request?.publisher ?? ctx.getRequestContext()?.publisher;
|
|
85
|
+
if (!publisher) return;
|
|
86
|
+
const roomList = Array.isArray(rooms) ? rooms : rooms ? [
|
|
87
|
+
rooms
|
|
88
|
+
] : [];
|
|
89
|
+
await Object.entries(publish).reduce(async (pending, [topic, hook])=>{
|
|
90
|
+
await pending;
|
|
91
|
+
try {
|
|
92
|
+
const payload = await hook(output, ctx);
|
|
93
|
+
if (void 0 === payload) return;
|
|
94
|
+
if (0 === roomList.length) return void await publisher({
|
|
95
|
+
topic,
|
|
96
|
+
payload,
|
|
97
|
+
input: operationInput,
|
|
98
|
+
ack
|
|
99
|
+
});
|
|
100
|
+
await roomList.reduce(async (chain, room)=>{
|
|
101
|
+
await chain;
|
|
102
|
+
await publisher({
|
|
103
|
+
topic,
|
|
104
|
+
payload,
|
|
105
|
+
input: operationInput,
|
|
106
|
+
ack,
|
|
107
|
+
meta: {
|
|
108
|
+
room
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
}, Promise.resolve());
|
|
112
|
+
} catch (error) {
|
|
113
|
+
logPublishError(error, {
|
|
114
|
+
topic,
|
|
115
|
+
phase: 'publish-hook'
|
|
116
|
+
}, ctx);
|
|
117
|
+
ctx.request?.onPublishError?.(error, {
|
|
118
|
+
topic,
|
|
119
|
+
phase: 'publish-hook'
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
}, Promise.resolve());
|
|
123
|
+
};
|
|
124
|
+
const wrapPublisher = (ctx)=>{
|
|
125
|
+
const request = ctx.request ?? ctx.getRequestContext();
|
|
126
|
+
if (!request?.publisher) return;
|
|
127
|
+
const original = request.publisher;
|
|
128
|
+
request.publisher = async (input)=>{
|
|
129
|
+
try {
|
|
130
|
+
await original(input);
|
|
131
|
+
} catch (error) {
|
|
132
|
+
logPublishError(error, {
|
|
133
|
+
topic: input.topic,
|
|
134
|
+
phase: 'publisher'
|
|
135
|
+
}, ctx);
|
|
136
|
+
request.onPublishError?.(error, {
|
|
137
|
+
topic: input.topic,
|
|
138
|
+
phase: 'publisher'
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
};
|
|
142
|
+
};
|
|
143
|
+
const runOperation = async (op, rawInput, ctx)=>{
|
|
144
|
+
const context = ctx ?? (0, external_context_cjs_namespaceObject.createSchemaContext)();
|
|
145
|
+
if (!context.getRequestContext()) context.setRequestContext({});
|
|
146
|
+
wrapPublisher(context);
|
|
147
|
+
const input = op.input.parse(rawInput, context);
|
|
148
|
+
const rooms = op.rooms ? op.rooms(input, context) : void 0;
|
|
149
|
+
const result = await op.exec(input, context);
|
|
150
|
+
const output = op.output ? op.output.parse(result, context) : result;
|
|
151
|
+
await runPublishHooks(op.publish, output, context, rooms, input, op.ack);
|
|
152
|
+
return output;
|
|
153
|
+
};
|
|
154
|
+
const runFieldOperation = async (op, rawDependsOn, rawInputOrContext, ctx)=>{
|
|
155
|
+
const isContext = (value)=>'object' == typeof value && null !== value && 'getBuildContext' in value && 'getRequestContext' in value;
|
|
156
|
+
const actualContext = isContext(rawInputOrContext) ? rawInputOrContext : ctx;
|
|
157
|
+
const rawInput = isContext(rawInputOrContext) ? void 0 : rawInputOrContext;
|
|
158
|
+
const context = actualContext ?? (0, external_context_cjs_namespaceObject.createSchemaContext)();
|
|
159
|
+
if (!context.getRequestContext()) context.setRequestContext({});
|
|
160
|
+
const dependsOn = op.dependsOn.parse(rawDependsOn, context);
|
|
161
|
+
const input = op.input ? op.input.parse(rawInput, context) : void 0;
|
|
162
|
+
const result = op.input ? await op.exec(dependsOn, input, context) : await op.exec(dependsOn, context);
|
|
163
|
+
if (op.output) return op.output.parse(result, context);
|
|
164
|
+
return result;
|
|
165
|
+
};
|
|
166
|
+
exports.fieldOperation = __webpack_exports__.fieldOperation;
|
|
167
|
+
exports.operation = __webpack_exports__.operation;
|
|
168
|
+
exports.runFieldOperation = __webpack_exports__.runFieldOperation;
|
|
169
|
+
exports.runOperation = __webpack_exports__.runOperation;
|
|
170
|
+
exports.withFieldOperationName = __webpack_exports__.withFieldOperationName;
|
|
171
|
+
exports.withOperationName = __webpack_exports__.withOperationName;
|
|
172
|
+
for(var __rspack_i in __webpack_exports__)if (-1 === [
|
|
173
|
+
"fieldOperation",
|
|
174
|
+
"operation",
|
|
175
|
+
"runFieldOperation",
|
|
176
|
+
"runOperation",
|
|
177
|
+
"withFieldOperationName",
|
|
178
|
+
"withOperationName"
|
|
179
|
+
].indexOf(__rspack_i)) exports[__rspack_i] = __webpack_exports__[__rspack_i];
|
|
180
|
+
Object.defineProperty(exports, '__esModule', {
|
|
181
|
+
value: true
|
|
182
|
+
});
|
|
@@ -0,0 +1,197 @@
|
|
|
1
|
+
import { Schema, Shape, Infer, SchemaContext, SchemaDoc, PublishAck } from './types.js';
|
|
2
|
+
type AnySchema = Schema<any>;
|
|
3
|
+
type InputSource = AnySchema | Shape | undefined;
|
|
4
|
+
type InputInfer<TInput> = TInput extends AnySchema ? Infer<TInput> : TInput extends Shape ? ShapeInfer<TInput> : undefined;
|
|
5
|
+
export interface OperationExecutor<TInput, TResult> {
|
|
6
|
+
(input: TInput, ctx: SchemaContext): TResult | Promise<TResult>;
|
|
7
|
+
}
|
|
8
|
+
export interface OperationRooms<TInput> {
|
|
9
|
+
(input: TInput, ctx: SchemaContext): string | readonly string[] | undefined;
|
|
10
|
+
}
|
|
11
|
+
export type OperationResult<TOutputSchema extends AnySchema | undefined, TResult> = TOutputSchema extends Schema<infer TOutput> ? TOutput : TResult;
|
|
12
|
+
export interface OperationPublishHook<TOutput> {
|
|
13
|
+
(output: TOutput, ctx: SchemaContext): unknown | void | Promise<unknown | void>;
|
|
14
|
+
}
|
|
15
|
+
export type OperationPublishMap<TOutput> = Record<string, OperationPublishHook<TOutput>>;
|
|
16
|
+
export type ShapeInfer<TShape extends Shape> = {
|
|
17
|
+
[K in keyof TShape]: Infer<TShape[K]>;
|
|
18
|
+
};
|
|
19
|
+
export interface Operation<TInputSchema extends AnySchema, TOutputSchema extends AnySchema | undefined, TResult> {
|
|
20
|
+
type: 'operation';
|
|
21
|
+
name?: string;
|
|
22
|
+
doc?: SchemaDoc;
|
|
23
|
+
input: TInputSchema;
|
|
24
|
+
output?: TOutputSchema;
|
|
25
|
+
exec: OperationExecutor<Infer<TInputSchema>, TResult>;
|
|
26
|
+
publish?: OperationPublishMap<OperationResult<TOutputSchema, TResult>>;
|
|
27
|
+
rooms?: OperationRooms<Infer<TInputSchema>>;
|
|
28
|
+
ack?: PublishAck;
|
|
29
|
+
}
|
|
30
|
+
export interface OperationInput<TInputSchema extends AnySchema, TResult> {
|
|
31
|
+
input: TInputSchema;
|
|
32
|
+
doc?: SchemaDoc;
|
|
33
|
+
exec: OperationExecutor<Infer<TInputSchema>, TResult>;
|
|
34
|
+
publish?: OperationPublishMap<TResult>;
|
|
35
|
+
rooms?: OperationRooms<Infer<TInputSchema>>;
|
|
36
|
+
ack?: PublishAck;
|
|
37
|
+
}
|
|
38
|
+
export interface OperationInputWithOutput<TInputSchema extends AnySchema, TOutputSchema extends AnySchema> {
|
|
39
|
+
input: TInputSchema;
|
|
40
|
+
output: TOutputSchema;
|
|
41
|
+
doc?: SchemaDoc;
|
|
42
|
+
exec: OperationExecutor<Infer<TInputSchema>, Infer<TOutputSchema>>;
|
|
43
|
+
publish?: OperationPublishMap<Infer<TOutputSchema>>;
|
|
44
|
+
rooms?: OperationRooms<Infer<TInputSchema>>;
|
|
45
|
+
ack?: PublishAck;
|
|
46
|
+
}
|
|
47
|
+
export interface OperationInputWithOptionalOutput<TInputSchema extends AnySchema, TResult> extends OperationInput<TInputSchema, TResult> {
|
|
48
|
+
output?: AnySchema;
|
|
49
|
+
}
|
|
50
|
+
export interface FieldOperationExecutor<TDependsOn, TInput, TResult> {
|
|
51
|
+
(dependsOn: TDependsOn, ctx: SchemaContext): TResult | Promise<TResult>;
|
|
52
|
+
(dependsOn: TDependsOn, input: TInput, ctx: SchemaContext): TResult | Promise<TResult>;
|
|
53
|
+
}
|
|
54
|
+
export interface FieldOperation<TDependsOnSchema extends AnySchema, TInput extends InputSource, TOutputSchema extends AnySchema | undefined, TResult> {
|
|
55
|
+
type: 'field';
|
|
56
|
+
name?: string;
|
|
57
|
+
doc?: SchemaDoc;
|
|
58
|
+
dependsOn: TDependsOnSchema;
|
|
59
|
+
input?: AnySchema;
|
|
60
|
+
output?: TOutputSchema;
|
|
61
|
+
exec: FieldOperationExecutor<Infer<TDependsOnSchema>, InputInfer<TInput>, TResult>;
|
|
62
|
+
}
|
|
63
|
+
export interface FieldOperationInput<TDependsOnSchema extends AnySchema, TResult, TInput extends InputSource = undefined> {
|
|
64
|
+
dependsOn: TDependsOnSchema;
|
|
65
|
+
input?: TInput;
|
|
66
|
+
doc?: SchemaDoc;
|
|
67
|
+
exec: FieldOperationExecutor<Infer<TDependsOnSchema>, InputInfer<TInput>, TResult>;
|
|
68
|
+
}
|
|
69
|
+
export interface FieldOperationInputWithOutput<TDependsOnSchema extends AnySchema, TOutputSchema extends AnySchema, TInput extends InputSource = undefined> {
|
|
70
|
+
dependsOn: TDependsOnSchema;
|
|
71
|
+
input?: TInput;
|
|
72
|
+
output: TOutputSchema;
|
|
73
|
+
doc?: SchemaDoc;
|
|
74
|
+
exec: FieldOperationExecutor<Infer<TDependsOnSchema>, InputInfer<TInput>, Infer<TOutputSchema>>;
|
|
75
|
+
}
|
|
76
|
+
export interface FieldOperationInputShape<TShape extends Shape, TResult, TInput extends InputSource = undefined> {
|
|
77
|
+
dependsOn: TShape;
|
|
78
|
+
input?: TInput;
|
|
79
|
+
doc?: SchemaDoc;
|
|
80
|
+
exec: FieldOperationExecutor<ShapeInfer<TShape>, InputInfer<TInput>, TResult>;
|
|
81
|
+
}
|
|
82
|
+
export interface FieldOperationInputShapeWithOutput<TShape extends Shape, TOutputSchema extends AnySchema, TInput extends InputSource = undefined> {
|
|
83
|
+
dependsOn: TShape;
|
|
84
|
+
input?: TInput;
|
|
85
|
+
output: TOutputSchema;
|
|
86
|
+
doc?: SchemaDoc;
|
|
87
|
+
exec: FieldOperationExecutor<ShapeInfer<TShape>, InputInfer<TInput>, Infer<TOutputSchema>>;
|
|
88
|
+
}
|
|
89
|
+
export interface FieldOperationInputWithOptionalOutput<TDependsOnSchema extends AnySchema, TResult> {
|
|
90
|
+
dependsOn: TDependsOnSchema;
|
|
91
|
+
input?: InputSource;
|
|
92
|
+
output?: AnySchema;
|
|
93
|
+
doc?: SchemaDoc;
|
|
94
|
+
exec: FieldOperationExecutor<Infer<TDependsOnSchema>, InputInfer<InputSource>, TResult>;
|
|
95
|
+
}
|
|
96
|
+
export interface FieldOperationInputShapeWithOptionalOutput<TResult> {
|
|
97
|
+
dependsOn: Shape;
|
|
98
|
+
input?: InputSource;
|
|
99
|
+
output?: AnySchema;
|
|
100
|
+
doc?: SchemaDoc;
|
|
101
|
+
exec: FieldOperationExecutor<ShapeInfer<Shape>, InputInfer<InputSource>, TResult>;
|
|
102
|
+
}
|
|
103
|
+
export interface OperationWithName<TInputSchema extends AnySchema, TOutputSchema extends AnySchema | undefined, TResult> {
|
|
104
|
+
name: string;
|
|
105
|
+
operation: Operation<TInputSchema, TOutputSchema, TResult>;
|
|
106
|
+
}
|
|
107
|
+
export interface FieldOperationWithName<TDependsOnSchema extends AnySchema, TInput extends InputSource, TOutputSchema extends AnySchema | undefined, TResult> {
|
|
108
|
+
name: string;
|
|
109
|
+
operation: FieldOperation<TDependsOnSchema, TInput, TOutputSchema, TResult>;
|
|
110
|
+
}
|
|
111
|
+
export interface OperationFactory {
|
|
112
|
+
<TInputSchema extends AnySchema, TOutputSchema extends AnySchema>(input: OperationInputWithOutput<TInputSchema, TOutputSchema>): Operation<TInputSchema, TOutputSchema, Infer<TOutputSchema>>;
|
|
113
|
+
<TInputSchema extends AnySchema, TResult>(input: OperationInput<TInputSchema, TResult>): Operation<TInputSchema, undefined, TResult>;
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* operation is part of the public LIVON API.
|
|
117
|
+
*
|
|
118
|
+
* @remarks
|
|
119
|
+
* Parameter and return types are defined in the TypeScript signature.
|
|
120
|
+
*
|
|
121
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/operation
|
|
122
|
+
*
|
|
123
|
+
* @example
|
|
124
|
+
* const result = operation(undefined as never);
|
|
125
|
+
*/
|
|
126
|
+
export declare function operation<TInputSchema extends AnySchema, TOutputSchema extends AnySchema>(input: OperationInputWithOutput<TInputSchema, TOutputSchema>): Operation<TInputSchema, TOutputSchema, Infer<TOutputSchema>>;
|
|
127
|
+
export declare function operation<TInputSchema extends AnySchema, TResult>(input: OperationInput<TInputSchema, TResult>): Operation<TInputSchema, undefined, TResult>;
|
|
128
|
+
export interface FieldOperationFactory {
|
|
129
|
+
<TDependsOnSchema extends AnySchema, TOutputSchema extends AnySchema, TInput extends InputSource = undefined>(input: FieldOperationInputWithOutput<TDependsOnSchema, TOutputSchema, TInput>): FieldOperation<TDependsOnSchema, TInput, TOutputSchema, Infer<TOutputSchema>>;
|
|
130
|
+
<TDependsOnSchema extends AnySchema, TResult, TInput extends InputSource = undefined>(input: FieldOperationInput<TDependsOnSchema, TResult, TInput>): FieldOperation<TDependsOnSchema, TInput, undefined, TResult>;
|
|
131
|
+
<TShape extends Shape, TOutputSchema extends AnySchema, TInput extends InputSource = undefined>(input: FieldOperationInputShapeWithOutput<TShape, TOutputSchema, TInput>): FieldOperation<AnySchema, TInput, TOutputSchema, Infer<TOutputSchema>>;
|
|
132
|
+
<TShape extends Shape, TResult, TInput extends InputSource = undefined>(input: FieldOperationInputShape<TShape, TResult, TInput>): FieldOperation<AnySchema, TInput, undefined, TResult>;
|
|
133
|
+
}
|
|
134
|
+
/**
|
|
135
|
+
* fieldOperation is part of the public LIVON API.
|
|
136
|
+
*
|
|
137
|
+
* @remarks
|
|
138
|
+
* Parameter and return types are defined in the TypeScript signature.
|
|
139
|
+
*
|
|
140
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/operation
|
|
141
|
+
*
|
|
142
|
+
* @example
|
|
143
|
+
* const result = fieldOperation(undefined as never);
|
|
144
|
+
*/
|
|
145
|
+
export declare function fieldOperation<TDependsOnSchema extends AnySchema, TOutputSchema extends AnySchema, TInput extends InputSource = undefined>(input: FieldOperationInputWithOutput<TDependsOnSchema, TOutputSchema, TInput>): FieldOperation<TDependsOnSchema, TInput, TOutputSchema, Infer<TOutputSchema>>;
|
|
146
|
+
export declare function fieldOperation<TDependsOnSchema extends AnySchema, TResult, TInput extends InputSource = undefined>(input: FieldOperationInput<TDependsOnSchema, TResult, TInput>): FieldOperation<TDependsOnSchema, TInput, undefined, TResult>;
|
|
147
|
+
export declare function fieldOperation<TShape extends Shape, TOutputSchema extends AnySchema, TInput extends InputSource = undefined>(input: FieldOperationInputShapeWithOutput<TShape, TOutputSchema, TInput>): FieldOperation<AnySchema, TInput, TOutputSchema, Infer<TOutputSchema>>;
|
|
148
|
+
export declare function fieldOperation<TShape extends Shape, TResult, TInput extends InputSource = undefined>(input: FieldOperationInputShape<TShape, TResult, TInput>): FieldOperation<AnySchema, TInput, undefined, TResult>;
|
|
149
|
+
/**
|
|
150
|
+
* withOperationName is part of the public LIVON API.
|
|
151
|
+
*
|
|
152
|
+
* @remarks
|
|
153
|
+
* Parameter and return types are defined in the TypeScript signature.
|
|
154
|
+
*
|
|
155
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/operation
|
|
156
|
+
*
|
|
157
|
+
* @example
|
|
158
|
+
* const result = withOperationName(undefined as never);
|
|
159
|
+
*/
|
|
160
|
+
export declare const withOperationName: <TInputSchema extends AnySchema, TOutputSchema extends AnySchema | undefined, TResult>({ name, operation: op, }: OperationWithName<TInputSchema, TOutputSchema, TResult>) => Operation<TInputSchema, TOutputSchema, TResult>;
|
|
161
|
+
/**
|
|
162
|
+
* withFieldOperationName is part of the public LIVON API.
|
|
163
|
+
*
|
|
164
|
+
* @remarks
|
|
165
|
+
* Parameter and return types are defined in the TypeScript signature.
|
|
166
|
+
*
|
|
167
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/operation
|
|
168
|
+
*
|
|
169
|
+
* @example
|
|
170
|
+
* const result = withFieldOperationName(undefined as never);
|
|
171
|
+
*/
|
|
172
|
+
export declare const withFieldOperationName: <TDependsOnSchema extends AnySchema, TInput extends InputSource, TOutputSchema extends AnySchema | undefined, TResult>({ name, operation: op, }: FieldOperationWithName<TDependsOnSchema, TInput, TOutputSchema, TResult>) => FieldOperation<TDependsOnSchema, TInput, TOutputSchema, TResult>;
|
|
173
|
+
/**
|
|
174
|
+
* runOperation is part of the public LIVON API.
|
|
175
|
+
*
|
|
176
|
+
* @remarks
|
|
177
|
+
* Parameter and return types are defined in the TypeScript signature.
|
|
178
|
+
*
|
|
179
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/operation
|
|
180
|
+
*
|
|
181
|
+
* @example
|
|
182
|
+
* const result = runOperation(undefined as never);
|
|
183
|
+
*/
|
|
184
|
+
export declare const runOperation: <TInputSchema extends AnySchema, TOutputSchema extends AnySchema | undefined, TResult>(op: Operation<TInputSchema, TOutputSchema, TResult>, rawInput: unknown, ctx?: SchemaContext) => Promise<OperationResult<TOutputSchema, TResult>>;
|
|
185
|
+
/**
|
|
186
|
+
* runFieldOperation is part of the public LIVON API.
|
|
187
|
+
*
|
|
188
|
+
* @remarks
|
|
189
|
+
* Parameter and return types are defined in the TypeScript signature.
|
|
190
|
+
*
|
|
191
|
+
* @see https://live-input-vector-output-node.github.io/livon-ts/docs/schema/operation
|
|
192
|
+
*
|
|
193
|
+
* @example
|
|
194
|
+
* const result = runFieldOperation(undefined as never);
|
|
195
|
+
*/
|
|
196
|
+
export declare const runFieldOperation: <TDependsOnSchema extends AnySchema, TInput extends InputSource, TOutputSchema extends AnySchema | undefined, TResult>(op: FieldOperation<TDependsOnSchema, TInput, TOutputSchema, TResult>, rawDependsOn: unknown, rawInputOrContext?: unknown, ctx?: SchemaContext) => Promise<OperationResult<TOutputSchema, TResult>>;
|
|
197
|
+
export {};
|
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
import { createSchemaContext } from "./context.js";
|
|
2
|
+
import { object } from "./object.js";
|
|
3
|
+
const isSchema = (value)=>'object' == typeof value && null !== value && 'parse' in value && 'ast' in value;
|
|
4
|
+
const normalizeDependsOn = (dependsOn, name)=>isSchema(dependsOn) ? dependsOn : object({
|
|
5
|
+
name: name ?? 'dependsOn',
|
|
6
|
+
shape: dependsOn
|
|
7
|
+
});
|
|
8
|
+
function operation(input) {
|
|
9
|
+
const output = 'output' in input ? input.output : void 0;
|
|
10
|
+
return {
|
|
11
|
+
type: 'operation',
|
|
12
|
+
input: input.input,
|
|
13
|
+
output,
|
|
14
|
+
exec: input.exec,
|
|
15
|
+
publish: input.publish,
|
|
16
|
+
rooms: input.rooms,
|
|
17
|
+
ack: input.ack,
|
|
18
|
+
doc: input.doc
|
|
19
|
+
};
|
|
20
|
+
}
|
|
21
|
+
function fieldOperation(input) {
|
|
22
|
+
const dependsOnSchema = normalizeDependsOn(input.dependsOn, 'dependsOn');
|
|
23
|
+
const inputSchema = input.input ? normalizeDependsOn(input.input, 'input') : void 0;
|
|
24
|
+
const output = 'output' in input ? input.output : void 0;
|
|
25
|
+
return {
|
|
26
|
+
type: 'field',
|
|
27
|
+
dependsOn: dependsOnSchema,
|
|
28
|
+
input: inputSchema,
|
|
29
|
+
output,
|
|
30
|
+
exec: input.exec,
|
|
31
|
+
doc: input.doc
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const withOperationName = ({ name, operation: op })=>({
|
|
35
|
+
...op,
|
|
36
|
+
name
|
|
37
|
+
});
|
|
38
|
+
const withFieldOperationName = ({ name, operation: op })=>({
|
|
39
|
+
...op,
|
|
40
|
+
name
|
|
41
|
+
});
|
|
42
|
+
const logPublishError = (error, info, ctx)=>{
|
|
43
|
+
try {
|
|
44
|
+
const logger = ctx?.request?.logger ?? ctx?.getRequestContext()?.logger;
|
|
45
|
+
if (logger?.error) return void logger.error('publish failed', info, error);
|
|
46
|
+
globalThis.console?.error?.('publish failed', info ?? {}, error);
|
|
47
|
+
} catch {}
|
|
48
|
+
};
|
|
49
|
+
const runPublishHooks = async (publish, output, ctx, rooms, operationInput, ack)=>{
|
|
50
|
+
if (!publish) return;
|
|
51
|
+
const publisher = ctx.request?.publisher ?? ctx.getRequestContext()?.publisher;
|
|
52
|
+
if (!publisher) return;
|
|
53
|
+
const roomList = Array.isArray(rooms) ? rooms : rooms ? [
|
|
54
|
+
rooms
|
|
55
|
+
] : [];
|
|
56
|
+
await Object.entries(publish).reduce(async (pending, [topic, hook])=>{
|
|
57
|
+
await pending;
|
|
58
|
+
try {
|
|
59
|
+
const payload = await hook(output, ctx);
|
|
60
|
+
if (void 0 === payload) return;
|
|
61
|
+
if (0 === roomList.length) return void await publisher({
|
|
62
|
+
topic,
|
|
63
|
+
payload,
|
|
64
|
+
input: operationInput,
|
|
65
|
+
ack
|
|
66
|
+
});
|
|
67
|
+
await roomList.reduce(async (chain, room)=>{
|
|
68
|
+
await chain;
|
|
69
|
+
await publisher({
|
|
70
|
+
topic,
|
|
71
|
+
payload,
|
|
72
|
+
input: operationInput,
|
|
73
|
+
ack,
|
|
74
|
+
meta: {
|
|
75
|
+
room
|
|
76
|
+
}
|
|
77
|
+
});
|
|
78
|
+
}, Promise.resolve());
|
|
79
|
+
} catch (error) {
|
|
80
|
+
logPublishError(error, {
|
|
81
|
+
topic,
|
|
82
|
+
phase: 'publish-hook'
|
|
83
|
+
}, ctx);
|
|
84
|
+
ctx.request?.onPublishError?.(error, {
|
|
85
|
+
topic,
|
|
86
|
+
phase: 'publish-hook'
|
|
87
|
+
});
|
|
88
|
+
}
|
|
89
|
+
}, Promise.resolve());
|
|
90
|
+
};
|
|
91
|
+
const wrapPublisher = (ctx)=>{
|
|
92
|
+
const request = ctx.request ?? ctx.getRequestContext();
|
|
93
|
+
if (!request?.publisher) return;
|
|
94
|
+
const original = request.publisher;
|
|
95
|
+
request.publisher = async (input)=>{
|
|
96
|
+
try {
|
|
97
|
+
await original(input);
|
|
98
|
+
} catch (error) {
|
|
99
|
+
logPublishError(error, {
|
|
100
|
+
topic: input.topic,
|
|
101
|
+
phase: 'publisher'
|
|
102
|
+
}, ctx);
|
|
103
|
+
request.onPublishError?.(error, {
|
|
104
|
+
topic: input.topic,
|
|
105
|
+
phase: 'publisher'
|
|
106
|
+
});
|
|
107
|
+
}
|
|
108
|
+
};
|
|
109
|
+
};
|
|
110
|
+
const runOperation = async (op, rawInput, ctx)=>{
|
|
111
|
+
const context = ctx ?? createSchemaContext();
|
|
112
|
+
if (!context.getRequestContext()) context.setRequestContext({});
|
|
113
|
+
wrapPublisher(context);
|
|
114
|
+
const input = op.input.parse(rawInput, context);
|
|
115
|
+
const rooms = op.rooms ? op.rooms(input, context) : void 0;
|
|
116
|
+
const result = await op.exec(input, context);
|
|
117
|
+
const output = op.output ? op.output.parse(result, context) : result;
|
|
118
|
+
await runPublishHooks(op.publish, output, context, rooms, input, op.ack);
|
|
119
|
+
return output;
|
|
120
|
+
};
|
|
121
|
+
const runFieldOperation = async (op, rawDependsOn, rawInputOrContext, ctx)=>{
|
|
122
|
+
const isContext = (value)=>'object' == typeof value && null !== value && 'getBuildContext' in value && 'getRequestContext' in value;
|
|
123
|
+
const actualContext = isContext(rawInputOrContext) ? rawInputOrContext : ctx;
|
|
124
|
+
const rawInput = isContext(rawInputOrContext) ? void 0 : rawInputOrContext;
|
|
125
|
+
const context = actualContext ?? createSchemaContext();
|
|
126
|
+
if (!context.getRequestContext()) context.setRequestContext({});
|
|
127
|
+
const dependsOn = op.dependsOn.parse(rawDependsOn, context);
|
|
128
|
+
const input = op.input ? op.input.parse(rawInput, context) : void 0;
|
|
129
|
+
const result = op.input ? await op.exec(dependsOn, input, context) : await op.exec(dependsOn, context);
|
|
130
|
+
if (op.output) return op.output.parse(result, context);
|
|
131
|
+
return result;
|
|
132
|
+
};
|
|
133
|
+
export { fieldOperation, operation, runFieldOperation, runOperation, withFieldOperationName, withOperationName };
|