@sanoma-ai/workflows 0.9.1 → 0.10.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/README.md +193 -50
- package/SECRET-SUPPORT.md +33 -0
- package/dist/apply-steps.js +5 -2
- package/dist/apply-steps.js.map +1 -1
- package/dist/apply.d.ts +3 -0
- package/dist/apply.js +27 -13
- package/dist/apply.js.map +1 -1
- package/dist/approvals.d.ts +1 -0
- package/dist/approvals.js +6 -1
- package/dist/approvals.js.map +1 -1
- package/dist/apps.d.ts +13 -24
- package/dist/apps.js +69 -68
- package/dist/apps.js.map +1 -1
- package/dist/ast.d.ts +9 -7
- package/dist/ast.js +2 -0
- package/dist/ast.js.map +1 -1
- package/dist/authentication.d.ts +54 -0
- package/dist/authentication.js +138 -0
- package/dist/authentication.js.map +1 -0
- package/dist/call-workflow.d.ts +5 -0
- package/dist/call-workflow.js +4 -3
- package/dist/call-workflow.js.map +1 -1
- package/dist/call.d.ts +3 -2
- package/dist/call.js +36 -7
- package/dist/call.js.map +1 -1
- package/dist/cedar.js +14 -1
- package/dist/cedar.js.map +1 -1
- package/dist/change-steps.js +7 -5
- package/dist/change-steps.js.map +1 -1
- package/dist/change.d.ts +7 -0
- package/dist/change.js +7 -0
- package/dist/change.js.map +1 -1
- package/dist/client.d.ts +62 -10
- package/dist/client.js +272 -47
- package/dist/client.js.map +1 -1
- package/dist/collection.d.ts +7 -0
- package/dist/collection.js +5 -2
- package/dist/collection.js.map +1 -1
- package/dist/config.d.ts +16 -4
- package/dist/config.js +89 -21
- package/dist/config.js.map +1 -1
- package/dist/connection.d.ts +389 -0
- package/dist/connection.js +657 -0
- package/dist/connection.js.map +1 -0
- package/dist/credentials.d.ts +7 -53
- package/dist/credentials.js +84 -247
- package/dist/credentials.js.map +1 -1
- package/dist/db.js +34 -2
- package/dist/db.js.map +1 -1
- package/dist/define.d.ts +9 -2
- package/dist/define.js.map +1 -1
- package/dist/definitions.d.ts +20 -0
- package/dist/definitions.js +16 -0
- package/dist/definitions.js.map +1 -0
- package/dist/deployment-key.d.ts +2 -0
- package/dist/deployment-key.js +22 -0
- package/dist/deployment-key.js.map +1 -0
- package/dist/describe.d.ts +15 -175
- package/dist/describe.js +122 -35
- package/dist/describe.js.map +1 -1
- package/dist/description.d.ts +532 -0
- package/dist/description.js +381 -0
- package/dist/description.js.map +1 -0
- package/dist/direct.js +7 -0
- package/dist/direct.js.map +1 -1
- package/dist/drift.d.ts +1 -1
- package/dist/drift.js +1 -1
- package/dist/drift.js.map +1 -1
- package/dist/env.d.ts +2 -0
- package/dist/env.js +2 -2
- package/dist/env.js.map +1 -1
- package/dist/fake.d.ts +13 -1
- package/dist/fake.js +70 -0
- package/dist/fake.js.map +1 -1
- package/dist/index.d.ts +11 -3
- package/dist/index.js +10 -2
- package/dist/index.js.map +1 -1
- package/dist/ledger.d.ts +2 -0
- package/dist/ledger.js +1 -1
- package/dist/ledger.js.map +1 -1
- package/dist/lint.d.ts +0 -9
- package/dist/lint.js +2 -17
- package/dist/lint.js.map +1 -1
- package/dist/load.d.ts +85 -0
- package/dist/load.js +391 -0
- package/dist/load.js.map +1 -0
- package/dist/lockfile.d.ts +2 -0
- package/dist/lockfile.js +8 -3
- package/dist/lockfile.js.map +1 -1
- package/dist/op.d.ts +22 -5
- package/dist/op.js +20 -2
- package/dist/op.js.map +1 -1
- package/dist/outline.d.ts +5 -0
- package/dist/outline.js +46 -5
- package/dist/outline.js.map +1 -1
- package/dist/paths.d.ts +18 -2
- package/dist/paths.js +19 -7
- package/dist/paths.js.map +1 -1
- package/dist/plugin.d.ts +0 -11
- package/dist/plugin.js +3 -18
- package/dist/plugin.js.map +1 -1
- package/dist/policy.d.ts +2 -0
- package/dist/policy.js.map +1 -1
- package/dist/resource.d.ts +10 -4
- package/dist/resource.js +11 -4
- package/dist/resource.js.map +1 -1
- package/dist/resources.d.ts +33 -76
- package/dist/resources.js +219 -227
- package/dist/resources.js.map +1 -1
- package/dist/run.d.ts +4 -0
- package/dist/run.js.map +1 -1
- package/dist/sandbox.d.ts +5 -2
- package/dist/sandbox.js +56 -7
- package/dist/sandbox.js.map +1 -1
- package/dist/scenario.d.ts +5 -0
- package/dist/scenario.js +3 -2
- package/dist/scenario.js.map +1 -1
- package/dist/scenarios.js +7 -1
- package/dist/scenarios.js.map +1 -1
- package/dist/schema.js +8 -0
- package/dist/schema.js.map +1 -1
- package/dist/secret-store-check.d.ts +11 -0
- package/dist/secret-store-check.js +76 -0
- package/dist/secret-store-check.js.map +1 -0
- package/dist/secret-store.d.ts +106 -0
- package/dist/secret-store.js +228 -0
- package/dist/secret-store.js.map +1 -0
- package/dist/secret.d.ts +2 -0
- package/dist/secret.js +32 -0
- package/dist/secret.js.map +1 -1
- package/dist/shared.d.ts +21 -11
- package/dist/shared.js +41 -7
- package/dist/shared.js.map +1 -1
- package/dist/sites.d.ts +4 -93
- package/dist/sites.js +76 -84
- package/dist/sites.js.map +1 -1
- package/dist/steps.d.ts +3 -0
- package/dist/steps.js.map +1 -1
- package/dist/version.d.ts +2 -1
- package/dist/version.js +2 -1
- package/dist/version.js.map +1 -1
- package/dist/wakeup-driver.js +15 -6
- package/dist/wakeup-driver.js.map +1 -1
- package/dist/worker.js +12 -8
- package/dist/worker.js.map +1 -1
- package/dist/writer.d.ts +53 -14
- package/dist/writer.js +113 -43
- package/dist/writer.js.map +1 -1
- package/oxlint.json +1 -5
- package/package.json +6 -1
- package/src/apply-steps.ts +5 -2
- package/src/apply.ts +54 -21
- package/src/approvals.ts +7 -1
- package/src/apps.ts +71 -86
- package/src/ast.ts +6 -6
- package/src/authentication.ts +191 -0
- package/src/call-workflow.ts +5 -4
- package/src/call.ts +52 -9
- package/src/cedar.ts +14 -1
- package/src/change-steps.ts +7 -4
- package/src/change.ts +10 -0
- package/src/client.ts +346 -45
- package/src/collection.ts +10 -2
- package/src/config.ts +107 -19
- package/src/connection.ts +912 -0
- package/src/credentials.ts +94 -281
- package/src/db.ts +34 -2
- package/src/define.ts +7 -2
- package/src/definitions.ts +31 -0
- package/src/deployment-key.ts +23 -0
- package/src/describe.ts +150 -227
- package/src/description.ts +426 -0
- package/src/direct.ts +7 -0
- package/src/drift.ts +10 -2
- package/src/env.ts +4 -2
- package/src/fake.ts +71 -0
- package/src/index.ts +53 -1
- package/src/ledger.ts +3 -1
- package/src/lint.ts +2 -17
- package/src/load.ts +466 -0
- package/src/lockfile.ts +10 -3
- package/src/op.ts +41 -7
- package/src/outline.ts +53 -7
- package/src/paths.ts +21 -6
- package/src/plugin.ts +3 -24
- package/src/policy.ts +2 -0
- package/src/resource.ts +24 -6
- package/src/resources.ts +246 -301
- package/src/run.ts +4 -0
- package/src/sandbox.ts +61 -7
- package/src/scenario.ts +24 -6
- package/src/scenarios.ts +7 -1
- package/src/schema.ts +10 -0
- package/src/secret-store-check.ts +93 -0
- package/src/secret-store.ts +314 -0
- package/src/secret.ts +29 -0
- package/src/shared.ts +44 -10
- package/src/sites.ts +85 -179
- package/src/steps.ts +3 -2
- package/src/version.ts +2 -1
- package/src/wakeup-driver.ts +22 -6
- package/src/worker.ts +12 -8
- package/src/writer.ts +145 -56
- package/dist/datafile.d.ts +0 -97
- package/dist/datafile.js +0 -479
- package/dist/datafile.js.map +0 -1
- package/src/datafile.ts +0 -601
package/dist/load.js
ADDED
|
@@ -0,0 +1,391 @@
|
|
|
1
|
+
import { existsSync, readFileSync, realpathSync, statSync } from "node:fs";
|
|
2
|
+
import { createRequire, registerHooks } from "node:module";
|
|
3
|
+
import { dirname, isAbsolute, join, relative, sep } from "node:path";
|
|
4
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
5
|
+
import { collectionIn } from "./collection.js";
|
|
6
|
+
import { callerFile } from "./define.js";
|
|
7
|
+
import { defineApp, defineSite } from "./definitions.js";
|
|
8
|
+
import { VENDOR } from "./op.js";
|
|
9
|
+
import { APPS_DIR, appOfPath, DATA_ENTRIES, inside, relPath, SECRET_ENTRIES, SITE_ENTRIES } from "./paths.js";
|
|
10
|
+
import { isDeclared, isObject, joinPath, resourceTypesOf } from "./resource.js";
|
|
11
|
+
import { secret } from "./secret.js";
|
|
12
|
+
import { errorMessage } from "./shared.js";
|
|
13
|
+
// A company's files, loaded: synchronously (`require` of an ES module, Node's type stripping and
|
|
14
|
+
// `module.registerHooks`), since what reads them is (`describeConfig`, `readPeople`). Each load
|
|
15
|
+
// is a *generation*: its files are modules of their own (`file:…?sanoma-load=<id>`), so an edit
|
|
16
|
+
// is read once a new generation starts, and what they import from the runtime (constructors,
|
|
17
|
+
// `collection`, `defineSite`, `defineApp`) is served from the loader's own objects, which record
|
|
18
|
+
// where each value was made. A superseded generation's modules stay in Node's cache: each edit
|
|
19
|
+
// costs one copy of the files it read.
|
|
20
|
+
/** The scheme of the loader's own modules: an entry, `sanoma-load:<id>/<file URL>`, and a runtime module, `sanoma-load:<id>/<specifier>`. */
|
|
21
|
+
const SCHEME = "sanoma-load:";
|
|
22
|
+
/** The query that tags a company file with its generation: `file:///…/github.ts?sanoma-load=<id>`. */
|
|
23
|
+
const QUERY = "sanoma-load";
|
|
24
|
+
const registry = (globalThis[Symbol.for("sanoma.load")] ??= {
|
|
25
|
+
generations: new Map(),
|
|
26
|
+
seq: 0,
|
|
27
|
+
ids: new WeakMap(),
|
|
28
|
+
made: new WeakMap(),
|
|
29
|
+
});
|
|
30
|
+
const require = createRequire(import.meta.url);
|
|
31
|
+
/** Where `value` was made, when a company file made it with a constructor the loader served. */
|
|
32
|
+
export const madeOf = (value) => typeof value === "object" && value !== null ? registry.made.get(value) : undefined;
|
|
33
|
+
/** Where `defineApp` comes from, served only to an app's `app.ts`. */
|
|
34
|
+
const APP_ENTRIES = new Set(["sanoma", "@sanoma-ai/workflows"]);
|
|
35
|
+
/**
|
|
36
|
+
* Loads `paths` (absolute, under `root`) as the generation of `root` and the constructors of
|
|
37
|
+
* `connectors` (`types`, by default theirs) has them, and says what each gave, by its path
|
|
38
|
+
* relative to the root with `/`, sorted. The same generation, and the same answer for the same
|
|
39
|
+
* paths, while no file it read, nor any file's directory, changed (by size and modification time:
|
|
40
|
+
* one `stat` each); else a new one, so a caller may key what it makes of the answer by it (and
|
|
41
|
+
* never changes it). `only` loads only the files whose text it passes; the answer is kept by its
|
|
42
|
+
* identity, so pass one function, not a new one per call.
|
|
43
|
+
*
|
|
44
|
+
* Served to the files, by specifier: `sanoma/resources` and `@sanoma-ai/workflows/resources`
|
|
45
|
+
* (`sanoma`, the constructors of the vendor `sanoma`, and `secret`); each connector's
|
|
46
|
+
* `<info.package>/resources` (its vendor's constructors, under its id); `sanoma/data` and
|
|
47
|
+
* `@sanoma-ai/workflows/data` (`collection`); `sanoma/site` and `@sanoma-ai/app/site`
|
|
48
|
+
* (`defineSite`); and to an app's `apps/<app>/app.ts` alone, `sanoma` and `@sanoma-ai/workflows`
|
|
49
|
+
* (`defineApp`). Anything else is resolved as Node does.
|
|
50
|
+
*/
|
|
51
|
+
export function loadModules(root, paths, connectors, { only, types = resourceTypesOf(connectors), } = {}) {
|
|
52
|
+
// Nothing to load, and a root that may not be there yet (a company not made): nothing to resolve.
|
|
53
|
+
if (!paths.length)
|
|
54
|
+
return new Map();
|
|
55
|
+
hook();
|
|
56
|
+
const real = realpathSync(root);
|
|
57
|
+
const gen = generationOf(real, connectors, types);
|
|
58
|
+
const files = paths.map((path) => join(real, relative(root, path)));
|
|
59
|
+
const byPaths = gen.answers.get(only ?? gen) ?? new Map();
|
|
60
|
+
gen.answers.set(only ?? gen, byPaths);
|
|
61
|
+
const key = files.join("\0");
|
|
62
|
+
const answered = byPaths.get(key);
|
|
63
|
+
if (answered)
|
|
64
|
+
return answered;
|
|
65
|
+
const answer = new Map();
|
|
66
|
+
for (const file of files) {
|
|
67
|
+
touch(gen, file);
|
|
68
|
+
if (only && !only(readFileSync(file, "utf8")))
|
|
69
|
+
continue;
|
|
70
|
+
const rel = relPath(gen.root, file);
|
|
71
|
+
const loaded = loadOne(gen, file, rel);
|
|
72
|
+
answer.set(rel, loaded);
|
|
73
|
+
if ("failedIn" in loaded)
|
|
74
|
+
answer.set(loaded.failedIn, gen.loaded.get(loaded.failedIn));
|
|
75
|
+
}
|
|
76
|
+
const result = new Map([...answer].toSorted(([a], [b]) => byOrder(a, b)));
|
|
77
|
+
// A value made in one file and exported by another is listed at the file that made it.
|
|
78
|
+
const owner = new Map();
|
|
79
|
+
for (const [rel, l] of result) {
|
|
80
|
+
if (!("exports" in l))
|
|
81
|
+
continue;
|
|
82
|
+
for (const [, value] of l.exports)
|
|
83
|
+
if (madeOf(value)?.file === rel)
|
|
84
|
+
owner.set(value, rel);
|
|
85
|
+
}
|
|
86
|
+
for (const [rel, l] of result) {
|
|
87
|
+
if (!("exports" in l))
|
|
88
|
+
continue;
|
|
89
|
+
const exports = l.exports
|
|
90
|
+
.filter(([, value]) => (owner.get(value) ?? rel) === rel)
|
|
91
|
+
.toSorted(([, a], [, b]) => byOrder(madeOf(a)?.seq ?? Infinity, madeOf(b)?.seq ?? Infinity));
|
|
92
|
+
result.set(rel, { exports });
|
|
93
|
+
}
|
|
94
|
+
byPaths.set(key, result);
|
|
95
|
+
answerGenerations.set(result, gen);
|
|
96
|
+
return result;
|
|
97
|
+
}
|
|
98
|
+
/**
|
|
99
|
+
* What `answer` (a `loadModules` answer) gave for `file`: its exports, or the error it threw (or a
|
|
100
|
+
* helper it imports threw) as a problem on one line, at the file that threw it; undefined when the
|
|
101
|
+
* answer does not have the file.
|
|
102
|
+
*/
|
|
103
|
+
export function exportsOf(answer, file) {
|
|
104
|
+
const loaded = answer.get(file);
|
|
105
|
+
if (loaded === undefined)
|
|
106
|
+
return undefined;
|
|
107
|
+
if ("failedIn" in loaded)
|
|
108
|
+
return exportsOf(answer, loaded.failedIn);
|
|
109
|
+
if ("exports" in loaded)
|
|
110
|
+
return loaded;
|
|
111
|
+
const { error, line, column } = loaded;
|
|
112
|
+
const message = errorMessage(error).replaceAll(/\s*\n\s*/g, " ");
|
|
113
|
+
return { problem: { file, ...(line !== undefined && { line, column: column ?? 1 }), message } };
|
|
114
|
+
}
|
|
115
|
+
/** The generation each answer is of. */
|
|
116
|
+
const answerGenerations = new WeakMap();
|
|
117
|
+
/** Every value the files of `answer` (a `loadModules` answer) made, exported or not, in the order made. */
|
|
118
|
+
export const madeWith = (answer) => (answerGenerations.get(answer)?.made ?? []).filter((value) => answer.has(madeOf(value).file));
|
|
119
|
+
/**
|
|
120
|
+
* The company files `answer` (a `loadModules` answer) was read from, by path relative to the root:
|
|
121
|
+
* its files and every company file they import, directly or not (or that another answer of its
|
|
122
|
+
* generation imported: never fewer).
|
|
123
|
+
*/
|
|
124
|
+
export const filesRead = (answer) => new Set([...answer.keys(), ...(answerGenerations.get(answer)?.imported ?? [])]);
|
|
125
|
+
/** One file of a generation, required once; an error placed at its own file, and reported there once. */
|
|
126
|
+
function loadOne(gen, file, rel) {
|
|
127
|
+
const done = gen.loaded.get(rel);
|
|
128
|
+
if (done)
|
|
129
|
+
return done;
|
|
130
|
+
let loaded;
|
|
131
|
+
try {
|
|
132
|
+
const { ns } = require(`${SCHEME}${gen.id}/${pathToFileURL(file).href}`);
|
|
133
|
+
loaded = { exports: Object.entries(ns) };
|
|
134
|
+
}
|
|
135
|
+
catch (error) {
|
|
136
|
+
// A file that imports one that threw throws the same object: reported once, where it was thrown.
|
|
137
|
+
const at = typeof error === "object" ? gen.reported.get(error) : undefined;
|
|
138
|
+
if (at !== undefined)
|
|
139
|
+
loaded = { failedIn: at };
|
|
140
|
+
else {
|
|
141
|
+
const placed = placeOf(gen, error);
|
|
142
|
+
// Never over a file that loaded (a stack cut short at `Error.stackTraceLimit`): then it is this file's.
|
|
143
|
+
const there = placed && gen.loaded.get(placed.file);
|
|
144
|
+
const { file: own = rel, line, column } = there && "exports" in there ? {} : (placed ?? {});
|
|
145
|
+
if (typeof error === "object")
|
|
146
|
+
gen.reported.set(error, own);
|
|
147
|
+
const report = { error, ...(line !== undefined && { line }), ...(column !== undefined && { column }) };
|
|
148
|
+
gen.loaded.set(own, report);
|
|
149
|
+
loaded = own === rel ? report : { failedIn: own };
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
gen.loaded.set(rel, loaded);
|
|
153
|
+
return loaded;
|
|
154
|
+
}
|
|
155
|
+
/** A frame of a generation's company file in a stack: its URL, without the query, then the tag, line and column. */
|
|
156
|
+
const TAGGED_FRAME = new RegExp(`(file://[^\\s()?]*)\\?${QUERY}=([\\w-]+):(\\d+):(\\d+)`, "g");
|
|
157
|
+
/**
|
|
158
|
+
* Where an error belongs: the last (outermost) frame of its stack in one of the generation's
|
|
159
|
+
* files, the top level of the file that was running, not a helper it called in another file; for
|
|
160
|
+
* a syntax error, the file and line its stack starts with (the caret's column); none for an error
|
|
161
|
+
* thrown before any file ran (top-level `await`, an import Node cannot find).
|
|
162
|
+
*/
|
|
163
|
+
function placeOf(gen, error) {
|
|
164
|
+
const stack = isObject(error) && typeof error.stack === "string" ? error.stack : undefined;
|
|
165
|
+
if (stack === undefined)
|
|
166
|
+
return undefined;
|
|
167
|
+
const frame = [...stack.matchAll(TAGGED_FRAME)].findLast(([, , tag]) => tag === gen.id);
|
|
168
|
+
if (frame) {
|
|
169
|
+
const [, url, , line, column] = frame;
|
|
170
|
+
return { file: relPath(gen.root, fileURLToPath(url)), line: Number(line), column: Number(column) };
|
|
171
|
+
}
|
|
172
|
+
// A syntax error's stack starts `<path or URL>:<line>`, then the source and a caret under the column.
|
|
173
|
+
const [first = "", ...lines] = stack.split("\n");
|
|
174
|
+
const syntax = /^(.+):(\d+)$/.exec(first);
|
|
175
|
+
const path = syntax && (syntax[1].startsWith("file:") ? fileURLToPath(syntax[1]) : syntax[1]);
|
|
176
|
+
if (syntax && path && isAbsolute(path) && inside(gen.root, path)) {
|
|
177
|
+
const caret = lines.slice(0, lines.indexOf("")).findLast((line) => /^\s*\^+\s*$/.test(line));
|
|
178
|
+
return { file: relPath(gen.root, path), line: Number(syntax[2]), ...(caret && { column: caret.indexOf("^") + 1 }) };
|
|
179
|
+
}
|
|
180
|
+
return undefined;
|
|
181
|
+
}
|
|
182
|
+
/**
|
|
183
|
+
* Each company file under `root` a load has read, and each one's folder, with its stamp
|
|
184
|
+
* (`stampOf`) as it was before the file was read: the latest generation's for a file several
|
|
185
|
+
* read. Taken after a load, it still says what the load read, so a file changed while it read is
|
|
186
|
+
* found changed after.
|
|
187
|
+
*/
|
|
188
|
+
export function stampsOf(root) {
|
|
189
|
+
const stamps = new Map();
|
|
190
|
+
if (!existsSync(root))
|
|
191
|
+
return stamps;
|
|
192
|
+
const real = realpathSync(root);
|
|
193
|
+
// In the order made: a later generation's stamp is the newer.
|
|
194
|
+
for (const gen of registry.generations.values()) {
|
|
195
|
+
if (gen.root === real)
|
|
196
|
+
for (const [path, stamp] of gen.stamps)
|
|
197
|
+
stamps.set(path, stamp);
|
|
198
|
+
}
|
|
199
|
+
return stamps;
|
|
200
|
+
}
|
|
201
|
+
const byOrder = (a, b) => (a < b ? -1 : a > b ? 1 : 0);
|
|
202
|
+
/** A file's size and modification time, or that it is gone: what a generation keeps of each file it read. */
|
|
203
|
+
export function stampOf(path) {
|
|
204
|
+
const stat = statSync(path, { bigint: true, throwIfNoEntry: false });
|
|
205
|
+
return stat ? `${stat.size} ${stat.mtimeNs}` : "gone";
|
|
206
|
+
}
|
|
207
|
+
/** True while each path's stamp (`stampOf`) is still the one kept. */
|
|
208
|
+
export function fresh(stamps) {
|
|
209
|
+
for (const [path, stamp] of stamps)
|
|
210
|
+
if (stampOf(path) !== stamp)
|
|
211
|
+
return false;
|
|
212
|
+
return true;
|
|
213
|
+
}
|
|
214
|
+
/** Records a file of the generation, and its directory, as they are now: before it is read, so an edit after is seen. */
|
|
215
|
+
function touch(gen, file) {
|
|
216
|
+
for (const path of [file, dirname(file)])
|
|
217
|
+
if (!gen.stamps.has(path))
|
|
218
|
+
gen.stamps.set(path, stampOf(path));
|
|
219
|
+
}
|
|
220
|
+
/**
|
|
221
|
+
* The generation of `root` and these constructors: the current one while nothing it stamped
|
|
222
|
+
* changed, else a new one. A generation of `root` whose files changed goes, whatever its
|
|
223
|
+
* constructors, so `stampsOf` never keeps the stamps of one no load will make again.
|
|
224
|
+
*/
|
|
225
|
+
function generationOf(root, connectors, types) {
|
|
226
|
+
const packages = connectors.flatMap((c) => {
|
|
227
|
+
const { id, info } = c[VENDOR];
|
|
228
|
+
return info?.package ? [`${info.package}/resources`, id] : [];
|
|
229
|
+
});
|
|
230
|
+
const typesKey = [...packages, ...[...types.values()].map(idOf)].join(" ");
|
|
231
|
+
let current;
|
|
232
|
+
for (const gen of registry.generations.values()) {
|
|
233
|
+
if (gen.root !== root)
|
|
234
|
+
continue;
|
|
235
|
+
if (!fresh(gen.stamps))
|
|
236
|
+
registry.generations.delete(gen.id);
|
|
237
|
+
else if (gen.typesKey === typesKey)
|
|
238
|
+
current = gen;
|
|
239
|
+
}
|
|
240
|
+
if (current !== undefined)
|
|
241
|
+
return current;
|
|
242
|
+
const gen = {
|
|
243
|
+
id: String(++registry.seq),
|
|
244
|
+
root,
|
|
245
|
+
typesKey,
|
|
246
|
+
virtual: new Map(),
|
|
247
|
+
stamps: new Map(),
|
|
248
|
+
made: [],
|
|
249
|
+
imported: new Set(),
|
|
250
|
+
loaded: new Map(),
|
|
251
|
+
reported: new Map(),
|
|
252
|
+
answers: new WeakMap(),
|
|
253
|
+
};
|
|
254
|
+
gen.virtual = runtimeModules(gen, connectors, types);
|
|
255
|
+
registry.generations.set(gen.id, gen);
|
|
256
|
+
return gen;
|
|
257
|
+
}
|
|
258
|
+
function idOf(object) {
|
|
259
|
+
let id = registry.ids.get(object);
|
|
260
|
+
if (id === undefined)
|
|
261
|
+
registry.ids.set(object, (id = ++registry.seq));
|
|
262
|
+
return id;
|
|
263
|
+
}
|
|
264
|
+
/** The runtime's modules a generation serves its files, by specifier: each constructor wrapped to record where it was called. */
|
|
265
|
+
function runtimeModules(gen, connectors, types) {
|
|
266
|
+
const byVendor = new Map();
|
|
267
|
+
for (const resource of types.values()) {
|
|
268
|
+
const constructors = byVendor.get(resource.vendor) ?? {};
|
|
269
|
+
// Frame 2 of `callerFile` is the wrapper's caller: the company file.
|
|
270
|
+
constructors[resource.type] = (fields, options) => record(gen, callerFile(), resource(fields, options), refersIn(fields));
|
|
271
|
+
byVendor.set(resource.vendor, constructors);
|
|
272
|
+
}
|
|
273
|
+
// A type the vendor does not declare is refused where it is called for, as `<vendor>.<type>`;
|
|
274
|
+
// an object's own names (`toString`, `toJSON`) are not types, so printing the vendor still works.
|
|
275
|
+
const constructorsOf = (vendor) => new Proxy(byVendor.get(vendor) ?? {}, {
|
|
276
|
+
get(target, key) {
|
|
277
|
+
if (typeof key !== "string" || key in target || key === "toJSON")
|
|
278
|
+
return Reflect.get(target, key);
|
|
279
|
+
const known = Object.keys(target);
|
|
280
|
+
throw new TypeError(`${vendor} has no resource type ${key}: its types are ${known.join(", ") || "none"}`);
|
|
281
|
+
},
|
|
282
|
+
});
|
|
283
|
+
const modules = new Map();
|
|
284
|
+
for (const connector of connectors) {
|
|
285
|
+
const { id, info } = connector[VENDOR];
|
|
286
|
+
if (info?.package)
|
|
287
|
+
modules.set(`${info.package}/resources`, { [id]: constructorsOf(id) });
|
|
288
|
+
}
|
|
289
|
+
for (const entry of SECRET_ENTRIES)
|
|
290
|
+
modules.set(entry, { sanoma: constructorsOf("sanoma"), secret });
|
|
291
|
+
const collection = (declaration) => {
|
|
292
|
+
const file = callerFile();
|
|
293
|
+
return record(gen, file, collectionIn(file === undefined ? undefined : appOfPath(relPath(gen.root, file)), declaration));
|
|
294
|
+
};
|
|
295
|
+
for (const entry of DATA_ENTRIES)
|
|
296
|
+
modules.set(entry, { collection });
|
|
297
|
+
const site = (definition) => record(gen, callerFile(), defineSite(definition));
|
|
298
|
+
for (const entry of SITE_ENTRIES)
|
|
299
|
+
modules.set(entry, { defineSite: site });
|
|
300
|
+
const app = (definition) => record(gen, callerFile(), defineApp(definition));
|
|
301
|
+
for (const entry of APP_ENTRIES)
|
|
302
|
+
modules.set(entry, { defineApp: app });
|
|
303
|
+
return modules;
|
|
304
|
+
}
|
|
305
|
+
/** Records where `value` was made, and returns it. */
|
|
306
|
+
function record(gen, file, value, refers = {}) {
|
|
307
|
+
gen.made.push(value);
|
|
308
|
+
registry.made.set(value, { file: file === undefined ? "" : relPath(gen.root, file), seq: gen.made.length, refers });
|
|
309
|
+
return value;
|
|
310
|
+
}
|
|
311
|
+
/** Each declared resource in a constructor's fields, by its dotted path, as the constructor walks them. */
|
|
312
|
+
function refersIn(value, at = "", into = {}) {
|
|
313
|
+
if (isDeclared(value))
|
|
314
|
+
into[at] = value;
|
|
315
|
+
else if (Array.isArray(value))
|
|
316
|
+
value.forEach((item, i) => refersIn(item, joinPath(at, String(i)), into));
|
|
317
|
+
else if (isObject(value))
|
|
318
|
+
for (const [field, item] of Object.entries(value))
|
|
319
|
+
refersIn(item, joinPath(at, field), into);
|
|
320
|
+
return into;
|
|
321
|
+
}
|
|
322
|
+
/** True for an app's `apps/<app>/app.ts`, by URL. */
|
|
323
|
+
const isAppFile = (gen, url) => {
|
|
324
|
+
const [top, app, file, ...rest] = relPath(gen.root, fileURLToPath(url)).split("/");
|
|
325
|
+
return top === APPS_DIR && app !== undefined && file === "app.ts" && !rest.length;
|
|
326
|
+
};
|
|
327
|
+
/** The generation a module URL belongs to: the query on a company file's, the first segment of the loader's own. */
|
|
328
|
+
function tagOf(url) {
|
|
329
|
+
if (url?.startsWith("file:"))
|
|
330
|
+
return new URL(url).searchParams.get(QUERY);
|
|
331
|
+
if (url?.startsWith(SCHEME))
|
|
332
|
+
return url.slice(SCHEME.length, url.indexOf("/"));
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Registers the loader's hooks, once per process (the registry's flag, for two copies of the
|
|
337
|
+
* package). A file of a generation resolves the runtime's modules to the generation's, and each
|
|
338
|
+
* company file (under the root, outside `node_modules`) to itself tagged with the generation,
|
|
339
|
+
* recorded and stamped; an entry is a module exporting the tagged file's namespace as `ns`, since
|
|
340
|
+
* `require` of a `file:` URL drops its query (the CommonJS loader keys by file name).
|
|
341
|
+
*/
|
|
342
|
+
function hook() {
|
|
343
|
+
if (registry.hooked)
|
|
344
|
+
return;
|
|
345
|
+
registry.hooked = true;
|
|
346
|
+
registerHooks({
|
|
347
|
+
resolve(specifier, context, next) {
|
|
348
|
+
if (specifier.startsWith(SCHEME))
|
|
349
|
+
return { url: specifier, shortCircuit: true };
|
|
350
|
+
const tag = tagOf(context.parentURL);
|
|
351
|
+
const gen = tag === null ? undefined : registry.generations.get(tag);
|
|
352
|
+
if (gen === undefined)
|
|
353
|
+
return next(specifier, context);
|
|
354
|
+
if (gen.virtual.has(specifier) &&
|
|
355
|
+
(!APP_ENTRIES.has(specifier) || (context.parentURL.startsWith("file:") && isAppFile(gen, context.parentURL)))) {
|
|
356
|
+
return { url: `${SCHEME}${gen.id}/${specifier}`, shortCircuit: true };
|
|
357
|
+
}
|
|
358
|
+
const resolved = next(specifier, context);
|
|
359
|
+
if (!resolved.url.startsWith("file:"))
|
|
360
|
+
return resolved;
|
|
361
|
+
const url = new URL(resolved.url);
|
|
362
|
+
const file = fileURLToPath(url);
|
|
363
|
+
if (!inside(gen.root, file) || file.split(sep).includes("node_modules"))
|
|
364
|
+
return resolved;
|
|
365
|
+
touch(gen, file);
|
|
366
|
+
gen.imported.add(relPath(gen.root, file));
|
|
367
|
+
url.searchParams.set(QUERY, gen.id);
|
|
368
|
+
return { ...resolved, url: url.href };
|
|
369
|
+
},
|
|
370
|
+
load(url, context, next) {
|
|
371
|
+
if (!url.startsWith(SCHEME))
|
|
372
|
+
return next(url, context);
|
|
373
|
+
const tag = tagOf(url);
|
|
374
|
+
const rest = url.slice(url.indexOf("/") + 1);
|
|
375
|
+
if (rest.startsWith("file:")) {
|
|
376
|
+
const target = new URL(rest);
|
|
377
|
+
target.searchParams.set(QUERY, tag);
|
|
378
|
+
return { format: "module", source: `export * as ns from ${JSON.stringify(target.href)};`, shortCircuit: true };
|
|
379
|
+
}
|
|
380
|
+
// Read from the registry by the module itself, so a company file gets the generation's own objects.
|
|
381
|
+
const from = `globalThis[Symbol.for("sanoma.load")].generations.get(${JSON.stringify(tag)}).virtual.get(${JSON.stringify(rest)})`;
|
|
382
|
+
const names = Object.keys(registry.generations.get(tag)?.virtual.get(rest) ?? {});
|
|
383
|
+
const source = [
|
|
384
|
+
`const m = ${from};`,
|
|
385
|
+
...names.map((name, i) => `const e${i} = m[${JSON.stringify(name)}];\nexport { e${i} as ${JSON.stringify(name)} };`),
|
|
386
|
+
].join("\n");
|
|
387
|
+
return { format: "module", source, shortCircuit: true };
|
|
388
|
+
},
|
|
389
|
+
});
|
|
390
|
+
}
|
|
391
|
+
//# sourceMappingURL=load.js.map
|
package/dist/load.js.map
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"load.js","sourceRoot":"","sources":["../src/load.ts"],"names":[],"mappings":"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"}
|
package/dist/lockfile.d.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { type ConnectionRef } from "./connection.ts";
|
|
1
2
|
import type { ResourceProblem } from "./resources.ts";
|
|
2
3
|
/** Where the lockfile is, relative to the config's root. */
|
|
3
4
|
export declare const LOCKFILE = "resources/sanoma.lock.json";
|
|
@@ -5,6 +6,7 @@ export declare const LOCKFILE = "resources/sanoma.lock.json";
|
|
|
5
6
|
export interface Binding {
|
|
6
7
|
type: string;
|
|
7
8
|
id: string;
|
|
9
|
+
connection?: ConnectionRef;
|
|
8
10
|
}
|
|
9
11
|
/** The lockfile's content: by declaration key, `<file>#<export>` (the file relative to the config's root, with `/`). */
|
|
10
12
|
export type Bindings = Record<string, Binding>;
|
package/dist/lockfile.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { connectionRefSchema } from "./connection.js";
|
|
1
2
|
import { existsSync, readFileSync, renameSync, rmSync, writeFileSync } from "node:fs";
|
|
2
3
|
import { join } from "node:path";
|
|
3
4
|
import { z } from "zod";
|
|
@@ -5,7 +6,11 @@ import { z } from "zod";
|
|
|
5
6
|
// hold intent only), as `package-lock.json` is from `package.json`. Only apply writes it.
|
|
6
7
|
/** Where the lockfile is, relative to the config's root. */
|
|
7
8
|
export const LOCKFILE = "resources/sanoma.lock.json";
|
|
8
|
-
const lockfile = z.record(z.string().regex(/^resources\/[^#]+#[^#]+$/), z.strictObject({
|
|
9
|
+
const lockfile = z.record(z.string().regex(/^resources\/[^#]+#[^#]+$/), z.strictObject({
|
|
10
|
+
type: z.string().regex(/^[^.\s]+\.[^.\s]+$/),
|
|
11
|
+
id: z.string().min(1),
|
|
12
|
+
connection: connectionRefSchema.optional(),
|
|
13
|
+
}));
|
|
9
14
|
/**
|
|
10
15
|
* The lockfile under `root`: no bindings when there is none, and no bindings with a problem when
|
|
11
16
|
* it is not JSON or not a map of `<file>#<export>` to `{ type, id }`.
|
|
@@ -35,7 +40,7 @@ export function readLockfile(root) {
|
|
|
35
40
|
export function serializeLockfile(bindings) {
|
|
36
41
|
const sorted = Object.entries(bindings)
|
|
37
42
|
.toSorted(([a], [b]) => (a < b ? -1 : a > b ? 1 : 0))
|
|
38
|
-
.map(([key, { type, id }]) => [key, { type, id }]);
|
|
43
|
+
.map(([key, { type, id, connection }]) => [key, { type, id, ...(connection && { connection }) }]);
|
|
39
44
|
return `${JSON.stringify(Object.fromEntries(sorted), null, 2)}\n`;
|
|
40
45
|
}
|
|
41
46
|
/** Writes the lockfile under `root` whole or not at all: to a file beside it, then renamed over it. Apply only. */
|
|
@@ -61,7 +66,7 @@ export function diffLockfiles(before, after) {
|
|
|
61
66
|
return was ? [{ key, type: was.type, kind: "unbind", from: was.id }] : [];
|
|
62
67
|
if (!was)
|
|
63
68
|
return [{ key, type: now.type, kind: "bind", to: now.id }];
|
|
64
|
-
if (was.id === now.id && was.type === now.type)
|
|
69
|
+
if (was.id === now.id && was.type === now.type && JSON.stringify(was.connection) === JSON.stringify(now.connection))
|
|
65
70
|
return [];
|
|
66
71
|
return [{ key, type: now.type, kind: "rebind", from: was.id, to: now.id }];
|
|
67
72
|
});
|
package/dist/lockfile.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,SAAS,CAAC;AACtF,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAGxB,kGAAkG;AAClG,0FAA0F;AAE1F,4DAA4D;AAC5D,MAAM,CAAC,MAAM,QAAQ,GAAG,4BAA4B,CAAC;
|
|
1
|
+
{"version":3,"file":"lockfile.js","sourceRoot":"","sources":["../src/lockfile.ts"],"names":[],"mappings":"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"}
|
package/dist/op.d.ts
CHANGED
|
@@ -1,3 +1,6 @@
|
|
|
1
|
+
import type { Principal } from "./define.ts";
|
|
2
|
+
import type { Authentication, CallAuthentication } from "./authentication.ts";
|
|
3
|
+
import type { ConnectionSnapshot } from "./connection.ts";
|
|
1
4
|
import type { ProviderV4 } from "@ai-sdk/provider";
|
|
2
5
|
import type { z } from "zod";
|
|
3
6
|
import type { Fake } from "./fake.ts";
|
|
@@ -39,6 +42,8 @@ export interface OpSpec<I extends z.ZodType = z.ZodType, O extends z.ZodType = z
|
|
|
39
42
|
* (a resource type's `handle`): the ledger records each as `"<name>"`, never its value.
|
|
40
43
|
*/
|
|
41
44
|
opaque?: readonly string[];
|
|
45
|
+
/** Logical destinations this operation may create with Secrets.ensure, derived from its authorized input. */
|
|
46
|
+
createsSecrets?: (input: any) => readonly string[];
|
|
42
47
|
}
|
|
43
48
|
/** One vendor operation, such as `ghost.post.publish`. Declares the contract only; drivers implement it. */
|
|
44
49
|
export interface Op<V extends string = string, R extends string = string, N extends string = string, I = any, O = any> {
|
|
@@ -59,6 +64,7 @@ export interface Op<V extends string = string, R extends string = string, N exte
|
|
|
59
64
|
};
|
|
60
65
|
/** From the spec: fields the ledger records by name only. */
|
|
61
66
|
readonly opaque?: readonly string[];
|
|
67
|
+
readonly createsSecrets?: (input: any) => readonly string[];
|
|
62
68
|
readonly input: z.ZodType<any, I>;
|
|
63
69
|
readonly output: z.ZodType<O>;
|
|
64
70
|
}
|
|
@@ -100,7 +106,7 @@ export type Connector<V extends string, S extends Specs> = {
|
|
|
100
106
|
* and `resolveConfig` reads only a record of its own shape (`checkConnector`): change it with
|
|
101
107
|
* the record, so a build refuses a connector another build made in another shape.
|
|
102
108
|
*/
|
|
103
|
-
export declare const CONNECTOR_FORMAT =
|
|
109
|
+
export declare const CONNECTOR_FORMAT = 3;
|
|
104
110
|
/**
|
|
105
111
|
* A connector's vendor: its id, who it is (`defineConnector`'s third argument, for a UI), its
|
|
106
112
|
* resource types, and the driver and fake its package attaches (`withSetup`).
|
|
@@ -152,6 +158,12 @@ export declare function defineConnector<const V extends string, const S extends
|
|
|
152
158
|
* not repeat the side effect.
|
|
153
159
|
*/
|
|
154
160
|
export interface CallContext {
|
|
161
|
+
/** Authenticated initiating principal; never supplied by operation input. */
|
|
162
|
+
principal?: Principal;
|
|
163
|
+
/** Authorized account metadata. Credential material stays inside the driver boundary. */
|
|
164
|
+
connection?: ConnectionSnapshot;
|
|
165
|
+
/** Resolved after policy, for this call alone. Never return it from a driver. */
|
|
166
|
+
authentication?: CallAuthentication;
|
|
155
167
|
idempotencyKey: string;
|
|
156
168
|
runId: string;
|
|
157
169
|
opId: string;
|
|
@@ -202,13 +214,15 @@ export declare function retryableStatus(status: number): boolean;
|
|
|
202
214
|
*/
|
|
203
215
|
export type DriverEnv = z.ZodObject<Record<string, z.ZodType<string | undefined, string | undefined>>>;
|
|
204
216
|
/**
|
|
205
|
-
* Implements a vendor's operations, keyed `"resource.name"`.
|
|
206
|
-
*
|
|
217
|
+
* Implements a vendor's operations, keyed `"resource.name"`. Named authentication is supplied
|
|
218
|
+
* in the call context. `env` describes a driver that has not added named-account support.
|
|
207
219
|
*/
|
|
208
220
|
export interface Driver {
|
|
209
221
|
readonly vendor: string;
|
|
210
222
|
readonly ops: Readonly<Record<string, DriverFn>>;
|
|
211
223
|
readonly env?: DriverEnv;
|
|
224
|
+
/** Methods this driver consumes from CallContext.authentication. Others fail closed. */
|
|
225
|
+
readonly authentication?: readonly string[];
|
|
212
226
|
}
|
|
213
227
|
/**
|
|
214
228
|
* What a connector package attaches to its connector (`withSetup`), for the config's resolver
|
|
@@ -219,7 +233,9 @@ export interface Driver {
|
|
|
219
233
|
* no repository a change is reviewed on.
|
|
220
234
|
*/
|
|
221
235
|
export interface ConnectorSetup {
|
|
222
|
-
/**
|
|
236
|
+
/** Auth methods available to named connections; login identity is separate. */
|
|
237
|
+
authentication?: Readonly<Record<string, Authentication>>;
|
|
238
|
+
/** Makes the live driver once per resolved config; credentials belong to each invocation. */
|
|
223
239
|
driver?: () => Driver;
|
|
224
240
|
/** Makes a fake of the vendor (`defineFake`): once per sandbox run, its own. */
|
|
225
241
|
fake?: () => Fake<any, any>;
|
|
@@ -333,7 +349,8 @@ export type OpIdOf<V extends string, S extends Specs> = {
|
|
|
333
349
|
* connector doesn't declare, is refused here rather than when a run calls it. `options.env`
|
|
334
350
|
* declares the environment variables it reads (see `DriverEnv`).
|
|
335
351
|
*/
|
|
336
|
-
export declare function defineDriver<V extends string, S extends Specs>(connector: Connector<V, S>, impl: DriverImpl<S
|
|
352
|
+
export declare function defineDriver<V extends string, S extends Specs>(connector: Connector<V, S>, impl: DriverImpl<S> | ((call: CallContext) => DriverImpl<S>), options?: {
|
|
337
353
|
env?: DriverEnv;
|
|
354
|
+
authentication?: readonly string[];
|
|
338
355
|
}): Driver;
|
|
339
356
|
export {};
|
package/dist/op.js
CHANGED
|
@@ -16,7 +16,7 @@ export const VENDOR = Symbol.for("sanoma.vendor");
|
|
|
16
16
|
* and `resolveConfig` reads only a record of its own shape (`checkConnector`): change it with
|
|
17
17
|
* the record, so a build refuses a connector another build made in another shape.
|
|
18
18
|
*/
|
|
19
|
-
export const CONNECTOR_FORMAT =
|
|
19
|
+
export const CONNECTOR_FORMAT = 3;
|
|
20
20
|
/** One `<svg>` element, with nothing but whitespace around it: what a logo must be. */
|
|
21
21
|
const SVG_ELEMENT = /^\s*<svg[\s>][\s\S]*<\/svg>\s*$/;
|
|
22
22
|
/** Whether `svg` is a logo as `VendorInfo` takes it: one `<svg>…</svg>` element. */
|
|
@@ -74,6 +74,7 @@ export function defineConnector(vendor, specs, info) {
|
|
|
74
74
|
target: spec.target,
|
|
75
75
|
phrases: spec.phrases,
|
|
76
76
|
...(spec.opaque?.length ? { opaque: spec.opaque } : {}),
|
|
77
|
+
...(spec.createsSecrets && { createsSecrets: spec.createsSecrets }),
|
|
77
78
|
input: spec.input,
|
|
78
79
|
output: spec.output,
|
|
79
80
|
});
|
|
@@ -174,6 +175,18 @@ export function defineDriver(connector, impl, options = {}) {
|
|
|
174
175
|
}
|
|
175
176
|
const vendor = connector[VENDOR].id;
|
|
176
177
|
const ops = {};
|
|
178
|
+
if (typeof impl === "function") {
|
|
179
|
+
// Build clients only once the runtime has authorized and authenticated this invocation.
|
|
180
|
+
for (const key of declared.keys()) {
|
|
181
|
+
ops[key] = async (input, call) => defineDriver(connector, impl(call), options).ops[key](input, call);
|
|
182
|
+
}
|
|
183
|
+
return Object.freeze({
|
|
184
|
+
vendor,
|
|
185
|
+
ops: Object.freeze(ops),
|
|
186
|
+
...(options.env && { env: options.env }),
|
|
187
|
+
...(options.authentication && { authentication: Object.freeze([...options.authentication]) }),
|
|
188
|
+
});
|
|
189
|
+
}
|
|
177
190
|
const extra = [];
|
|
178
191
|
for (const [resource, fns] of Object.entries(impl)) {
|
|
179
192
|
for (const [name, fn] of Object.entries(fns ?? {})) {
|
|
@@ -191,6 +204,11 @@ export function defineDriver(connector, impl, options = {}) {
|
|
|
191
204
|
];
|
|
192
205
|
if (problems.length)
|
|
193
206
|
throw new Error(`defineDriver("${vendor}"): ${problems.join("; ")}`);
|
|
194
|
-
return Object.freeze({
|
|
207
|
+
return Object.freeze({
|
|
208
|
+
vendor,
|
|
209
|
+
ops: Object.freeze(ops),
|
|
210
|
+
...(options.env && { env: options.env }),
|
|
211
|
+
...(options.authentication && { authentication: Object.freeze([...options.authentication]) }),
|
|
212
|
+
});
|
|
195
213
|
}
|
|
196
214
|
//# sourceMappingURL=op.js.map
|