@ucdjs/pipelines-core 0.0.1-beta.7 → 0.0.1-beta.8
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/README.md +0 -3
- package/dist/index.d.mts +39 -343
- package/dist/index.mjs +99 -99
- package/dist/outputs/index.d.mts +17 -0
- package/dist/outputs/index.mjs +73 -0
- package/dist/route-BT-OXkF-.d.mts +96 -0
- package/dist/{source-Bnjgl99T.d.mts → source-Bw_42mA2.d.mts} +21 -4
- package/dist/source-UYQsDb7S.mjs +49 -0
- package/dist/sources/index.d.mts +2 -2
- package/dist/sources/index.mjs +3 -6
- package/dist/tracing/index.d.mts +178 -0
- package/dist/tracing/index.mjs +60 -0
- package/dist/{transform-C2GdfzQ-.d.mts → transform-BkBLzZAP.d.mts} +3 -2
- package/dist/{transform-BGOswbNk.mjs → transform-C7y-ZJKs.mjs} +2 -3
- package/dist/transforms/index.d.mts +2 -2
- package/dist/transforms/index.mjs +4 -8
- package/dist/{types-T24cxilU.d.mts → types-B_R0NiDI.d.mts} +16 -41
- package/dist/types-BxE_sFho.mjs +19 -0
- package/package.json +13 -8
- package/dist/source-EtWCktj_.mjs +0 -26
package/dist/index.mjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { n as
|
|
2
|
-
import { n as
|
|
1
|
+
import { n as normalizeRouteOutputs, t as filesystemSink } from "./types-BxE_sFho.mjs";
|
|
2
|
+
import { a as resolveSourceFiles, i as resolveMultipleSourceFiles, n as isPipelineOutputSource, r as pipelineOutputSource, t as definePipelineSource } from "./source-UYQsDb7S.mjs";
|
|
3
|
+
import { n as definePipelineTransform, t as applyTransforms } from "./transform-C7y-ZJKs.mjs";
|
|
3
4
|
import picomatch from "picomatch";
|
|
4
|
-
|
|
5
5
|
//#region src/dependencies.ts
|
|
6
6
|
function parseDependency(dep) {
|
|
7
7
|
if (dep.startsWith("route:")) {
|
|
@@ -12,37 +12,19 @@ function parseDependency(dep) {
|
|
|
12
12
|
routeId
|
|
13
13
|
};
|
|
14
14
|
}
|
|
15
|
-
|
|
16
|
-
const rest = dep.slice(9);
|
|
17
|
-
const sepIndex = rest.indexOf(":");
|
|
18
|
-
if (sepIndex <= 0 || sepIndex >= rest.length - 1) throw new Error(`Invalid dependency format: ${dep}. Expected "route:<id>" or "artifact:<routeId>:<artifactName>"`);
|
|
19
|
-
return {
|
|
20
|
-
type: "artifact",
|
|
21
|
-
routeId: rest.slice(0, sepIndex),
|
|
22
|
-
artifactName: rest.slice(sepIndex + 1)
|
|
23
|
-
};
|
|
24
|
-
}
|
|
25
|
-
throw new Error(`Invalid dependency format: ${dep}. Expected "route:<id>" or "artifact:<routeId>:<artifactName>"`);
|
|
15
|
+
throw new Error(`Invalid dependency format: ${dep}. Expected "route:<id>"`);
|
|
26
16
|
}
|
|
27
17
|
function isRouteDependency(dep) {
|
|
28
18
|
return dep.startsWith("route:");
|
|
29
19
|
}
|
|
30
|
-
function isArtifactDependency(dep) {
|
|
31
|
-
return dep.startsWith("artifact:");
|
|
32
|
-
}
|
|
33
20
|
function createRouteDependency(routeId) {
|
|
34
21
|
return `route:${routeId}`;
|
|
35
22
|
}
|
|
36
|
-
function createArtifactDependency(routeId, artifactName) {
|
|
37
|
-
return `artifact:${routeId}:${artifactName}`;
|
|
38
|
-
}
|
|
39
|
-
|
|
40
23
|
//#endregion
|
|
41
24
|
//#region src/dag.ts
|
|
42
25
|
function buildDAG(routes) {
|
|
43
26
|
const errors = [];
|
|
44
27
|
const nodes = /* @__PURE__ */ new Map();
|
|
45
|
-
const artifactsByRoute = /* @__PURE__ */ new Map();
|
|
46
28
|
const seenIds = /* @__PURE__ */ new Map();
|
|
47
29
|
for (let i = 0; i < routes.length; i++) {
|
|
48
30
|
const route = routes[i];
|
|
@@ -60,65 +42,29 @@ function buildDAG(routes) {
|
|
|
60
42
|
errors
|
|
61
43
|
};
|
|
62
44
|
const routeIds = new Set(routes.map((r) => r.id));
|
|
63
|
-
for (const route of routes) {
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
id: route.id,
|
|
69
|
-
dependencies: /* @__PURE__ */ new Set(),
|
|
70
|
-
dependents: /* @__PURE__ */ new Set(),
|
|
71
|
-
emittedArtifacts
|
|
72
|
-
});
|
|
73
|
-
}
|
|
45
|
+
for (const route of routes) nodes.set(route.id, {
|
|
46
|
+
id: route.id,
|
|
47
|
+
dependencies: /* @__PURE__ */ new Set(),
|
|
48
|
+
dependents: /* @__PURE__ */ new Set()
|
|
49
|
+
});
|
|
74
50
|
for (const route of routes) {
|
|
75
51
|
const node = nodes.get(route.id);
|
|
76
52
|
if (!route.depends) continue;
|
|
77
53
|
for (const dep of route.depends) {
|
|
78
54
|
const parsed = parseDependency(dep);
|
|
79
|
-
if (
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
continue;
|
|
90
|
-
}
|
|
91
|
-
node.dependencies.add(parsed.routeId);
|
|
92
|
-
nodes.get(parsed.routeId).dependents.add(route.id);
|
|
93
|
-
} else if (isArtifactDependency(dep)) {
|
|
94
|
-
if (parsed.type !== "artifact") continue;
|
|
95
|
-
if (!routeIds.has(parsed.routeId)) {
|
|
96
|
-
errors.push({
|
|
97
|
-
type: "missing-route",
|
|
98
|
-
message: `Route "${route.id}" depends on artifact from non-existent route "${parsed.routeId}"`,
|
|
99
|
-
details: {
|
|
100
|
-
routeId: route.id,
|
|
101
|
-
dependencyId: parsed.routeId
|
|
102
|
-
}
|
|
103
|
-
});
|
|
104
|
-
continue;
|
|
105
|
-
}
|
|
106
|
-
const routeArtifacts = artifactsByRoute.get(parsed.routeId);
|
|
107
|
-
const artifactKey = `${parsed.routeId}:${parsed.artifactName}`;
|
|
108
|
-
if (!routeArtifacts?.has(artifactKey)) {
|
|
109
|
-
errors.push({
|
|
110
|
-
type: "missing-artifact",
|
|
111
|
-
message: `Route "${route.id}" depends on non-existent artifact "${parsed.artifactName}" from route "${parsed.routeId}"`,
|
|
112
|
-
details: {
|
|
113
|
-
routeId: route.id,
|
|
114
|
-
dependencyId: artifactKey
|
|
115
|
-
}
|
|
116
|
-
});
|
|
117
|
-
continue;
|
|
118
|
-
}
|
|
119
|
-
node.dependencies.add(parsed.routeId);
|
|
120
|
-
nodes.get(parsed.routeId).dependents.add(route.id);
|
|
55
|
+
if (!routeIds.has(parsed.routeId)) {
|
|
56
|
+
errors.push({
|
|
57
|
+
type: "missing-route",
|
|
58
|
+
message: `Route "${route.id}" depends on non-existent route "${parsed.routeId}"`,
|
|
59
|
+
details: {
|
|
60
|
+
routeId: route.id,
|
|
61
|
+
dependencyId: parsed.routeId
|
|
62
|
+
}
|
|
63
|
+
});
|
|
64
|
+
continue;
|
|
121
65
|
}
|
|
66
|
+
node.dependencies.add(parsed.routeId);
|
|
67
|
+
nodes.get(parsed.routeId).dependents.add(route.id);
|
|
122
68
|
}
|
|
123
69
|
}
|
|
124
70
|
const cycleResult = detectCycle(nodes);
|
|
@@ -201,52 +147,110 @@ function getExecutionLayers(dag) {
|
|
|
201
147
|
}
|
|
202
148
|
return layers;
|
|
203
149
|
}
|
|
204
|
-
|
|
205
150
|
//#endregion
|
|
206
151
|
//#region src/filters.ts
|
|
152
|
+
const FILTER_NODE = Symbol.for("ucdjs.filter-node");
|
|
153
|
+
function setFilterNode(filter, node) {
|
|
154
|
+
Object.defineProperty(filter, FILTER_NODE, {
|
|
155
|
+
value: node,
|
|
156
|
+
enumerable: false,
|
|
157
|
+
configurable: false,
|
|
158
|
+
writable: false
|
|
159
|
+
});
|
|
160
|
+
return filter;
|
|
161
|
+
}
|
|
162
|
+
function getFilterNode(filter) {
|
|
163
|
+
return filter[FILTER_NODE];
|
|
164
|
+
}
|
|
165
|
+
function createPipelineFilter(caller, args, filter) {
|
|
166
|
+
return setFilterNode(filter, {
|
|
167
|
+
type: "filter",
|
|
168
|
+
name: caller.name,
|
|
169
|
+
args
|
|
170
|
+
});
|
|
171
|
+
}
|
|
172
|
+
function serializeNode(filter, insideCombinator = false) {
|
|
173
|
+
const node = getFilterNode(filter);
|
|
174
|
+
if (!node) return "<custom>";
|
|
175
|
+
switch (node.type) {
|
|
176
|
+
case "filter": {
|
|
177
|
+
const args = node.args.map(formatArg).join(", ");
|
|
178
|
+
return `${node.name}(${args})`;
|
|
179
|
+
}
|
|
180
|
+
case "and": {
|
|
181
|
+
const description = node.filters.map((filter) => serializeNode(filter, true)).join(" AND ");
|
|
182
|
+
return insideCombinator ? `(${description})` : description;
|
|
183
|
+
}
|
|
184
|
+
case "or": {
|
|
185
|
+
const description = node.filters.map((filter) => serializeNode(filter, true)).join(" OR ");
|
|
186
|
+
return insideCombinator ? `(${description})` : description;
|
|
187
|
+
}
|
|
188
|
+
case "not": return `NOT ${serializeNode(node.filter, true)}`;
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
function formatArg(arg) {
|
|
192
|
+
if (typeof arg === "string") return JSON.stringify(arg);
|
|
193
|
+
if (arg instanceof RegExp) return String(arg);
|
|
194
|
+
if (Array.isArray(arg)) return JSON.stringify(arg);
|
|
195
|
+
return String(arg);
|
|
196
|
+
}
|
|
197
|
+
function getFilterDescription(filter) {
|
|
198
|
+
if (!getFilterNode(filter)) return;
|
|
199
|
+
return serializeNode(filter);
|
|
200
|
+
}
|
|
207
201
|
function byName(name) {
|
|
208
|
-
return (
|
|
202
|
+
return createPipelineFilter(byName, [name], (context) => context.file.name === name);
|
|
209
203
|
}
|
|
210
204
|
function byDir(dir) {
|
|
211
|
-
return (
|
|
205
|
+
return createPipelineFilter(byDir, [dir], (context) => context.file.dir === dir);
|
|
212
206
|
}
|
|
213
207
|
function byExt(ext) {
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
return (ctx) => ctx.file.ext === normalizedExt;
|
|
208
|
+
const normalizedExt = ext === "" ? "" : ext.startsWith(".") ? ext : `.${ext}`;
|
|
209
|
+
return createPipelineFilter(byExt, [normalizedExt], (context) => context.file.ext === normalizedExt);
|
|
217
210
|
}
|
|
218
211
|
function byGlob(pattern) {
|
|
219
|
-
const
|
|
220
|
-
return (
|
|
212
|
+
const matches = picomatch(pattern);
|
|
213
|
+
return createPipelineFilter(byGlob, [pattern], (context) => matches(context.file.path));
|
|
221
214
|
}
|
|
222
215
|
function byPath(pathPattern) {
|
|
223
|
-
if (typeof pathPattern === "string") return (
|
|
224
|
-
return (
|
|
216
|
+
if (typeof pathPattern === "string") return createPipelineFilter(byPath, [pathPattern], (context) => context.file.path === pathPattern);
|
|
217
|
+
return createPipelineFilter(byPath, [pathPattern], (context) => pathPattern.test(context.file.path));
|
|
225
218
|
}
|
|
226
219
|
function byProp(pattern) {
|
|
227
|
-
if (typeof pattern === "string") return (
|
|
228
|
-
return (
|
|
220
|
+
if (typeof pattern === "string") return createPipelineFilter(byProp, [pattern], (context) => context.row?.property === pattern);
|
|
221
|
+
return createPipelineFilter(byProp, [pattern], (context) => {
|
|
222
|
+
const property = context.row?.property;
|
|
223
|
+
return property != null && pattern.test(property);
|
|
224
|
+
});
|
|
229
225
|
}
|
|
230
226
|
function bySource(sourceIds) {
|
|
231
227
|
const ids = Array.isArray(sourceIds) ? sourceIds : [sourceIds];
|
|
232
|
-
return (
|
|
228
|
+
return createPipelineFilter(bySource, [ids.length === 1 ? ids[0] : ids], (context) => context.source != null && ids.includes(context.source.id));
|
|
233
229
|
}
|
|
234
230
|
function and(...filters) {
|
|
235
|
-
return (
|
|
231
|
+
return setFilterNode((context) => filters.every((filter) => filter(context)), {
|
|
232
|
+
type: "and",
|
|
233
|
+
filters
|
|
234
|
+
});
|
|
236
235
|
}
|
|
237
236
|
function or(...filters) {
|
|
238
|
-
return (
|
|
237
|
+
return setFilterNode((context) => filters.some((filter) => filter(context)), {
|
|
238
|
+
type: "or",
|
|
239
|
+
filters
|
|
240
|
+
});
|
|
239
241
|
}
|
|
240
242
|
function not(filter) {
|
|
241
|
-
return (
|
|
243
|
+
return setFilterNode((context) => !filter(context), {
|
|
244
|
+
type: "not",
|
|
245
|
+
filter
|
|
246
|
+
});
|
|
242
247
|
}
|
|
243
248
|
function always() {
|
|
244
|
-
return () => true;
|
|
249
|
+
return createPipelineFilter(always, [], () => true);
|
|
245
250
|
}
|
|
246
251
|
function never() {
|
|
247
|
-
return () => false;
|
|
252
|
+
return createPipelineFilter(never, [], () => false);
|
|
248
253
|
}
|
|
249
|
-
|
|
250
254
|
//#endregion
|
|
251
255
|
//#region src/pipeline.ts
|
|
252
256
|
/**
|
|
@@ -288,7 +292,6 @@ function definePipeline(options) {
|
|
|
288
292
|
strict: options.strict ?? false,
|
|
289
293
|
concurrency: options.concurrency ?? 4,
|
|
290
294
|
fallback: options.fallback,
|
|
291
|
-
onEvent: options.onEvent,
|
|
292
295
|
dag: dagResult.dag,
|
|
293
296
|
tags: options.tags ?? []
|
|
294
297
|
};
|
|
@@ -302,13 +305,11 @@ function getPipelineRouteIds(pipeline) {
|
|
|
302
305
|
function getPipelineSourceIds(pipeline) {
|
|
303
306
|
return pipeline.inputs.map((source) => source.id);
|
|
304
307
|
}
|
|
305
|
-
|
|
306
308
|
//#endregion
|
|
307
309
|
//#region src/route.ts
|
|
308
310
|
function definePipelineRoute(definition) {
|
|
309
311
|
return definition;
|
|
310
312
|
}
|
|
311
|
-
|
|
312
313
|
//#endregion
|
|
313
314
|
//#region src/utils/arrays.ts
|
|
314
315
|
/**
|
|
@@ -333,6 +334,5 @@ function splitMinFields(line, delimiter, minFields) {
|
|
|
333
334
|
const parts = line.split(delimiter);
|
|
334
335
|
return parts.length >= minFields ? parts : null;
|
|
335
336
|
}
|
|
336
|
-
|
|
337
337
|
//#endregion
|
|
338
|
-
export { always, and, applyTransforms, buildDAG, byDir, byExt, byGlob, byName, byPath, byProp, bySource,
|
|
338
|
+
export { FILTER_NODE, always, and, applyTransforms, buildDAG, byDir, byExt, byGlob, byName, byPath, byProp, bySource, createPipelineFilter, createRouteDependency, definePipeline, definePipelineRoute, definePipelineSource, definePipelineTransform, filesystemSink, getExecutionLayers, getFilterDescription, getPipelineRouteIds, getPipelineSourceIds, isPipelineDefinition, isPipelineOutputSource, isRouteDependency, never, normalizeRouteOutputs, not, or, parseDependency, pipelineOutputSource, resolveMultipleSourceFiles, resolveSourceFiles, splitMinFields, splitTwoFields };
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { c as FilesystemOutputSinkDefinition, d as RouteOutputDefinition, f as RouteOutputPathContext, h as normalizeRouteOutputs, l as NormalizedRouteOutputDefinition, m as filesystemSink, p as RouteOutputPathResolver, u as OutputSinkDefinition } from "../route-BT-OXkF-.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/outputs/resolve.d.ts
|
|
4
|
+
interface ResolvedOutputDestination {
|
|
5
|
+
locator: string;
|
|
6
|
+
displayLocator: string;
|
|
7
|
+
}
|
|
8
|
+
declare const DEFAULT_FALLBACK_OUTPUTS: readonly NormalizedRouteOutputDefinition[];
|
|
9
|
+
declare function getOutputProperty(output: unknown): string | undefined;
|
|
10
|
+
declare function resolveOutputDestination(definition: NormalizedRouteOutputDefinition, ctx: RouteOutputPathContext, resolvePath?: (base: string, relative: string) => string): ResolvedOutputDestination;
|
|
11
|
+
declare function renderOutputPathTemplate(template: string, ctx: RouteOutputPathContext): string;
|
|
12
|
+
declare function propertyToKebab(value: string): string;
|
|
13
|
+
//#endregion
|
|
14
|
+
//#region src/outputs/serialize.d.ts
|
|
15
|
+
declare function serializeOutputValue(value: unknown, format: "json" | "text"): string;
|
|
16
|
+
//#endregion
|
|
17
|
+
export { DEFAULT_FALLBACK_OUTPUTS, type FilesystemOutputSinkDefinition, type NormalizedRouteOutputDefinition, type OutputSinkDefinition, type ResolvedOutputDestination, type RouteOutputDefinition, type RouteOutputPathContext, type RouteOutputPathResolver, filesystemSink, getOutputProperty, normalizeRouteOutputs, propertyToKebab, renderOutputPathTemplate, resolveOutputDestination, serializeOutputValue };
|
|
@@ -0,0 +1,73 @@
|
|
|
1
|
+
import { n as normalizeRouteOutputs, t as filesystemSink } from "../types-BxE_sFho.mjs";
|
|
2
|
+
//#region src/outputs/resolve.ts
|
|
3
|
+
const DEFAULT_FALLBACK_OUTPUTS = [{
|
|
4
|
+
id: "fallback-output",
|
|
5
|
+
format: "json"
|
|
6
|
+
}];
|
|
7
|
+
const KEBAB_WORD_RE = /[a-z0-9]+/g;
|
|
8
|
+
const LEADING_SLASHES_RE = /^\/+/;
|
|
9
|
+
const TEMPLATE_TOKEN_RE = /\{([^{}]+)\}/g;
|
|
10
|
+
function getOutputProperty(output) {
|
|
11
|
+
if (typeof output !== "object" || output == null) return;
|
|
12
|
+
if ("property" in output && typeof output.property === "string") return output.property;
|
|
13
|
+
}
|
|
14
|
+
function resolveOutputDestination(definition, ctx, resolvePath) {
|
|
15
|
+
if (definition.path) {
|
|
16
|
+
const relativeLocator = typeof definition.path === "function" ? definition.path(ctx) : renderOutputPathTemplate(definition.path, ctx);
|
|
17
|
+
return createDestination(definition.sink, relativeLocator, resolvePath);
|
|
18
|
+
}
|
|
19
|
+
const property = ctx.property ?? "output";
|
|
20
|
+
const defaultRelative = `${ctx.routeId}/${propertyToKebab(property)}-${ctx.outputIndex}.${definition.format === "text" ? "txt" : "json"}`;
|
|
21
|
+
return createDestination(definition.sink, defaultRelative, resolvePath);
|
|
22
|
+
}
|
|
23
|
+
function createDestination(sink, relativeLocator, resolvePath) {
|
|
24
|
+
const normalizedRelative = relativeLocator.replaceAll("\\", "/");
|
|
25
|
+
if (normalizedRelative.startsWith("/") || normalizedRelative.split("/").includes("..")) throw new Error(`Output path must stay within the configured sink: "${relativeLocator}"`);
|
|
26
|
+
if (sink?.type === "filesystem") {
|
|
27
|
+
const resolved = sink.baseDir ? resolvePath?.(sink.baseDir, normalizedRelative) ?? `${sink.baseDir}/${normalizedRelative}` : resolvePath?.("", normalizedRelative) ?? normalizedRelative;
|
|
28
|
+
return {
|
|
29
|
+
locator: resolved,
|
|
30
|
+
displayLocator: resolved
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
const stripped = normalizedRelative.replace(LEADING_SLASHES_RE, "");
|
|
34
|
+
return {
|
|
35
|
+
locator: `memory://${stripped}`,
|
|
36
|
+
displayLocator: `memory://${stripped}`
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
function renderOutputPathTemplate(template, ctx) {
|
|
40
|
+
return template.replaceAll(TEMPLATE_TOKEN_RE, (_match, token) => {
|
|
41
|
+
const [rawKey = "", transform] = String(token).split(":");
|
|
42
|
+
const value = resolveTemplateValue(rawKey, ctx);
|
|
43
|
+
if (value == null) return "";
|
|
44
|
+
const stringValue = String(value);
|
|
45
|
+
switch (transform) {
|
|
46
|
+
case "lower": return stringValue.toLowerCase();
|
|
47
|
+
case "kebab": return propertyToKebab(stringValue);
|
|
48
|
+
default: return stringValue;
|
|
49
|
+
}
|
|
50
|
+
});
|
|
51
|
+
}
|
|
52
|
+
function resolveTemplateValue(key, ctx) {
|
|
53
|
+
switch (key) {
|
|
54
|
+
case "version": return ctx.version;
|
|
55
|
+
case "routeId": return ctx.routeId;
|
|
56
|
+
case "property": return ctx.property;
|
|
57
|
+
case "outputIndex": return ctx.outputIndex;
|
|
58
|
+
case "file.name": return ctx.file.name;
|
|
59
|
+
case "file.path": return ctx.file.path;
|
|
60
|
+
default: return;
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
function propertyToKebab(value) {
|
|
64
|
+
return (value.toLowerCase().match(KEBAB_WORD_RE) ?? []).join("-");
|
|
65
|
+
}
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/outputs/serialize.ts
|
|
68
|
+
function serializeOutputValue(value, format) {
|
|
69
|
+
if (format === "text") return typeof value === "string" ? value : JSON.stringify(value, null, 2) ?? "null";
|
|
70
|
+
return JSON.stringify(value, null, 2) ?? "null";
|
|
71
|
+
}
|
|
72
|
+
//#endregion
|
|
73
|
+
export { DEFAULT_FALLBACK_OUTPUTS, filesystemSink, getOutputProperty, normalizeRouteOutputs, propertyToKebab, renderOutputPathTemplate, resolveOutputDestination, serializeOutputValue };
|
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
import { a as ParsedRow, d as ResolvedEntry, l as PipelineLogger, n as FileContext, o as ParserFn, s as PipelineFilter, u as PropertyJson } from "./types-B_R0NiDI.mjs";
|
|
2
|
+
import { a as PipelineTransformDefinition, n as ChainTransforms, t as AnyPipelineTransformDefinition } from "./transform-BkBLzZAP.mjs";
|
|
3
|
+
|
|
4
|
+
//#region src/dependencies.d.ts
|
|
5
|
+
type RouteDependency = `route:${string}`;
|
|
6
|
+
type PipelineDependency = RouteDependency;
|
|
7
|
+
interface ParsedRouteDependency {
|
|
8
|
+
type: "route";
|
|
9
|
+
routeId: string;
|
|
10
|
+
}
|
|
11
|
+
type ParsedDependency = ParsedRouteDependency;
|
|
12
|
+
type ParseDependencyType<T extends string> = T extends `route:${infer RouteId}` ? {
|
|
13
|
+
type: "route";
|
|
14
|
+
routeId: RouteId;
|
|
15
|
+
} : never;
|
|
16
|
+
type ExtractRouteDependencies<T extends readonly PipelineDependency[]> = { [K in keyof T]: T[K] extends `route:${infer RouteId}` ? RouteId : never }[number];
|
|
17
|
+
declare function parseDependency(dep: PipelineDependency): ParsedDependency;
|
|
18
|
+
declare function isRouteDependency(dep: PipelineDependency): dep is RouteDependency;
|
|
19
|
+
declare function createRouteDependency(routeId: string): RouteDependency;
|
|
20
|
+
//#endregion
|
|
21
|
+
//#region src/outputs/types.d.ts
|
|
22
|
+
interface FilesystemOutputSinkDefinition {
|
|
23
|
+
type: "filesystem";
|
|
24
|
+
baseDir?: string;
|
|
25
|
+
}
|
|
26
|
+
type OutputSinkDefinition = FilesystemOutputSinkDefinition;
|
|
27
|
+
interface RouteOutputPathContext {
|
|
28
|
+
version: string;
|
|
29
|
+
routeId: string;
|
|
30
|
+
file: FileContext;
|
|
31
|
+
output: unknown;
|
|
32
|
+
property?: string;
|
|
33
|
+
outputIndex: number;
|
|
34
|
+
}
|
|
35
|
+
type RouteOutputPathResolver = (ctx: RouteOutputPathContext) => string;
|
|
36
|
+
interface RouteOutputDefinition {
|
|
37
|
+
/**
|
|
38
|
+
* Stable identifier for this output destination within the route.
|
|
39
|
+
*/
|
|
40
|
+
id?: string;
|
|
41
|
+
/**
|
|
42
|
+
* Destination sink to use when the output should be persisted.
|
|
43
|
+
* When omitted, the output remains available for the run only.
|
|
44
|
+
*/
|
|
45
|
+
sink?: OutputSinkDefinition;
|
|
46
|
+
/**
|
|
47
|
+
* Output format used by built-in sinks.
|
|
48
|
+
* @default "json"
|
|
49
|
+
*/
|
|
50
|
+
format?: "json" | "text";
|
|
51
|
+
/**
|
|
52
|
+
* Preferred explicit path for the output.
|
|
53
|
+
*/
|
|
54
|
+
path?: string | RouteOutputPathResolver;
|
|
55
|
+
}
|
|
56
|
+
declare function filesystemSink(options?: Omit<FilesystemOutputSinkDefinition, "type">): FilesystemOutputSinkDefinition;
|
|
57
|
+
interface NormalizedRouteOutputDefinition {
|
|
58
|
+
id: string;
|
|
59
|
+
sink?: OutputSinkDefinition;
|
|
60
|
+
format: "json" | "text";
|
|
61
|
+
path?: RouteOutputDefinition["path"];
|
|
62
|
+
}
|
|
63
|
+
declare function normalizeRouteOutputs(route: PipelineRouteDefinition): NormalizedRouteOutputDefinition[];
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/route.d.ts
|
|
66
|
+
interface ResolveContext<TDepends extends readonly PipelineDependency[] = readonly PipelineDependency[]> {
|
|
67
|
+
version: string;
|
|
68
|
+
file: FileContext;
|
|
69
|
+
logger: PipelineLogger;
|
|
70
|
+
getRouteData: <T = unknown>(routeId: ExtractRouteDependencies<TDepends>) => readonly T[];
|
|
71
|
+
normalizeEntries: (entries: ResolvedEntry[]) => ResolvedEntry[];
|
|
72
|
+
now: () => string;
|
|
73
|
+
}
|
|
74
|
+
type ResolverFn<TOutput = PropertyJson[], TDepends extends readonly PipelineDependency[] = readonly PipelineDependency[]> = (ctx: ResolveContext<TDepends>, rows: AsyncIterable<ParsedRow>) => Promise<TOutput>;
|
|
75
|
+
type PipelineRouteResolver<TDepends extends readonly PipelineDependency[], TTransforms extends readonly AnyPipelineTransformDefinition[], TOutput> = (ctx: ResolveContext<TDepends>, rows: AsyncIterable<TTransforms extends readonly [] ? ParsedRow : ChainTransforms<ParsedRow, TTransforms>>) => Promise<TOutput>;
|
|
76
|
+
interface PipelineRouteDefinition<TId extends string = string, TDepends extends readonly PipelineDependency[] = readonly PipelineDependency[], TTransforms extends readonly AnyPipelineTransformDefinition[] = readonly [], TOutput = PropertyJson[]> {
|
|
77
|
+
id: TId;
|
|
78
|
+
filter: PipelineFilter;
|
|
79
|
+
depends?: TDepends;
|
|
80
|
+
parser: ParserFn;
|
|
81
|
+
transforms?: TTransforms;
|
|
82
|
+
resolver: PipelineRouteResolver<TDepends, TTransforms, TOutput>;
|
|
83
|
+
outputs?: RouteOutputDefinition[];
|
|
84
|
+
cache?: boolean;
|
|
85
|
+
}
|
|
86
|
+
type AnyPipelineRouteDefinition = PipelineRouteDefinition<any, any, any, any>;
|
|
87
|
+
declare function definePipelineRoute<const TId extends string, const TDepends extends readonly PipelineDependency[] = readonly [], const TTransforms extends readonly AnyPipelineTransformDefinition[] = readonly [], TOutput = PropertyJson[]>(definition: PipelineRouteDefinition<TId, TDepends, TTransforms, TOutput>): PipelineRouteDefinition<TId, TDepends, TTransforms, TOutput>;
|
|
88
|
+
type InferRoute<T> = T extends PipelineRouteDefinition<infer TId, infer TDepends, infer TTransforms extends readonly PipelineTransformDefinition<any, any>[], infer TOutput> ? {
|
|
89
|
+
id: TId;
|
|
90
|
+
depends: TDepends;
|
|
91
|
+
transforms: TTransforms;
|
|
92
|
+
output: TOutput;
|
|
93
|
+
} : never;
|
|
94
|
+
type InferRoutesOutput<T extends readonly AnyPipelineRouteDefinition[]> = T[number] extends PipelineRouteDefinition<any, any, any, infer TOutput> ? TOutput extends unknown[] ? TOutput[number] : TOutput : never;
|
|
95
|
+
//#endregion
|
|
96
|
+
export { parseDependency as C, isRouteDependency as S, ParseDependencyType as _, ResolveContext as a, PipelineDependency as b, FilesystemOutputSinkDefinition as c, RouteOutputDefinition as d, RouteOutputPathContext as f, ExtractRouteDependencies as g, normalizeRouteOutputs as h, PipelineRouteDefinition as i, NormalizedRouteOutputDefinition as l, filesystemSink as m, InferRoute as n, ResolverFn as o, RouteOutputPathResolver as p, InferRoutesOutput as r, definePipelineRoute as s, AnyPipelineRouteDefinition as t, OutputSinkDefinition as u, ParsedDependency as v, createRouteDependency as x, ParsedRouteDependency as y };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { n as FileContext, s as PipelineFilter } from "./types-
|
|
1
|
+
import { l as PipelineLogger, n as FileContext, s as PipelineFilter } from "./types-B_R0NiDI.mjs";
|
|
2
2
|
|
|
3
3
|
//#region src/source.d.ts
|
|
4
4
|
interface StreamOptions {
|
|
@@ -22,16 +22,33 @@ interface PipelineSourceDefinition<TId extends string = string> {
|
|
|
22
22
|
backend: SourceBackend;
|
|
23
23
|
includes?: PipelineFilter;
|
|
24
24
|
excludes?: PipelineFilter;
|
|
25
|
+
kind?: "standard" | "pipeline-output";
|
|
26
|
+
}
|
|
27
|
+
interface PipelineOutputSourceDefinition<TId extends string = string> extends PipelineSourceDefinition<TId> {
|
|
28
|
+
kind: "pipeline-output";
|
|
29
|
+
pipelineId: string;
|
|
30
|
+
outputId?: string;
|
|
25
31
|
}
|
|
26
32
|
interface SourceFileContext extends FileContext {
|
|
27
33
|
source: {
|
|
28
34
|
id: string;
|
|
29
35
|
};
|
|
30
36
|
}
|
|
37
|
+
interface ResolveSourceContext {
|
|
38
|
+
logger: PipelineLogger;
|
|
39
|
+
}
|
|
31
40
|
declare function definePipelineSource<const TId extends string>(definition: PipelineSourceDefinition<TId>): PipelineSourceDefinition<TId>;
|
|
32
|
-
declare function
|
|
33
|
-
|
|
41
|
+
declare function pipelineOutputSource<const TId extends string = string>(options: {
|
|
42
|
+
id?: TId;
|
|
43
|
+
pipelineId: string;
|
|
44
|
+
outputId?: string;
|
|
45
|
+
}): PipelineOutputSourceDefinition<TId>;
|
|
46
|
+
declare function isPipelineOutputSource(source: PipelineSourceDefinition): source is PipelineOutputSourceDefinition;
|
|
47
|
+
declare function resolveSourceFiles(source: PipelineSourceDefinition, version: string, {
|
|
48
|
+
logger
|
|
49
|
+
}: ResolveSourceContext): Promise<SourceFileContext[]>;
|
|
50
|
+
declare function resolveMultipleSourceFiles(sources: PipelineSourceDefinition[] | readonly PipelineSourceDefinition[], version: string, context: ResolveSourceContext): Promise<SourceFileContext[]>;
|
|
34
51
|
type InferSourceId<T> = T extends PipelineSourceDefinition<infer TId> ? TId : never;
|
|
35
52
|
type InferSourceIds<T extends readonly PipelineSourceDefinition[]> = { [K in keyof T]: InferSourceId<T[K]> }[number];
|
|
36
53
|
//#endregion
|
|
37
|
-
export {
|
|
54
|
+
export { PipelineSourceDefinition as a, SourceFileContext as c, isPipelineOutputSource as d, pipelineOutputSource as f, PipelineOutputSourceDefinition as i, StreamOptions as l, resolveSourceFiles as m, InferSourceId as n, ResolveSourceContext as o, resolveMultipleSourceFiles as p, InferSourceIds as r, SourceBackend as s, FileMetadata as t, definePipelineSource as u };
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
//#region src/source.ts
|
|
2
|
+
function definePipelineSource(definition) {
|
|
3
|
+
return definition;
|
|
4
|
+
}
|
|
5
|
+
const unsupportedPipelineOutputBackend = {
|
|
6
|
+
listFiles: async () => {
|
|
7
|
+
throw new Error("Pipeline output sources are resolved by the executor and cannot be listed directly.");
|
|
8
|
+
},
|
|
9
|
+
readFile: async () => {
|
|
10
|
+
throw new Error("Pipeline output sources are resolved by the executor and cannot be read directly.");
|
|
11
|
+
}
|
|
12
|
+
};
|
|
13
|
+
function pipelineOutputSource(options) {
|
|
14
|
+
return {
|
|
15
|
+
id: options.id ?? `pipeline:${options.pipelineId}${options.outputId ? `:${options.outputId}` : ""}`,
|
|
16
|
+
kind: "pipeline-output",
|
|
17
|
+
pipelineId: options.pipelineId,
|
|
18
|
+
outputId: options.outputId,
|
|
19
|
+
backend: unsupportedPipelineOutputBackend
|
|
20
|
+
};
|
|
21
|
+
}
|
|
22
|
+
function isPipelineOutputSource(source) {
|
|
23
|
+
return source.kind === "pipeline-output";
|
|
24
|
+
}
|
|
25
|
+
async function resolveSourceFiles(source, version, { logger }) {
|
|
26
|
+
if (isPipelineOutputSource(source)) return [];
|
|
27
|
+
return (await source.backend.listFiles(version)).filter((file) => {
|
|
28
|
+
const ctx = {
|
|
29
|
+
file,
|
|
30
|
+
logger
|
|
31
|
+
};
|
|
32
|
+
if (source.includes && !source.includes(ctx)) return false;
|
|
33
|
+
if (source.excludes && source.excludes(ctx)) return false;
|
|
34
|
+
return true;
|
|
35
|
+
}).map((file) => ({
|
|
36
|
+
...file,
|
|
37
|
+
source: { id: source.id }
|
|
38
|
+
}));
|
|
39
|
+
}
|
|
40
|
+
async function resolveMultipleSourceFiles(sources, version, context) {
|
|
41
|
+
const filesByPath = /* @__PURE__ */ new Map();
|
|
42
|
+
for (const source of sources) {
|
|
43
|
+
const files = await resolveSourceFiles(source, version, context);
|
|
44
|
+
for (const file of files) filesByPath.set(file.path, file);
|
|
45
|
+
}
|
|
46
|
+
return [...filesByPath.values()];
|
|
47
|
+
}
|
|
48
|
+
//#endregion
|
|
49
|
+
export { resolveSourceFiles as a, resolveMultipleSourceFiles as i, isPipelineOutputSource as n, pipelineOutputSource as r, definePipelineSource as t };
|
package/dist/sources/index.d.mts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { n as FileContext } from "../types-
|
|
2
|
-
import { a as
|
|
1
|
+
import { n as FileContext } from "../types-B_R0NiDI.mjs";
|
|
2
|
+
import { a as PipelineSourceDefinition, s as SourceBackend } from "../source-Bw_42mA2.mjs";
|
|
3
3
|
|
|
4
4
|
//#region src/sources/http.d.ts
|
|
5
5
|
interface HttpBackendOptions {
|
package/dist/sources/index.mjs
CHANGED
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
import { t as definePipelineSource } from "../source-
|
|
2
|
-
|
|
1
|
+
import { t as definePipelineSource } from "../source-UYQsDb7S.mjs";
|
|
3
2
|
//#region src/sources/http.ts
|
|
4
3
|
const UNICODE_ORG_BASE_URL = "https://www.unicode.org/Public/";
|
|
5
4
|
function createHttpBackend(options) {
|
|
@@ -60,13 +59,12 @@ function createUnicodeOrgSource(id) {
|
|
|
60
59
|
});
|
|
61
60
|
}
|
|
62
61
|
const unicodeOrgSource = createUnicodeOrgSource();
|
|
63
|
-
|
|
64
62
|
//#endregion
|
|
65
63
|
//#region src/sources/memory.ts
|
|
66
64
|
function getFileContext(version, file) {
|
|
67
65
|
const path = file.path;
|
|
68
66
|
const parts = path.split("/");
|
|
69
|
-
const name = parts
|
|
67
|
+
const name = parts.at(-1);
|
|
70
68
|
if (!name) throw new Error(`Invalid file path: ${file.path}`);
|
|
71
69
|
const extIndex = name.lastIndexOf(".");
|
|
72
70
|
const ext = extIndex >= 0 ? name.slice(extIndex) : "";
|
|
@@ -108,6 +106,5 @@ function createMemorySource(options) {
|
|
|
108
106
|
backend: createMemoryBackend({ files: options?.files ?? {} })
|
|
109
107
|
});
|
|
110
108
|
}
|
|
111
|
-
|
|
112
109
|
//#endregion
|
|
113
|
-
export { UNICODE_ORG_BASE_URL, createHttpBackend, createHttpSource, createMemoryBackend, createMemorySource, createUnicodeOrgSource, unicodeOrgSource };
|
|
110
|
+
export { UNICODE_ORG_BASE_URL, createHttpBackend, createHttpSource, createMemoryBackend, createMemorySource, createUnicodeOrgSource, unicodeOrgSource };
|