@vendure/cloud-config 0.4.0 → 0.5.0-dev.20261016123507.ge07a06e
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 +13 -4
- package/dist/cloud-asset-server-plugin.d.ts.map +1 -1
- package/dist/cloud-asset-server-plugin.js +22 -38
- package/dist/cloud-asset-server-plugin.js.map +1 -1
- package/dist/cloud-config.d.ts.map +1 -1
- package/dist/cloud-dashboard-plugin.d.ts.map +1 -1
- package/dist/cloud-dashboard-plugin.js +20 -36
- package/dist/cloud-dashboard-plugin.js.map +1 -1
- package/dist/cloud-plugin-declaration.d.ts.map +1 -1
- package/dist/cloud-plugin-declaration.js +18 -23
- package/dist/cloud-plugin-declaration.js.map +1 -1
- package/dist/composition.d.ts.map +1 -1
- package/dist/composition.js +22 -32
- package/dist/composition.js.map +1 -1
- package/dist/define-cloud-config.d.ts.map +1 -1
- package/dist/define-cloud-config.js +12 -17
- package/dist/define-cloud-config.js.map +1 -1
- package/dist/durable-workflow-reads.d.ts +20 -0
- package/dist/durable-workflow-reads.d.ts.map +1 -0
- package/dist/durable-workflow-reads.js +57 -0
- package/dist/durable-workflow-reads.js.map +1 -0
- package/dist/durable-workflows.d.ts +74 -0
- package/dist/durable-workflows.d.ts.map +1 -0
- package/dist/durable-workflows.js +102 -0
- package/dist/durable-workflows.js.map +1 -0
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +3 -6
- package/dist/errors.js.map +1 -1
- package/dist/index.d.ts +3 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -2
- package/dist/index.js.map +1 -1
- package/dist/migrations.d.ts.map +1 -1
- package/dist/migrations.js +70 -104
- package/dist/migrations.js.map +1 -1
- package/dist/outbound-hosts.d.ts +6 -0
- package/dist/outbound-hosts.d.ts.map +1 -1
- package/dist/outbound-hosts.js +114 -55
- package/dist/outbound-hosts.js.map +1 -1
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +6 -7
- package/dist/path.js.map +1 -1
- package/dist/platform-capabilities.d.ts.map +1 -1
- package/dist/platform-capabilities.js +12 -18
- package/dist/platform-capabilities.js.map +1 -1
- package/dist/platform-fields.d.ts.map +1 -1
- package/dist/platform-fields.js +10 -15
- package/dist/platform-fields.js.map +1 -1
- package/dist/plugin-attribution.d.ts.map +1 -1
- package/dist/plugin-attribution.js +22 -31
- package/dist/plugin-attribution.js.map +1 -1
- package/dist/runtime-backstop.d.ts.map +1 -1
- package/dist/runtime-backstop.js +2 -5
- package/dist/runtime-backstop.js.map +1 -1
- package/dist/secrets.d.ts.map +1 -1
- package/dist/secrets.js +20 -50
- package/dist/secrets.js.map +1 -1
- package/dist/stack.d.ts.map +1 -1
- package/dist/stack.js +12 -21
- package/dist/stack.js.map +1 -1
- package/dist/superseded-plugins.d.ts.map +1 -1
- package/dist/superseded-plugins.js +4 -7
- package/dist/superseded-plugins.js.map +1 -1
- package/dist/vendure-extension.d.ts +2 -0
- package/dist/vendure-extension.d.ts.map +1 -1
- package/dist/vendure-extension.js +53 -34
- package/dist/vendure-extension.js.map +1 -1
- package/package.json +10 -3
- package/dist/tenant-workflows.d.ts +0 -44
- package/dist/tenant-workflows.d.ts.map +0 -1
- package/dist/tenant-workflows.js +0 -219
- package/dist/tenant-workflows.js.map +0 -1
|
@@ -2,13 +2,10 @@ import { CloudConfigError } from "./errors.js";
|
|
|
2
2
|
import { pluginName } from "./plugin-attribution.js";
|
|
3
3
|
const SUPERSEDED_SPECS = [
|
|
4
4
|
{
|
|
5
|
-
// The behavioural check
|
|
6
|
-
//
|
|
7
|
-
//
|
|
8
|
-
//
|
|
9
|
-
// check has been told to ignore, and the boot succeeds with their storage strategy discarded.
|
|
10
|
-
// `DashboardPlugin` is not exposed to this: the platform's plugin is
|
|
11
|
-
// `CloudDashboardServerPlugin`, which is a different name.
|
|
5
|
+
// The behavioural check ignores the names of the platform's own plugins. The platform serves
|
|
6
|
+
// assets with the upstream `AssetServerPlugin`, configured by `CloudAssetServerPlugin`, so a
|
|
7
|
+
// customer declaring it writes `assetOptions.assetStorageStrategy` under an ignored name. The
|
|
8
|
+
// boot succeeds with their storage strategy discarded.
|
|
12
9
|
plugin: "AssetServerPlugin",
|
|
13
10
|
replacement: "CloudAssetServerPlugin",
|
|
14
11
|
reason: "Vendure Cloud stores assets in a bucket it creates for this environment and serves them at /assets. CloudAssetServerPlugin keeps your presets, transform strategies, naming, previews and cache header, and supplies the storage and the URLs.",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"superseded-plugins.js","sourceRoot":"","sources":["../src/superseded-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAA2C,UAAU,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"superseded-plugins.js","sourceRoot":"","sources":["../src/superseded-plugins.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAA2C,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAsB9F,MAAM,gBAAgB,GAAG;IACvB;QACE,6FAA6F;QAC7F,6FAA6F;QAC7F,8FAA8F;QAC9F,uDAAuD;QACvD,MAAM,EAAE,mBAAmB;QAC3B,WAAW,EAAE,wBAAwB;QACrC,MAAM,EACJ,gPAAgP;KACnP;IACD;QACE,MAAM,EAAE,iBAAiB;QACzB,WAAW,EAAE,sBAAsB;QACnC,MAAM,EACJ,oKAAoK;KACvK;CAC6C,CAAC;AAEjD,MAAM,CAAC,MAAM,kBAAkB,GAAgC,gBAAgB,CAAC;AAEhF,MAAM,UAAU,oBAAoB,CAAC,IAAY;IAC/C,OAAO,kBAAkB,CAAC,IAAI,CAAC,CAAC,UAAU,EAAE,EAAE,CAAC,UAAU,CAAC,MAAM,KAAK,IAAI,CAAC,CAAC;AAC7E,CAAC;AASD,MAAM,OAAO,6BAA8B,SAAQ,gBAAgB;IACxD,YAAY,CAAyC;IAE9D,YAAY,YAAoD;QAC9D,MAAM,MAAM,GAAG,YAAY;aACxB,GAAG,CAAC,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,EAAE,EAAE;YACjC,MAAM,KAAK,GACT,SAAS,KAAK,SAAS;gBACrB,CAAC,CAAC,UAAU,CAAC,MAAM;gBACnB,CAAC,CAAC,GAAG,UAAU,CAAC,MAAM,+BAA+B,SAAS,IAAI,CAAC;YACvE,OAAO,KAAK,KAAK,uCAAuC,UAAU,CAAC,MAAM,aAAa,UAAU,CAAC,WAAW,WAAW,CAAC;QAC1H,CAAC,CAAC;aACD,IAAI,CAAC,MAAM,CAAC,CAAC;QAChB,KAAK,CACH,8CAA8C,YAAY,CAAC,MAAM,UAC/D,YAAY,CAAC,MAAM,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,GACnC,qDAAqD,MAAM,IAAI,CAChE,CAAC;QACF,IAAI,CAAC,YAAY,GAAG,YAAY,CAAC;IACnC,CAAC;CACF;AAED,MAAM,UAAU,gCAAgC,CAC9C,OAA8B,EAC9B,cAAiC,IAAI,GAAG,EAAE;IAE1C,MAAM,YAAY,GAAkC,EAAE,CAAC;IACvD,KAAK,MAAM,MAAM,IAAI,OAAO,EAAE,CAAC;QAC7B,MAAM,UAAU,GAAG,oBAAoB,CAAC,UAAU,CAAC,MAAM,CAAC,CAAC,CAAC;QAC5D,IAAI,CAAC,UAAU;YAAE,SAAS;QAC1B,YAAY,CAAC,IAAI,CAAC,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,CAAC,CAAC;IAC5E,CAAC;IACD,IAAI,YAAY,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QAC5B,MAAM,IAAI,6BAA6B,CAAC,YAAY,CAAC,CAAC;IACxD,CAAC;AACH,CAAC"}
|
|
@@ -20,6 +20,8 @@ export interface VendureExtension {
|
|
|
20
20
|
export type CloudPluginEntry = VendurePluginEntry | VendureExtension;
|
|
21
21
|
export declare class InvalidVendureExtensionError extends CloudConfigError {
|
|
22
22
|
}
|
|
23
|
+
export declare class InvalidOutboundHostsError extends InvalidVendureExtensionError {
|
|
24
|
+
}
|
|
23
25
|
export declare class DuplicateVendureExtensionIdError extends CloudConfigError {
|
|
24
26
|
readonly id: string;
|
|
25
27
|
constructor(id: string);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vendure-extension.d.ts","sourceRoot":"","sources":["../src/vendure-extension.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAI1D,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;
|
|
1
|
+
{"version":3,"file":"vendure-extension.d.ts","sourceRoot":"","sources":["../src/vendure-extension.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAE/C,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AAI1D,MAAM,MAAM,kBAAkB,GAAG,WAAW,CAAC,aAAa,CAAC,SAAS,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC;AAI/E,QAAA,MAAM,SAAS,eAAgD,CAAC;AAIhE,MAAM,WAAW,qBAAqB;IAIpC,EAAE,EAAE,MAAM,CAAC;IACX,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAIvC,UAAU,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IAE/B,aAAa,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;CACnC;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,CAAC,SAAS,CAAC,EAAE,IAAI,CAAC;IAC3B,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;IACpB,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAGhD,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;IAEvC,QAAQ,CAAC,aAAa,EAAE,SAAS,MAAM,EAAE,CAAC;IAI1C,QAAQ,CAAC,UAAU,EAAE,MAAM,GAAG,SAAS,CAAC;CACzC;AAKD,MAAM,MAAM,gBAAgB,GAAG,kBAAkB,GAAG,gBAAgB,CAAC;AAErE,qBAAa,4BAA6B,SAAQ,gBAAgB;CAAG;AAKrE,qBAAa,yBAA0B,SAAQ,4BAA4B;CAAG;AAE9E,qBAAa,gCAAiC,SAAQ,gBAAgB;IACpE,QAAQ,CAAC,EAAE,EAAE,MAAM,CAAC;gBAER,EAAE,EAAE,MAAM;CAMvB;AAkBD,wBAAgB,sBAAsB,CAAC,SAAS,EAAE,qBAAqB,GAAG,gBAAgB,CA2BzF;AA0BD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,OAAO,GAAG,KAAK,IAAI,gBAAgB,CAE5E;AAQD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,GAAG,MAAM,CAQtF;AAED,wBAAgB,0BAA0B,CAAC,SAAS,EAAE,gBAAgB,GAAG,MAAM,EAAE,CAEhF;AAED,MAAM,WAAW,gBAAgB;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,CAAC;IAChD,QAAQ,CAAC,UAAU,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACjD,QAAQ,CAAC,WAAW,EAAE,WAAW,CAAC,UAAU,EAAE,gBAAgB,CAAC,CAAC;CACjE;AAQD,wBAAgB,wBAAwB,CAAC,OAAO,EAAE,SAAS,gBAAgB,EAAE,GAAG,gBAAgB,CAyB/F"}
|
|
@@ -1,12 +1,17 @@
|
|
|
1
1
|
import { dirname, isAbsolute, resolve } from "node:path";
|
|
2
2
|
import { CloudConfigError } from "./errors.js";
|
|
3
|
+
import { parseOutboundHost } from "./outbound-hosts.js";
|
|
3
4
|
import { stackFrameFiles } from "./stack.js";
|
|
4
|
-
// Registered for
|
|
5
|
-
//
|
|
6
|
-
// silently treats as plugins, and core would be handed an object it cannot configure.
|
|
5
|
+
// Registered on `Symbol.for` like the config handle's symbol (ADR-0043). A second copy of this
|
|
6
|
+
// package would otherwise produce extensions that `defineCloudConfig` treats as plugins.
|
|
7
7
|
const EXTENSION = Symbol.for("vendure-cloud.vendure-extension");
|
|
8
8
|
export class InvalidVendureExtensionError extends CloudConfigError {
|
|
9
9
|
}
|
|
10
|
+
// A declared outbound host entry that is not a bare public hostname. Its own class so the managed
|
|
11
|
+
// build can name this failure without reading the message, which quotes the extension's id. A
|
|
12
|
+
// value that is not a list has no entries to name, so it stays the general error.
|
|
13
|
+
export class InvalidOutboundHostsError extends InvalidVendureExtensionError {
|
|
14
|
+
}
|
|
10
15
|
export class DuplicateVendureExtensionIdError extends CloudConfigError {
|
|
11
16
|
id;
|
|
12
17
|
constructor(id) {
|
|
@@ -14,24 +19,19 @@ export class DuplicateVendureExtensionIdError extends CloudConfigError {
|
|
|
14
19
|
this.id = id;
|
|
15
20
|
}
|
|
16
21
|
}
|
|
17
|
-
// ADR-0047's one mechanical trap: `migrations: ['./migrations/*.js']` written in a package's
|
|
18
|
-
//
|
|
19
|
-
// referenced it.
|
|
20
|
-
//
|
|
21
|
-
//
|
|
22
|
-
// matches nothing and raises nothing. Reading the call stack also works whichever module
|
|
23
|
-
// system the build emits, including CommonJS output, where `import.meta` is unavailable.
|
|
22
|
+
// ADR-0047's one mechanical trap: `migrations: ['./migrations/*.js']` written in a package's own
|
|
23
|
+
// index means that package's directory, not the directory of the configuration file that
|
|
24
|
+
// referenced it. A glob left behind after copying a declaration to another file matches nothing
|
|
25
|
+
// and raises nothing. The declaring file is read off the call stack, which also works in
|
|
26
|
+
// CommonJS output, where `import.meta` is unavailable.
|
|
24
27
|
//
|
|
25
|
-
// Installing our own `prepareStackTrace`
|
|
26
|
-
//
|
|
27
|
-
//
|
|
28
|
-
//
|
|
29
|
-
// would resolve against a source tree that the image does not ship. Replacing the hook
|
|
30
|
-
// bypasses them and yields the emitted file, which is what the migrations sit beside.
|
|
28
|
+
// Installing our own `prepareStackTrace` bypasses `source-map-support` and
|
|
29
|
+
// `--enable-source-maps`, which return the original `.ts` path. The runtime image runs
|
|
30
|
+
// `node --enable-source-maps` (`apps/vc-builder/src/runtime.ts`), where the glob would resolve
|
|
31
|
+
// against a source tree the image does not ship.
|
|
31
32
|
function declaringFile(boundary) {
|
|
32
|
-
// The first frame specifically
|
|
33
|
-
//
|
|
34
|
-
// hand back whichever of our own callers happened to be beneath it.
|
|
33
|
+
// The first frame specifically. A caller that is not a file on disk has no declaring file, and
|
|
34
|
+
// the next frame down would be one of our own callers.
|
|
35
35
|
return stackFrameFiles(boundary, 2)[0];
|
|
36
36
|
}
|
|
37
37
|
export function defineVendureExtension(extension) {
|
|
@@ -41,9 +41,8 @@ export function defineVendureExtension(extension) {
|
|
|
41
41
|
}
|
|
42
42
|
const migrations = [...(extension.migrations ?? [])];
|
|
43
43
|
const declaredIn = declaringFile(defineVendureExtension);
|
|
44
|
-
// Raised at definition time
|
|
45
|
-
//
|
|
46
|
-
// matches nothing.
|
|
44
|
+
// Raised at definition time so a runtime that cannot report the declaring file fails on its first
|
|
45
|
+
// run, not with a glob that matches nothing.
|
|
47
46
|
if (declaredIn === undefined && migrations.some((glob) => !isAbsolute(glob))) {
|
|
48
47
|
throw new InvalidVendureExtensionError(`Vendure Cloud: the Vendure Extension "${id}" declares migrations as relative globs, and this runtime does not report the file that declared them.\n A relative glob is relative to that file, so it cannot be resolved. Write them as absolute paths instead.\n`);
|
|
49
48
|
}
|
|
@@ -52,20 +51,41 @@ export function defineVendureExtension(extension) {
|
|
|
52
51
|
id,
|
|
53
52
|
plugins: Object.freeze([...extension.plugins]),
|
|
54
53
|
migrations: Object.freeze(migrations),
|
|
55
|
-
outboundHosts: Object.freeze(
|
|
54
|
+
outboundHosts: Object.freeze(declaredOutboundHosts(id, extension.outboundHosts)),
|
|
56
55
|
declaredIn,
|
|
57
56
|
});
|
|
58
57
|
}
|
|
58
|
+
// Raised while the configuration is evaluated, which the managed build does before an image exists,
|
|
59
|
+
// so a bad declaration fails the build rather than a deployment.
|
|
60
|
+
function declaredOutboundHosts(id, declared) {
|
|
61
|
+
if (declared === undefined)
|
|
62
|
+
return [];
|
|
63
|
+
if (!Array.isArray(declared)) {
|
|
64
|
+
throw new InvalidVendureExtensionError(`Vendure Cloud: the Vendure Extension "${id}" declares outboundHosts as something other than a list.\n Declare a list of public hostnames, such as ['api.example.com'].\n`);
|
|
65
|
+
}
|
|
66
|
+
const hosts = [];
|
|
67
|
+
const problems = [];
|
|
68
|
+
declared.forEach((value, index) => {
|
|
69
|
+
const parsed = parseOutboundHost(value);
|
|
70
|
+
if ("host" in parsed)
|
|
71
|
+
hosts.push(parsed.host);
|
|
72
|
+
else
|
|
73
|
+
problems.push(` outboundHosts[${index}] ${parsed.problem}.\n`);
|
|
74
|
+
});
|
|
75
|
+
if (problems.length > 0) {
|
|
76
|
+
throw new InvalidOutboundHostsError(`Vendure Cloud: the Vendure Extension "${id}" declares outbound hosts that are not public hostnames.\n${problems.join("")} Declare each as a bare public hostname, such as 'api.example.com'.\n`);
|
|
77
|
+
}
|
|
78
|
+
return hosts;
|
|
79
|
+
}
|
|
59
80
|
export function isVendureExtension(value) {
|
|
60
81
|
return typeof value === "object" && value !== null && EXTENSION in value;
|
|
61
82
|
}
|
|
62
|
-
// String path resolution only; `loadExtensionMigrations` in `migrations.ts`
|
|
63
|
-
//
|
|
64
|
-
//
|
|
83
|
+
// String path resolution only; `loadExtensionMigrations` in `migrations.ts` reads what the result
|
|
84
|
+
// matches. Recording which extension owns each applied migration on the Deployment row is the
|
|
85
|
+
// other half of ADR-0048 and is CLO-423.
|
|
65
86
|
//
|
|
66
|
-
//
|
|
67
|
-
//
|
|
68
|
-
// index arithmetic that can be got wrong.
|
|
87
|
+
// The singular form exists because the loader reports an unmatched glob by the text the author
|
|
88
|
+
// wrote, and pairing that text with a positional result needs index arithmetic.
|
|
69
89
|
export function resolveMigrationGlob(extension, glob) {
|
|
70
90
|
if (isAbsolute(glob))
|
|
71
91
|
return glob;
|
|
@@ -77,13 +97,12 @@ export function resolveMigrationGlob(extension, glob) {
|
|
|
77
97
|
export function resolveExtensionMigrations(extension) {
|
|
78
98
|
return extension.migrations.map((glob) => resolveMigrationGlob(extension, glob));
|
|
79
99
|
}
|
|
80
|
-
// Turns the array a customer wrote
|
|
81
|
-
//
|
|
100
|
+
// Turns the array a customer wrote, plugins and extensions mixed, into the flat array core takes,
|
|
101
|
+
// in declaration order, and records which extension each plugin came from so
|
|
82
102
|
// `recordPlatformFieldWrites` can name both.
|
|
83
103
|
//
|
|
84
|
-
// A plugin declared by two extensions maps to the first
|
|
85
|
-
//
|
|
86
|
-
// no finer answer available here. Detecting that overlap at all is CLO-418.
|
|
104
|
+
// A plugin declared by two extensions maps to the first. Attribution is per plugin class, because
|
|
105
|
+
// core keeps the configuration function there. CLO-418 detects the overlap.
|
|
87
106
|
export function flattenVendureExtensions(entries) {
|
|
88
107
|
const plugins = [];
|
|
89
108
|
const extensions = [];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"vendure-extension.js","sourceRoot":"","sources":["../src/vendure-extension.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,UAAU,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEzD,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,eAAe,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"vendure-extension.js","sourceRoot":"","sources":["../src/vendure-extension.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vendure/cloud-config",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0-dev.20261016123507.ge07a06e",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "The Cloud Config interface a Vendure Cloud application is written against.",
|
|
6
6
|
"license": "MIT",
|
|
@@ -36,7 +36,8 @@
|
|
|
36
36
|
"README.md"
|
|
37
37
|
],
|
|
38
38
|
"publishConfig": {
|
|
39
|
-
"access": "public"
|
|
39
|
+
"access": "public",
|
|
40
|
+
"tag": "dev"
|
|
40
41
|
},
|
|
41
42
|
"scripts": {
|
|
42
43
|
"build": "tsc",
|
|
@@ -55,6 +56,11 @@
|
|
|
55
56
|
"@vendure/asset-server-plugin": "^3.7.0",
|
|
56
57
|
"@vendure/core": "^3.7.0"
|
|
57
58
|
},
|
|
59
|
+
"peerDependenciesMeta": {
|
|
60
|
+
"@vendure/core": {
|
|
61
|
+
"optional": true
|
|
62
|
+
}
|
|
63
|
+
},
|
|
58
64
|
"devDependencies": {
|
|
59
65
|
"@types/node": "^22.20.1",
|
|
60
66
|
"@vendure-cloud/tsconfig": "workspace:*",
|
|
@@ -62,5 +68,6 @@
|
|
|
62
68
|
"@vendure/core": "3.7.3",
|
|
63
69
|
"typescript": "catalog:",
|
|
64
70
|
"vitest": "^3.2.6"
|
|
65
|
-
}
|
|
71
|
+
},
|
|
72
|
+
"gitHead": "e07a06eb81ba944dcd1e2ca8bae155cb19fd1b59"
|
|
66
73
|
}
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
import { CloudConfigError } from "./errors.js";
|
|
2
|
-
import { type PluginLike } from "./plugin-attribution.js";
|
|
3
|
-
export type TenantWorkflow = (...args: never[]) => Promise<unknown>;
|
|
4
|
-
export declare const RESERVED_TENANT_WORKFLOW_NAME_PREFIX = "vendure-cloud.";
|
|
5
|
-
export interface TenantWorkflowDefinition {
|
|
6
|
-
readonly name: string;
|
|
7
|
-
readonly workflow: TenantWorkflow;
|
|
8
|
-
}
|
|
9
|
-
export interface RegisteredTenantWorkflow extends TenantWorkflowDefinition {
|
|
10
|
-
readonly declaredBy: string;
|
|
11
|
-
}
|
|
12
|
-
export interface SealedTenantWorkflowRegistry {
|
|
13
|
-
readonly workflows: readonly RegisteredTenantWorkflow[];
|
|
14
|
-
readonly digest: string;
|
|
15
|
-
}
|
|
16
|
-
export declare class TenantWorkflowDeclarationError extends CloudConfigError {
|
|
17
|
-
}
|
|
18
|
-
export type InvalidTenantWorkflowReason = "not-a-list" | "not-a-definition" | "name-not-a-string" | "no-name" | "untrimmed-name" | "name-contains-newline" | "reserved-name" | "not-a-function" | "plugin-not-extensible";
|
|
19
|
-
export declare class InvalidTenantWorkflowError extends TenantWorkflowDeclarationError {
|
|
20
|
-
readonly declaredBy: string;
|
|
21
|
-
readonly reason: InvalidTenantWorkflowReason;
|
|
22
|
-
constructor(declaredBy: string, reason: InvalidTenantWorkflowReason, detail: string);
|
|
23
|
-
}
|
|
24
|
-
export declare class DuplicateTenantWorkflowError extends TenantWorkflowDeclarationError {
|
|
25
|
-
readonly workflowName: string;
|
|
26
|
-
readonly declaredBy: string;
|
|
27
|
-
readonly conflictsWith: string;
|
|
28
|
-
constructor(workflowName: string, declaredBy: string, conflictsWith: string);
|
|
29
|
-
}
|
|
30
|
-
export declare class TenantWorkflowsAlreadyDeclaredError extends TenantWorkflowDeclarationError {
|
|
31
|
-
readonly declaredBy: string;
|
|
32
|
-
constructor(declaredBy: string);
|
|
33
|
-
}
|
|
34
|
-
export declare class LateTenantWorkflowDeclarationError extends TenantWorkflowDeclarationError {
|
|
35
|
-
readonly declaredBy: string;
|
|
36
|
-
constructor(declaredBy: string);
|
|
37
|
-
}
|
|
38
|
-
export declare class TenantWorkflowRegistrySealedTwiceError extends TenantWorkflowDeclarationError {
|
|
39
|
-
constructor();
|
|
40
|
-
}
|
|
41
|
-
export declare function declareTenantWorkflows(plugin: PluginLike, workflows: readonly TenantWorkflowDefinition[]): void;
|
|
42
|
-
export declare function sealTenantWorkflowRegistry(plugins: readonly PluginLike[]): SealedTenantWorkflowRegistry;
|
|
43
|
-
export declare function sealedTenantWorkflowRegistry(): SealedTenantWorkflowRegistry | undefined;
|
|
44
|
-
//# sourceMappingURL=tenant-workflows.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-workflows.d.ts","sourceRoot":"","sources":["../src/tenant-workflows.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,gBAAgB,EAAE,MAAM,aAAa,CAAC;AAC/C,OAAO,EAAE,KAAK,UAAU,EAA4B,MAAM,yBAAyB,CAAC;AAyBpF,MAAM,MAAM,cAAc,GAAG,CAAC,GAAG,IAAI,EAAE,KAAK,EAAE,KAAK,OAAO,CAAC,OAAO,CAAC,CAAC;AAMpE,eAAO,MAAM,oCAAoC,mBAAmB,CAAC;AAOrE,MAAM,WAAW,wBAAwB;IACvC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;CACnC;AAED,MAAM,WAAW,wBAAyB,SAAQ,wBAAwB;IACxE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;CAC7B;AAED,MAAM,WAAW,4BAA4B;IAG3C,QAAQ,CAAC,SAAS,EAAE,SAAS,wBAAwB,EAAE,CAAC;IAGxD,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC;CACzB;AAED,qBAAa,8BAA+B,SAAQ,gBAAgB;CAAG;AAKvE,MAAM,MAAM,2BAA2B,GACnC,YAAY,GACZ,kBAAkB,GAClB,mBAAmB,GACnB,SAAS,GACT,gBAAgB,GAChB,uBAAuB,GACvB,eAAe,GACf,gBAAgB,GAChB,uBAAuB,CAAC;AAE5B,qBAAa,0BAA2B,SAAQ,8BAA8B;IAC5E,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,MAAM,EAAE,2BAA2B,CAAC;gBAEjC,UAAU,EAAE,MAAM,EAAE,MAAM,EAAE,2BAA2B,EAAE,MAAM,EAAE,MAAM;CAOpF;AAKD,qBAAa,4BAA6B,SAAQ,8BAA8B;IAC9E,QAAQ,CAAC,YAAY,EAAE,MAAM,CAAC;IAC9B,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;IAC5B,QAAQ,CAAC,aAAa,EAAE,MAAM,CAAC;gBAEnB,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM;CAW5E;AAED,qBAAa,mCAAoC,SAAQ,8BAA8B;IACrF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,UAAU,EAAE,MAAM;CAM/B;AAED,qBAAa,kCAAmC,SAAQ,8BAA8B;IACpF,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,UAAU,EAAE,MAAM;CAM/B;AAED,qBAAa,sCAAuC,SAAQ,8BAA8B;;CAMzF;AAsBD,wBAAgB,sBAAsB,CACpC,MAAM,EAAE,UAAU,EAClB,SAAS,EAAE,SAAS,wBAAwB,EAAE,GAC7C,IAAI,CA4BN;AAID,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,SAAS,UAAU,EAAE,GAC7B,4BAA4B,CAuC9B;AAID,wBAAgB,4BAA4B,IAAI,4BAA4B,GAAG,SAAS,CAEvF"}
|
package/dist/tenant-workflows.js
DELETED
|
@@ -1,219 +0,0 @@
|
|
|
1
|
-
import { createHash } from "node:crypto";
|
|
2
|
-
import { CloudConfigError } from "./errors.js";
|
|
3
|
-
import { pluginName, pluginTarget } from "./plugin-attribution.js";
|
|
4
|
-
// How a tenant's durable workflows reach the executor the platform launches. ADR-0060's fourth open
|
|
5
|
-
// item owns the decision, the alternative it rejects and the reasoning; read it first.
|
|
6
|
-
//
|
|
7
|
-
// **It lives here rather than beside the executor because a customer has to be able to call it.**
|
|
8
|
-
// Under ADR-0046 the image supplies `@vendure-cloud/cloud-runtime` and a customer never installs it,
|
|
9
|
-
// so a declaration seam there reaches the platform's own plugins and nobody else's. This package is
|
|
10
|
-
// what `@vendure/cloud` re-exports, which is what a customer pins.
|
|
11
|
-
// Registered rather than module-local, for the reason the cloud config handle's symbol is
|
|
12
|
-
// (ADR-0043): a second copy of this package would otherwise write markers the sealing copy cannot
|
|
13
|
-
// read, and a plugin's workflows would never register with nothing reporting it.
|
|
14
|
-
const DECLARATION = Symbol.for("vendure-cloud.tenant-workflows");
|
|
15
|
-
// Whether any copy has sealed. Registered for the same reason the marker is, and a boolean rather
|
|
16
|
-
// than the registry itself so that reading it needs no validation: a second copy that began with
|
|
17
|
-
// its own flag unset would accept a declaration the sealing copy has already gone past, write it to
|
|
18
|
-
// the shared marker, and leave nobody to register it.
|
|
19
|
-
const SEALED = Symbol.for("vendure-cloud.tenant-workflows.sealed");
|
|
20
|
-
// Reserved for workflows the platform may come to register on a tenant executor. Those would not
|
|
21
|
-
// arrive through this seam, so the seal could not see the collision; refusing the prefix now costs
|
|
22
|
-
// one comparison, and reserving it after a customer has shipped a workflow under it would strand
|
|
23
|
-
// the recorded steps behind that name.
|
|
24
|
-
export const RESERVED_TENANT_WORKFLOW_NAME_PREFIX = "vendure-cloud.";
|
|
25
|
-
export class TenantWorkflowDeclarationError extends CloudConfigError {
|
|
26
|
-
}
|
|
27
|
-
export class InvalidTenantWorkflowError extends TenantWorkflowDeclarationError {
|
|
28
|
-
declaredBy;
|
|
29
|
-
reason;
|
|
30
|
-
constructor(declaredBy, reason, detail) {
|
|
31
|
-
super(`Vendure Cloud: ${declaredBy} declared durable workflows the platform cannot register. ${detail} Refusing to boot.\n`);
|
|
32
|
-
this.declaredBy = declaredBy;
|
|
33
|
-
this.reason = reason;
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
// A workflow name is the identity its recorded steps are replayed against, so two workflows cannot
|
|
37
|
-
// share one. Two plugins claiming a name and one plugin claiming it twice are different mistakes to
|
|
38
|
-
// correct, so they are different sentences.
|
|
39
|
-
export class DuplicateTenantWorkflowError extends TenantWorkflowDeclarationError {
|
|
40
|
-
workflowName;
|
|
41
|
-
declaredBy;
|
|
42
|
-
conflictsWith;
|
|
43
|
-
constructor(workflowName, declaredBy, conflictsWith) {
|
|
44
|
-
const name = JSON.stringify(workflowName);
|
|
45
|
-
super(declaredBy === conflictsWith
|
|
46
|
-
? `Vendure Cloud: ${declaredBy} declared the durable workflow ${name} twice. A workflow name is the identity its recorded steps are replayed against, so two workflows cannot share one. Rename one of them. Refusing to boot.\n`
|
|
47
|
-
: `Vendure Cloud: the durable workflow ${name} was declared by both ${declaredBy} and ${conflictsWith}. A workflow name is the identity its recorded steps are replayed against, so two workflows cannot share one. Rename one of them. Refusing to boot.\n`);
|
|
48
|
-
this.workflowName = workflowName;
|
|
49
|
-
this.declaredBy = declaredBy;
|
|
50
|
-
this.conflictsWith = conflictsWith;
|
|
51
|
-
}
|
|
52
|
-
}
|
|
53
|
-
export class TenantWorkflowsAlreadyDeclaredError extends TenantWorkflowDeclarationError {
|
|
54
|
-
declaredBy;
|
|
55
|
-
constructor(declaredBy) {
|
|
56
|
-
super(`Vendure Cloud: ${declaredBy} declared its durable workflows twice. The second declaration would replace the first, so the workflows in it would never run. Declare them once. Refusing to boot.\n`);
|
|
57
|
-
this.declaredBy = declaredBy;
|
|
58
|
-
}
|
|
59
|
-
}
|
|
60
|
-
export class LateTenantWorkflowDeclarationError extends TenantWorkflowDeclarationError {
|
|
61
|
-
declaredBy;
|
|
62
|
-
constructor(declaredBy) {
|
|
63
|
-
super(`Vendure Cloud: ${declaredBy} declared durable workflows after the platform had read the registered set. Declare them where the plugin class is defined. Refusing to boot.\n`);
|
|
64
|
-
this.declaredBy = declaredBy;
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
export class TenantWorkflowRegistrySealedTwiceError extends TenantWorkflowDeclarationError {
|
|
68
|
-
constructor() {
|
|
69
|
-
super("Vendure Cloud: the durable workflow registry was sealed twice in one process. Two seals are two answers to which workflows this process runs, and only one of them reaches the executor. Refusing to boot.\n");
|
|
70
|
-
}
|
|
71
|
-
}
|
|
72
|
-
// This copy's answer, held so that a caller reaching the seal's result from a second call site does
|
|
73
|
-
// not have to seal again — which would refuse. It is undefined in a copy that did not seal, and the
|
|
74
|
-
// seal refuses in every copy once any of them has, so there is exactly one of these in a process.
|
|
75
|
-
let sealed;
|
|
76
|
-
function anyCopyHasSealed() {
|
|
77
|
-
return Reflect.get(globalThis, SEALED) === true;
|
|
78
|
-
}
|
|
79
|
-
function readDeclaration(target) {
|
|
80
|
-
// An own declaration only. A subclass of a plugin that declares workflows inherits the marker down
|
|
81
|
-
// the prototype chain, and both classes in one plugins array would then present the same names — a
|
|
82
|
-
// duplicate refusal against a boot that had nothing wrong with it. A subclass that wants workflows
|
|
83
|
-
// declares its own.
|
|
84
|
-
if (!Object.hasOwn(target, DECLARATION))
|
|
85
|
-
return undefined;
|
|
86
|
-
return target[DECLARATION];
|
|
87
|
-
}
|
|
88
|
-
export function declareTenantWorkflows(plugin, workflows) {
|
|
89
|
-
const declaredBy = pluginName(plugin);
|
|
90
|
-
if (anyCopyHasSealed()) {
|
|
91
|
-
throw new LateTenantWorkflowDeclarationError(declaredBy);
|
|
92
|
-
}
|
|
93
|
-
// `pluginTarget`, because a plugin reaches the array either as a class or as a DynamicModule
|
|
94
|
-
// wrapping one and the declaration belongs on the class. A declaration written on the wrapper
|
|
95
|
-
// would be missed by every read.
|
|
96
|
-
const target = pluginTarget(plugin);
|
|
97
|
-
if (readDeclaration(target) !== undefined) {
|
|
98
|
-
throw new TenantWorkflowsAlreadyDeclaredError(declaredBy);
|
|
99
|
-
}
|
|
100
|
-
// Checked here as well as at the seal, so that the stack names the file the declaration was
|
|
101
|
-
// written in.
|
|
102
|
-
const checked = assertIsRegistrable(workflows, declaredBy);
|
|
103
|
-
if (!Object.isExtensible(target)) {
|
|
104
|
-
// `defineProperty` would throw a bare TypeError naming neither the plugin nor what it was doing,
|
|
105
|
-
// which is the outcome the checks above exist to avoid.
|
|
106
|
-
throw new InvalidTenantWorkflowError(declaredBy, "plugin-not-extensible", "The plugin class is sealed or frozen, so the declaration cannot be attached to it.");
|
|
107
|
-
}
|
|
108
|
-
// Frozen through to each entry, for the reason the sealed set is. Non-enumerable, so the plugin
|
|
109
|
-
// spreads and serialises as it did before — a visible property would appear in anything that
|
|
110
|
-
// inspects the plugins array as configuration nobody wrote.
|
|
111
|
-
Object.defineProperty(target, DECLARATION, { value: checked });
|
|
112
|
-
}
|
|
113
|
-
// The one read, and the point after which nothing may be added. Every run mode may call it; the
|
|
114
|
-
// process that launches an executor registers exactly what it returns.
|
|
115
|
-
export function sealTenantWorkflowRegistry(plugins) {
|
|
116
|
-
if (anyCopyHasSealed()) {
|
|
117
|
-
throw new TenantWorkflowRegistrySealedTwiceError();
|
|
118
|
-
}
|
|
119
|
-
const byName = new Map();
|
|
120
|
-
// A plugins array holding one class twice, or a class and a DynamicModule around it, resolves to
|
|
121
|
-
// one declaration. Without this the second pass reports that declaration as a duplicate of itself
|
|
122
|
-
// and refuses a boot that had nothing wrong with it.
|
|
123
|
-
const read = new Set();
|
|
124
|
-
for (const plugin of plugins) {
|
|
125
|
-
const target = pluginTarget(plugin);
|
|
126
|
-
if (read.has(target))
|
|
127
|
-
continue;
|
|
128
|
-
read.add(target);
|
|
129
|
-
const declared = readDeclaration(target);
|
|
130
|
-
if (declared === undefined)
|
|
131
|
-
continue;
|
|
132
|
-
const declaredBy = pluginName(plugin);
|
|
133
|
-
// Validated again, because a declaration can arrive through the registered marker from a copy of
|
|
134
|
-
// this package that predates a rule added here, having never passed the checks above.
|
|
135
|
-
for (const definition of assertIsRegistrable(declared, declaredBy)) {
|
|
136
|
-
const first = byName.get(definition.name);
|
|
137
|
-
if (first !== undefined) {
|
|
138
|
-
throw new DuplicateTenantWorkflowError(definition.name, first.declaredBy, declaredBy);
|
|
139
|
-
}
|
|
140
|
-
byName.set(definition.name, Object.freeze({ ...definition, declaredBy }));
|
|
141
|
-
}
|
|
142
|
-
}
|
|
143
|
-
// Compared by code unit rather than with `localeCompare`, which reads the process's locale and
|
|
144
|
-
// would order two processes' identical sets differently.
|
|
145
|
-
const workflows = [...byName.values()].sort(compareByName);
|
|
146
|
-
sealed = Object.freeze({
|
|
147
|
-
workflows: Object.freeze(workflows),
|
|
148
|
-
digest: digestOf(workflows),
|
|
149
|
-
});
|
|
150
|
-
Reflect.set(globalThis, SEALED, true);
|
|
151
|
-
return sealed;
|
|
152
|
-
}
|
|
153
|
-
// What this copy sealed, for a caller that needs the set at launch and the digest beside the
|
|
154
|
-
// application version and does not hold the seal's return value at both.
|
|
155
|
-
export function sealedTenantWorkflowRegistry() {
|
|
156
|
-
return sealed;
|
|
157
|
-
}
|
|
158
|
-
function compareByName(a, b) {
|
|
159
|
-
if (a.name === b.name)
|
|
160
|
-
return 0;
|
|
161
|
-
return a.name < b.name ? -1 : 1;
|
|
162
|
-
}
|
|
163
|
-
// Newline-separated for the reason ADR-0061 separates its own two inputs with one: a name carrying a
|
|
164
|
-
// newline is refused, so no two sets of names compose one digest. SHA-256, lowercase hex, UTF-8 and
|
|
165
|
-
// the separator are all things two builds have to agree on, so a test pins the output against
|
|
166
|
-
// literals rather than recomputing it.
|
|
167
|
-
function digestOf(workflows) {
|
|
168
|
-
return createHash("sha256")
|
|
169
|
-
.update(workflows.map((workflow) => workflow.name).join("\n"), "utf8")
|
|
170
|
-
.digest("hex");
|
|
171
|
-
}
|
|
172
|
-
// A plugin written in JavaScript, or compiled against an older copy of this package, carries
|
|
173
|
-
// whatever it holds. So the list, each entry and each field are checked rather than the two fields
|
|
174
|
-
// TypeScript happens to name.
|
|
175
|
-
function assertIsRegistrable(workflows, declaredBy) {
|
|
176
|
-
if (!Array.isArray(workflows)) {
|
|
177
|
-
throw new InvalidTenantWorkflowError(declaredBy, "not-a-list", `The declaration is ${describeType(workflows)} rather than a list of workflows.`);
|
|
178
|
-
}
|
|
179
|
-
const checked = [];
|
|
180
|
-
const names = new Set();
|
|
181
|
-
for (const definition of workflows) {
|
|
182
|
-
if (typeof definition !== "object" || definition === null) {
|
|
183
|
-
throw new InvalidTenantWorkflowError(declaredBy, "not-a-definition", `The declaration holds ${describeType(definition)} where a workflow was expected.`);
|
|
184
|
-
}
|
|
185
|
-
const { name, workflow } = definition;
|
|
186
|
-
if (typeof name !== "string") {
|
|
187
|
-
throw new InvalidTenantWorkflowError(declaredBy, "name-not-a-string", `A workflow is named ${describeType(name)} rather than a string.`);
|
|
188
|
-
}
|
|
189
|
-
if (name.length === 0) {
|
|
190
|
-
throw new InvalidTenantWorkflowError(declaredBy, "no-name", "A workflow needs a name.");
|
|
191
|
-
}
|
|
192
|
-
if (name.trim() !== name) {
|
|
193
|
-
throw new InvalidTenantWorkflowError(declaredBy, "untrimmed-name", `The name ${JSON.stringify(name)} is surrounded by whitespace, which nothing reading a log line can see and which makes two names a person reads as one.`);
|
|
194
|
-
}
|
|
195
|
-
if (name.includes("\n")) {
|
|
196
|
-
throw new InvalidTenantWorkflowError(declaredBy, "name-contains-newline", `The name ${JSON.stringify(name)} contains a newline, which separates one name from the next in the registered set's identity.`);
|
|
197
|
-
}
|
|
198
|
-
if (name.startsWith(RESERVED_TENANT_WORKFLOW_NAME_PREFIX)) {
|
|
199
|
-
throw new InvalidTenantWorkflowError(declaredBy, "reserved-name", `The name ${JSON.stringify(name)} begins with ${JSON.stringify(RESERVED_TENANT_WORKFLOW_NAME_PREFIX)}, which Vendure Cloud reserves for its own workflows.`);
|
|
200
|
-
}
|
|
201
|
-
if (typeof workflow !== "function") {
|
|
202
|
-
throw new InvalidTenantWorkflowError(declaredBy, "not-a-function", `The workflow ${JSON.stringify(name)} is ${describeType(workflow)} rather than a function.`);
|
|
203
|
-
}
|
|
204
|
-
if (names.has(name)) {
|
|
205
|
-
throw new DuplicateTenantWorkflowError(name, declaredBy, declaredBy);
|
|
206
|
-
}
|
|
207
|
-
names.add(name);
|
|
208
|
-
checked.push(Object.freeze({ name, workflow }));
|
|
209
|
-
}
|
|
210
|
-
return Object.freeze(checked);
|
|
211
|
-
}
|
|
212
|
-
function describeType(value) {
|
|
213
|
-
if (value === null)
|
|
214
|
-
return "null";
|
|
215
|
-
if (Array.isArray(value))
|
|
216
|
-
return "a list";
|
|
217
|
-
return `a value of type ${typeof value}`;
|
|
218
|
-
}
|
|
219
|
-
//# sourceMappingURL=tenant-workflows.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"tenant-workflows.js","sourceRoot":"","sources":["../src/tenant-workflows.ts"],"names":[],"mappings":"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"}
|