@pithy-sh/core 0.7.3 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/naming/domains.d.ts +43 -3
- package/dist/naming/domains.d.ts.map +1 -1
- package/dist/naming/domains.js +62 -4
- package/dist/naming/feature.d.ts +126 -11
- package/dist/naming/feature.d.ts.map +1 -1
- package/dist/naming/feature.js +184 -30
- package/dist/naming/limits.d.ts +23 -7
- package/dist/naming/limits.d.ts.map +1 -1
- package/dist/naming/limits.js +22 -9
- package/dist/naming/provisionScope.d.ts +25 -11
- package/dist/naming/provisionScope.d.ts.map +1 -1
- package/dist/naming/provisionScope.js +28 -11
- package/dist/seed/seed.d.ts +36 -7
- package/dist/seed/seed.d.ts.map +1 -1
- package/dist/version.generated.d.ts +1 -1
- package/dist/version.generated.js +1 -1
- package/dist/worker/identity.d.ts +9 -0
- package/dist/worker/identity.d.ts.map +1 -1
- package/dist/worker/identity.js +10 -1
- package/dist/workflow/faults.d.ts +34 -2
- package/dist/workflow/faults.d.ts.map +1 -1
- package/dist/workflow/faults.js +42 -18
- package/dist/workflow/host.d.ts +7 -0
- package/dist/workflow/host.d.ts.map +1 -1
- package/dist/workflow/host.js +5 -3
- package/dist/workflow/naming.d.ts +8 -0
- package/dist/workflow/naming.d.ts.map +1 -1
- package/dist/workflow/naming.js +15 -0
- package/package.json +1 -1
- package/src/naming/domains.ts +75 -5
- package/src/naming/feature.ts +274 -38
- package/src/naming/limits.ts +25 -8
- package/src/naming/provisionScope.ts +39 -14
- package/src/seed/seed.ts +36 -7
- package/src/version.generated.ts +1 -1
- package/src/worker/identity.ts +10 -0
- package/src/workflow/faults.ts +61 -4
- package/src/workflow/host.ts +15 -3
- package/src/workflow/naming.ts +25 -0
package/dist/seed/seed.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../src/seed/seed.ts"],"names":[],"mappings":"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
|
|
1
|
+
{"version":3,"file":"seed.d.ts","sourceRoot":"","sources":["../../src/seed/seed.ts"],"names":[],"mappings":"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"}
|
|
@@ -3,5 +3,5 @@
|
|
|
3
3
|
/** This package's npm name — the join key against a release feed. */
|
|
4
4
|
export declare const PACKAGE_NAME = "@pithy-sh/core";
|
|
5
5
|
/** This package's version, stamped from its own package.json at generation time. */
|
|
6
|
-
export declare const PACKAGE_VERSION = "0.
|
|
6
|
+
export declare const PACKAGE_VERSION = "0.8.0";
|
|
7
7
|
//# sourceMappingURL=version.generated.d.ts.map
|
|
@@ -4,6 +4,6 @@
|
|
|
4
4
|
/** This package's npm name — the join key against a release feed. */
|
|
5
5
|
const PACKAGE_NAME = "@pithy-sh/core";
|
|
6
6
|
/** This package's version, stamped from its own package.json at generation time. */
|
|
7
|
-
const PACKAGE_VERSION = "0.
|
|
7
|
+
const PACKAGE_VERSION = "0.8.0";
|
|
8
8
|
//#endregion
|
|
9
9
|
export { PACKAGE_NAME, PACKAGE_VERSION };
|
|
@@ -24,6 +24,15 @@
|
|
|
24
24
|
export declare const PROJECT_VAR = "PROJECT";
|
|
25
25
|
/** The var naming the environment this deployment serves — `dev`, `staging`, or `prod`. */
|
|
26
26
|
export declare const ENVIRONMENT_VAR = "ENVIRONMENT";
|
|
27
|
+
/**
|
|
28
|
+
* The var naming where a deployed Worker answers — `https://<host>`, no path, no trailing slash.
|
|
29
|
+
*
|
|
30
|
+
* Generated, never hand-set: `pithy worker sync` writes it from a declared domain, and `pithy provision
|
|
31
|
+
* --feature` writes a feature's from its `workers.dev` address (#643). It is the one statement of a feature's
|
|
32
|
+
* origin a running Worker can read, because the account's `workers.dev` subdomain is something only the
|
|
33
|
+
* Cloudflare API knows, and a Worker has no business calling it at module scope.
|
|
34
|
+
*/
|
|
35
|
+
export declare const BASE_URL_VAR = "BASE_URL";
|
|
27
36
|
/**
|
|
28
37
|
* The var carrying a Worker's **own** dev origin, from `pithy dev` to whatever launches that Worker.
|
|
29
38
|
*
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/worker/identity.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,qFAAqF;AACrF,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,2FAA2F;AAC3F,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,WAAW,CAAC;AAEnC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,SAAS,CAAC;AAEnC,qGAAqG;AACrG,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,wEAAwE;IACxE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;;;;OAQG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,qBAAqB;IACpC,yGAAyG;IACzG,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAW3D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,qBAAqB,CAazE;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAEzD"}
|
|
1
|
+
{"version":3,"file":"identity.d.ts","sourceRoot":"","sources":["../../src/worker/identity.ts"],"names":[],"mappings":"AAGA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,qFAAqF;AACrF,eAAO,MAAM,WAAW,YAAY,CAAC;AAErC,2FAA2F;AAC3F,eAAO,MAAM,eAAe,gBAAgB,CAAC;AAE7C;;;;;;;GAOG;AACH,eAAO,MAAM,YAAY,aAAa,CAAC;AAEvC;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,iBAAiB,wBAAwB,CAAC;AAEvD;;;;;;;GAOG;AACH,eAAO,MAAM,UAAU,WAAW,CAAC;AAEnC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,wBAAwB,wBAAwB,CAAC;AAE9D;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,YAAY,SAAS,CAAC;AAEnC,qGAAqG;AACrG,MAAM,WAAW,cAAc;IAC7B,8EAA8E;IAC9E,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;IACvB,wEAAwE;IACxE,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;IAC3B,2EAA2E;IAC3E,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB;;;;;;;;OAQG;IACH,OAAO,EAAE,MAAM,GAAG,IAAI,CAAC;CACxB;AAED;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,qBAAqB;IACpC,yGAAyG;IACzG,EAAE,EAAE,MAAM,GAAG,IAAI,CAAC;IAClB;;;;;;;OAOG;IACH,GAAG,EAAE,MAAM,GAAG,IAAI,CAAC;IACnB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA6BG;IACH,SAAS,EAAE,MAAM,GAAG,IAAI,CAAC;CAC1B;AAgBD;;;;;;;;;GASG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,OAAO,GAAG,cAAc,CAW3D;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AACH,wBAAgB,qBAAqB,CAAC,GAAG,EAAE,OAAO,GAAG,qBAAqB,CAazE;AAED;;;;;;;;GAQG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAEzD"}
|
package/dist/worker/identity.js
CHANGED
|
@@ -26,6 +26,15 @@ const PROJECT_VAR = "PROJECT";
|
|
|
26
26
|
/** The var naming the environment this deployment serves — `dev`, `staging`, or `prod`. */
|
|
27
27
|
const ENVIRONMENT_VAR = "ENVIRONMENT";
|
|
28
28
|
/**
|
|
29
|
+
* The var naming where a deployed Worker answers — `https://<host>`, no path, no trailing slash.
|
|
30
|
+
*
|
|
31
|
+
* Generated, never hand-set: `pithy worker sync` writes it from a declared domain, and `pithy provision
|
|
32
|
+
* --feature` writes a feature's from its `workers.dev` address (#643). It is the one statement of a feature's
|
|
33
|
+
* origin a running Worker can read, because the account's `workers.dev` subdomain is something only the
|
|
34
|
+
* Cloudflare API knows, and a Worker has no business calling it at module scope.
|
|
35
|
+
*/
|
|
36
|
+
const BASE_URL_VAR = "BASE_URL";
|
|
37
|
+
/**
|
|
29
38
|
* The var carrying a Worker's **own** dev origin, from `pithy dev` to whatever launches that Worker.
|
|
30
39
|
*
|
|
31
40
|
* Not stamped into `wrangler.jsonc` like the three above, and that is the whole point of it. A dev port
|
|
@@ -175,4 +184,4 @@ function workerVersion(env) {
|
|
|
175
184
|
return workerVersionMetadata(env).id;
|
|
176
185
|
}
|
|
177
186
|
//#endregion
|
|
178
|
-
export { ENVIRONMENT_VAR, PROJECT_VAR, SELF_BINDING, VERSION_METADATA_BINDING, WORKER_ORIGIN_VAR, WORKER_VAR, workerIdentity, workerVersion, workerVersionMetadata };
|
|
187
|
+
export { BASE_URL_VAR, ENVIRONMENT_VAR, PROJECT_VAR, SELF_BINDING, VERSION_METADATA_BINDING, WORKER_ORIGIN_VAR, WORKER_VAR, workerIdentity, workerVersion, workerVersionMetadata };
|
|
@@ -65,10 +65,42 @@ export interface WorkflowFault {
|
|
|
65
65
|
* test rather than a claim — and so the same function decides in a test, in Miniflare, and in production.
|
|
66
66
|
*/
|
|
67
67
|
export declare function classifyWorkflowFault(error: unknown, policy: WorkflowRetryPolicy): WorkflowFault;
|
|
68
|
-
/**
|
|
68
|
+
/**
|
|
69
|
+
* The half of a Workflow step this kit uses: run a named body, or serve its journalled result.
|
|
70
|
+
*
|
|
71
|
+
* **`sleep` is optional here and required on what {@link classifiedSteps} hands back, and the asymmetry
|
|
72
|
+
* is the truth rather than a convenience.** The platform's own `WorkflowStep` always offers one. What
|
|
73
|
+
* does not are this kit's hand-written test doubles, which exist to exercise the classification and
|
|
74
|
+
* nothing else — and demanding a primitive the classifier never classifies would cost every one of them
|
|
75
|
+
* a line of noise. Handing an optional one back instead would push a null check into the one caller that
|
|
76
|
+
* genuinely pauses.
|
|
77
|
+
*/
|
|
69
78
|
export interface WorkflowStepLike {
|
|
70
79
|
/** Run a named step, or return its journalled result if this instance already completed it. */
|
|
71
80
|
do<T>(name: string, fn: () => Promise<T>): Promise<T>;
|
|
81
|
+
/**
|
|
82
|
+
* Pause the instance for `durationMs` and resume it afterwards — possibly in a fresh isolate, which
|
|
83
|
+
* is the whole reason a caller reaches for it rather than for a timer. Absent only on a test double.
|
|
84
|
+
*/
|
|
85
|
+
sleep?(name: string, durationMs: number): Promise<void>;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* A step runner that can pause — what {@link classifiedSteps} hands back, always.
|
|
89
|
+
*
|
|
90
|
+
* The durable pause is why this type exists rather than being a convenience over the one above. A `sleep`
|
|
91
|
+
* is journalled, so a wait survives the instance being evicted during it; a `setTimeout` inside one step
|
|
92
|
+
* burns that step's wall clock and dies with the instance holding it.
|
|
93
|
+
*
|
|
94
|
+
* **It was introduced on a stronger claim, and the claim did not survive contact (pithy-sh/pithy#647).** The
|
|
95
|
+
* argument was that a Secrets Store binding answers the same for its isolate's whole life, so only a resume
|
|
96
|
+
* into a fresh isolate could ever see a write land. Measured against a real store on 2026-09-25, that is
|
|
97
|
+
* false: a binding refreshes inside a live isolate roughly 1.3-1.5s after the REST write, proved by holding
|
|
98
|
+
* two isolates warm through a write and watching each serve the old value before it and the new one after,
|
|
99
|
+
* over 328 samples. The durability argument above is the true one and is sufficient on its own.
|
|
100
|
+
*/
|
|
101
|
+
export interface DurableStepLike extends WorkflowStepLike {
|
|
102
|
+
/** Pause the instance for `durationMs`, then resume. */
|
|
103
|
+
sleep(name: string, durationMs: number): Promise<void>;
|
|
72
104
|
}
|
|
73
105
|
/**
|
|
74
106
|
* The platform's terminal-error class — `NonRetryableError` from `cloudflare:workflows`, taken as a
|
|
@@ -95,5 +127,5 @@ export interface TerminalErrorConstructor {
|
|
|
95
127
|
* `runSendBatch`, `runAtRestKeyRotation`) takes this instead with no change: the classification is
|
|
96
128
|
* declared once, at the entrypoint, and every step below it inherits the decision.
|
|
97
129
|
*/
|
|
98
|
-
export declare function classifiedSteps(step: WorkflowStepLike, policy: WorkflowRetryPolicy, terminalError: TerminalErrorConstructor):
|
|
130
|
+
export declare function classifiedSteps(step: WorkflowStepLike, policy: WorkflowRetryPolicy, terminalError: TerminalErrorConstructor): DurableStepLike;
|
|
99
131
|
//# sourceMappingURL=faults.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"faults.d.ts","sourceRoot":"","sources":["../../src/workflow/faults.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,2FAA2F;AAC3F,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,UAAU,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,iHAAiH;IACjH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC7C;AAED,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,WAAW,EAAE,wBAAwB,CAAC;IACtC,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;CAChB;AAsDD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,GAAG,aAAa,CA0BhG;AAED
|
|
1
|
+
{"version":3,"file":"faults.d.ts","sourceRoot":"","sources":["../../src/workflow/faults.ts"],"names":[],"mappings":"AAOA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,2FAA2F;AAC3F,MAAM,MAAM,wBAAwB,GAAG,OAAO,GAAG,UAAU,CAAC;AAE5D;;;;;;GAMG;AACH,MAAM,WAAW,mBAAmB;IAClC,iHAAiH;IACjH,UAAU,EAAE,MAAM,CAAC;IACnB;;;;OAIG;IACH,SAAS,EAAE,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,CAAC;CAC7C;AAED,2FAA2F;AAC3F,MAAM,WAAW,aAAa;IAC5B,sBAAsB;IACtB,WAAW,EAAE,wBAAwB,CAAC;IACtC,mFAAmF;IACnF,IAAI,EAAE,MAAM,CAAC;IACb,+EAA+E;IAC/E,MAAM,EAAE,MAAM,CAAC;CAChB;AAsDD;;;GAGG;AACH,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,OAAO,EAAE,MAAM,EAAE,mBAAmB,GAAG,aAAa,CA0BhG;AAED;;;;;;;;;GASG;AACH,MAAM,WAAW,gBAAgB;IAC/B,+FAA+F;IAC/F,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,MAAM,EAAE,EAAE,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAAC;IACtD;;;OAGG;IACH,KAAK,CAAC,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACzD;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,eAAgB,SAAQ,gBAAgB;IACvD,wDAAwD;IACxD,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;CACxD;AAED;;;;;;;;;;;;;GAaG;AACH,MAAM,WAAW,wBAAwB;IACvC,KAAK,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;CAC9B;AAED;;;;;;;GAOG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,gBAAgB,EACtB,MAAM,EAAE,mBAAmB,EAC3B,aAAa,EAAE,wBAAwB,GACtC,eAAe,CAmDjB"}
|
package/dist/workflow/faults.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
-
import { PithyError } from "../error/pithyError.js";
|
|
3
|
+
import { InternalError, PithyError } from "../error/pithyError.js";
|
|
4
4
|
import { d1TransientFault } from "../data/withD1Retry.js";
|
|
5
5
|
import { encodeWorkflowStepMessage } from "./stepMessage.js";
|
|
6
6
|
//#region src/workflow/faults.ts
|
|
@@ -91,23 +91,47 @@ function classifyWorkflowFault(error, policy) {
|
|
|
91
91
|
* declared once, at the entrypoint, and every step below it inherits the decision.
|
|
92
92
|
*/
|
|
93
93
|
function classifiedSteps(step, policy, terminalError) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
94
|
+
const runner = {
|
|
95
|
+
do(name, fn) {
|
|
96
|
+
return step.do(name, async () => {
|
|
97
|
+
try {
|
|
98
|
+
return await fn();
|
|
99
|
+
} catch (error) {
|
|
100
|
+
const fault = classifyWorkflowFault(error, policy);
|
|
101
|
+
if (fault.disposition === "retry") throw error;
|
|
102
|
+
const terminal = new terminalError(encodeWorkflowStepMessage({
|
|
103
|
+
code: fault.code,
|
|
104
|
+
message: messageOf(error),
|
|
105
|
+
action: pithyActionOf(error)
|
|
106
|
+
}));
|
|
107
|
+
terminal.cause = error;
|
|
108
|
+
throw terminal;
|
|
109
|
+
}
|
|
110
|
+
});
|
|
111
|
+
},
|
|
112
|
+
/**
|
|
113
|
+
* Forwarded, and deliberately unclassified. A pause raises no fault of the capability's — the
|
|
114
|
+
* instance either resumes or it is gone — so there is nothing here for a policy to decide.
|
|
115
|
+
*
|
|
116
|
+
* A runner that cannot pause is refused, and the refusal is raised **through `do`** rather than
|
|
117
|
+
* thrown from here. A throw from here is a throw the engine never classifies, so it is free to
|
|
118
|
+
* re-drive the instance — and re-driving is the unbounded loop the caller is spending its sleeps to
|
|
119
|
+
* avoid. Going through `do` makes the refusal terminal on its first attempt, like every other
|
|
120
|
+
* answer that cannot change.
|
|
121
|
+
*/
|
|
122
|
+
sleep(name, durationMs) {
|
|
123
|
+
const pause = step.sleep;
|
|
124
|
+
if (pause === void 0) return runner.do(`${name}/cannot-pause`, async () => {
|
|
125
|
+
throw new InternalError({
|
|
126
|
+
message: "This Workflow step runner cannot pause.",
|
|
127
|
+
action: "Give the step runner a `sleep`; the platform's own `WorkflowStep` always has one.",
|
|
128
|
+
detail: `step '${name}' asked to pause ${durationMs}ms through a runner that declares no sleep`
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
return pause.call(step, name, durationMs);
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
return runner;
|
|
111
135
|
}
|
|
112
136
|
//#endregion
|
|
113
137
|
export { classifiedSteps, classifyWorkflowFault };
|
package/dist/workflow/host.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
+
import type { FeatureIdentity } from "../naming/feature";
|
|
3
4
|
import { type WorkflowHostNameParts } from "./naming";
|
|
4
5
|
import type { WorkflowRegistry } from "./spec";
|
|
5
6
|
/**
|
|
@@ -106,6 +107,12 @@ export interface WorkflowHostParams {
|
|
|
106
107
|
capability: string;
|
|
107
108
|
/** The target environment (`dev` | `staging` | `production`). */
|
|
108
109
|
env: string;
|
|
110
|
+
/**
|
|
111
|
+
* The feature this host serves, when it serves one (#643). Its name then takes the feature's head —
|
|
112
|
+
* `<project>-f<issue>-<slug>-<capability>` — as the Workflows derived with the same parts do; `env` still
|
|
113
|
+
* says `feature`, and that is what the host's `ENVIRONMENT` var is stamped with.
|
|
114
|
+
*/
|
|
115
|
+
feature?: FeatureIdentity;
|
|
109
116
|
/** D1 binding name → database id. An unlisted binding keeps the template's id. */
|
|
110
117
|
databaseIds?: Record<string, string>;
|
|
111
118
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/workflow/host.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"host.d.ts","sourceRoot":"","sources":["../../src/workflow/host.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,mBAAmB,CAAC;AAEzD,OAAO,EAAE,KAAK,qBAAqB,EAAwC,MAAM,UAAU,CAAC;AAC5F,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,QAAQ,CAAC;AAE/C;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,uGAAuG;AACvG,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;CACZ;AAED,+CAA+C;AAC/C,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,WAAW,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,8GAA8G;AAC9G,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,CAAC;IACnB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,4GAA4G;AAC5G,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,kEAAkE;AAClE,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAED,kGAAkG;AAClG,MAAM,WAAW,uBAAuB;IACtC,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AAED,sGAAsG;AACtG,MAAM,WAAW,mBAAmB;IAClC,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,MAAM,CAAC;IACb,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;;GAIG;AACH,MAAM,WAAW,oBAAoB;IACnC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,mBAAmB,CAAC,EAAE,MAAM,EAAE,CAAC;IAC/B,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,aAAa,EAAE,CAAC;IAC/B,aAAa,CAAC,EAAE,aAAa,EAAE,CAAC;IAChC,UAAU,CAAC,EAAE,aAAa,EAAE,CAAC;IAC7B,SAAS,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACnC,EAAE,CAAC,EAAE,aAAa,CAAC;IACnB,UAAU,CAAC,EAAE,oBAAoB,EAAE,CAAC;IACpC,qBAAqB,CAAC,EAAE,uBAAuB,EAAE,CAAC;IAClD,SAAS,CAAC,EAAE,mBAAmB,EAAE,CAAC;IAClC,QAAQ,CAAC,EAAE;QAAE,KAAK,EAAE,MAAM,EAAE,CAAA;KAAE,CAAC;IAC/B,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAC/B;AAED,yGAAyG;AACzG,MAAM,WAAW,kBAAkB;IACjC;;;;;OAKG;IACH,OAAO,EAAE,MAAM,CAAC;IAChB,4FAA4F;IAC5F,UAAU,EAAE,MAAM,CAAC;IACnB,iEAAiE;IACjE,GAAG,EAAE,MAAM,CAAC;IACZ;;;;OAIG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;IAC1B,kFAAkF;IAClF,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC;;;;OAIG;IACH,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,sCAAsC;IACtC,cAAc,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,qCAAqC;IACrC,aAAa,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACvC,2CAA2C;IAC3C,mBAAmB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC7C,wEAAwE;IACxE,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,MAAM,CAAC;IAC7B;;;;;;OAMG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACrC,iGAAiG;IACjG,IAAI,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAC9B;;;OAGG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;OAGG;IACH,cAAc,CAAC,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC;;;;;;;;;OASG;IACH,SAAS,CAAC,EAAE,SAAS,mBAAmB,EAAE,CAAC;CAC5C;AAOD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,oBAAoB,EAAE,MAAM,EAAE,kBAAkB,GAAG,oBAAoB,CAgGpH;AAED;;;;GAIG;AACH,wBAAgB,gBAAgB,CAC9B,QAAQ,EAAE,gBAAgB,EAC1B,KAAK,EAAE,qBAAqB,GAC3B;IAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,EAAE,CAAA;CAAE,CAsBvD"}
|
package/dist/workflow/host.js
CHANGED
|
@@ -31,7 +31,8 @@ function resolveWorkflowHost(template, params) {
|
|
|
31
31
|
resolved.name = workflowHostName({
|
|
32
32
|
project: params.project,
|
|
33
33
|
capability: params.capability,
|
|
34
|
-
env: params.env
|
|
34
|
+
env: params.env,
|
|
35
|
+
...params.feature ? { feature: params.feature } : {}
|
|
35
36
|
});
|
|
36
37
|
if (resolved.d1_databases) resolved.d1_databases = resolved.d1_databases.map((entry) => ({
|
|
37
38
|
...entry,
|
|
@@ -91,7 +92,7 @@ function resolveWorkflowHost(template, params) {
|
|
|
91
92
|
* `className` cannot be hosted: there would be no class for wrangler to instantiate.
|
|
92
93
|
*/
|
|
93
94
|
function hostWorkflowsFor(registry, parts) {
|
|
94
|
-
const { project, capability, env } = parts;
|
|
95
|
+
const { project, capability, env, feature } = parts;
|
|
95
96
|
const owned = Object.values(registry).filter((entry) => entry.capability === capability);
|
|
96
97
|
const workflows = [];
|
|
97
98
|
const crons = [];
|
|
@@ -106,7 +107,8 @@ function hostWorkflowsFor(registry, parts) {
|
|
|
106
107
|
project,
|
|
107
108
|
capability,
|
|
108
109
|
job: entry.job,
|
|
109
|
-
env
|
|
110
|
+
env,
|
|
111
|
+
...feature ? { feature } : {}
|
|
110
112
|
}),
|
|
111
113
|
class_name: entry.spec.className
|
|
112
114
|
});
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
// SPDX-FileCopyrightText: 2026 Pithy
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
|
+
import { type FeatureIdentity } from "../naming/feature";
|
|
3
4
|
/**
|
|
4
5
|
* Every name a durable job answers to, in one module. The CLI writes these into a host worker's
|
|
5
6
|
* resolved `wrangler.jsonc`, the provisioner deploys under them, and the dispatcher resolves
|
|
@@ -43,6 +44,13 @@ export interface WorkflowHostNameParts {
|
|
|
43
44
|
capability: string;
|
|
44
45
|
/** The deployment environment (e.g. `staging`). */
|
|
45
46
|
env: string;
|
|
47
|
+
/**
|
|
48
|
+
* **The feature this deployment is, when it is one (#643).** A feature's host Worker and Workflows take the
|
|
49
|
+
* feature's head — `<project>-f<issue>-<slug>-…` — not `<project>-feature-…`, which every open branch would
|
|
50
|
+
* share: Worker and Workflow names are account-wide, so a second branch's deploy would replace the first's.
|
|
51
|
+
* `env` stays `feature`, which is what the host's `ENVIRONMENT` var says; only the names change.
|
|
52
|
+
*/
|
|
53
|
+
feature?: FeatureIdentity;
|
|
46
54
|
}
|
|
47
55
|
/** The identity of one durable job's Workflow in one environment. */
|
|
48
56
|
export interface WorkflowScriptNameParts extends WorkflowHostNameParts {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/workflow/naming.ts"],"names":[],"mappings":"
|
|
1
|
+
{"version":3,"file":"naming.d.ts","sourceRoot":"","sources":["../../src/workflow/naming.ts"],"names":[],"mappings":"AAIA,OAAO,EAAE,KAAK,eAAe,EAA0C,MAAM,mBAAmB,CAAC;AAKjG;;;;;;;;;;;;;;;;GAgBG;AAEH;;;;;;;GAOG;AACH,eAAO,MAAM,uBAAuB,IAAsC,CAAC;AAE3E;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,IAAoC,CAAC;AAkFvE,oEAAoE;AACpE,MAAM,WAAW,qBAAqB;IACpC,gHAAgH;IAChH,OAAO,EAAE,MAAM,CAAC;IAChB,+DAA+D;IAC/D,UAAU,EAAE,MAAM,CAAC;IACnB,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;IACZ;;;;;OAKG;IACH,OAAO,CAAC,EAAE,eAAe,CAAC;CAC3B;AAED,qEAAqE;AACrE,MAAM,WAAW,uBAAwB,SAAQ,qBAAqB;IACpE,mDAAmD;IACnD,GAAG,EAAE,MAAM,CAAC;CACb;AAED;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,uBAAuB,GAAG,MAAM,CAMzE;AAED;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,qBAAqB,GAAG,MAAM,CAIrE;AAED;;;;;;;;GAQG;AACH,wBAAgB,WAAW,CAAC,UAAU,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAInE"}
|
package/dist/workflow/naming.js
CHANGED
|
@@ -4,6 +4,7 @@ import { InternalError } from "../error/pithyError.js";
|
|
|
4
4
|
import { NAME_SEGMENT } from "../naming/segment.js";
|
|
5
5
|
import { NAMESPACE_LIMITS } from "../naming/limits.js";
|
|
6
6
|
import { assertValidProjectName, kebab } from "../naming/resource.js";
|
|
7
|
+
import { featureWorkerName, featureWorkflowName } from "../naming/feature.js";
|
|
7
8
|
//#region src/workflow/naming.ts
|
|
8
9
|
/**
|
|
9
10
|
* Every name a durable job answers to, in one module. The CLI writes these into a host worker's
|
|
@@ -96,6 +97,18 @@ function head(project, env) {
|
|
|
96
97
|
return `${kebab(project)}-${env}`;
|
|
97
98
|
}
|
|
98
99
|
/**
|
|
100
|
+
* The feature a name is composed for, held to the project the parts name — two projects in one set of parts is
|
|
101
|
+
* a name composed for somebody else's feature.
|
|
102
|
+
*/
|
|
103
|
+
function featureOf(parts) {
|
|
104
|
+
const feature = parts.feature;
|
|
105
|
+
if (feature.project !== parts.project) throw new InternalError({
|
|
106
|
+
message: "A feature's Workflow name was asked for with two different projects.",
|
|
107
|
+
detail: `parts name project "${parts.project}" and a feature of project "${feature.project}".`
|
|
108
|
+
});
|
|
109
|
+
return feature;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
99
112
|
* The deployed name of one job's Workflow in one environment — `<project>-<env>-<capability>-<job>`,
|
|
100
113
|
* e.g. `acme-staging-media-image-to-text`. This is what the CLI writes as the `name` of a
|
|
101
114
|
* `workflows` entry, and what `CloudflareWorkflowsClient` addresses when triggering from outside
|
|
@@ -109,6 +122,7 @@ function workflowScriptName(parts) {
|
|
|
109
122
|
assertSegment(parts.capability, "capability");
|
|
110
123
|
assertSegment(parts.job, "job");
|
|
111
124
|
assertCapabilityJob(parts.capability, parts.job);
|
|
125
|
+
if (parts.feature) return featureWorkflowName(featureOf(parts), parts.capability, parts.job);
|
|
112
126
|
return assertLength(`${head(parts.project, parts.env)}-${parts.capability}-${parts.job}`, MAX_WORKFLOW_NAME_BYTES);
|
|
113
127
|
}
|
|
114
128
|
/**
|
|
@@ -120,6 +134,7 @@ function workflowScriptName(parts) {
|
|
|
120
134
|
*/
|
|
121
135
|
function workflowHostName(parts) {
|
|
122
136
|
assertSegment(parts.capability, "capability");
|
|
137
|
+
if (parts.feature) return featureWorkerName(featureOf(parts), parts.capability);
|
|
123
138
|
return assertLength(`${head(parts.project, parts.env)}-${parts.capability}`, MAX_WORKER_NAME_BYTES);
|
|
124
139
|
}
|
|
125
140
|
/**
|
package/package.json
CHANGED
package/src/naming/domains.ts
CHANGED
|
@@ -2,7 +2,9 @@
|
|
|
2
2
|
// SPDX-License-Identifier: MIT
|
|
3
3
|
|
|
4
4
|
import { z } from "zod";
|
|
5
|
-
import {
|
|
5
|
+
import { type AmbientEnv, ambientEnv } from "../env/ambient";
|
|
6
|
+
import { BASE_URL_VAR } from "../worker/identity";
|
|
7
|
+
import { ENVIRONMENTS, FEATURE_ENVIRONMENT } from "./environment";
|
|
6
8
|
|
|
7
9
|
/**
|
|
8
10
|
* Where a Worker answers, declared once per Worker per environment.
|
|
@@ -39,6 +41,18 @@ import { ENVIRONMENTS } from "./environment";
|
|
|
39
41
|
/** A hostname a Worker answers on. No scheme, no path, no port — wrangler's `routes` pattern is a host. */
|
|
40
42
|
const HOSTNAME_PATTERN = /^(?!-)[a-z0-9-]{1,63}(?<!-)(\.(?!-)[a-z0-9-]{1,63}(?<!-))+$/;
|
|
41
43
|
|
|
44
|
+
/**
|
|
45
|
+
* Whether a string is a public hostname: dot-separated DNS labels, at least two, lowercase. No scheme, no
|
|
46
|
+
* port, no trailing dot, and nothing a URL parser decoded into one — `%2e%2e` is `..` once parsed, which is an
|
|
47
|
+
* empty label rather than a host (#643). `localhost` is not one: it has a single label, and it is this machine.
|
|
48
|
+
*
|
|
49
|
+
* The one test for "is this a host" that an origin read from a stamp and an origin typed on a command line
|
|
50
|
+
* both pass, so the two cannot accept different things.
|
|
51
|
+
*/
|
|
52
|
+
export function isPublicHostname(hostname: string): boolean {
|
|
53
|
+
return hostname.length <= 253 && HOSTNAME_PATTERN.test(hostname);
|
|
54
|
+
}
|
|
55
|
+
|
|
42
56
|
/** The environments a domain may be declared for — every managed one, never `dev`. */
|
|
43
57
|
export const DOMAIN_ENVIRONMENTS = ENVIRONMENTS.filter((environment) => environment !== "dev");
|
|
44
58
|
|
|
@@ -135,10 +149,46 @@ export interface ResolvedOrigin {
|
|
|
135
149
|
origin: string;
|
|
136
150
|
/** The hostname alone: a route pattern, and what Turnstile binds a widget to. */
|
|
137
151
|
hostname: string;
|
|
138
|
-
/**
|
|
152
|
+
/**
|
|
153
|
+
* Whether `domains` declared it. `false` means {@link LOCAL_ORIGIN} was substituted, or — for a feature
|
|
154
|
+
* environment only — that the address is the `workers.dev` one provisioning stamped ({@link featureOrigin}).
|
|
155
|
+
*/
|
|
139
156
|
declared: boolean;
|
|
140
157
|
}
|
|
141
158
|
|
|
159
|
+
/**
|
|
160
|
+
* **A feature environment's origin: the `workers.dev` address provisioning stamped, or null (#643).**
|
|
161
|
+
*
|
|
162
|
+
* A feature Worker answers on `https://<script>.<account subdomain>.workers.dev`. Nothing can declare that —
|
|
163
|
+
* `domains` has no feature key, because a branch's hostname is composed from the branch — and the Worker cannot
|
|
164
|
+
* derive it either, because the subdomain is the account's and only the Cloudflare API knows it. So `pithy
|
|
165
|
+
* provision --feature` derives it, through the CLI's one address resolver, and stamps it as the feature
|
|
166
|
+
* stanza's {@link BASE_URL_VAR}. This is the one reader of that stamp.
|
|
167
|
+
*
|
|
168
|
+
* **Only a `workers.dev` https origin is accepted, and that is the guard rather than a tidiness check.** A
|
|
169
|
+
* feature stanza is generated from the Worker's top level, so a `BASE_URL` somebody set by hand up there
|
|
170
|
+
* arrives in the feature too — and it is another environment's origin, most likely production's. Honoring it
|
|
171
|
+
* would send a branch's magic links into production, which is the one thing {@link resolveOrigin} exists to
|
|
172
|
+
* make impossible. A feature's address is `workers.dev` by construction, so anything else is not one and
|
|
173
|
+
* resolves to nothing. No path, no port, no credentials: an origin, or null.
|
|
174
|
+
*/
|
|
175
|
+
export function featureOrigin(stamped: string | undefined): { origin: string; hostname: string } | null {
|
|
176
|
+
if (!stamped) return null;
|
|
177
|
+
let url: URL;
|
|
178
|
+
try {
|
|
179
|
+
url = new URL(stamped);
|
|
180
|
+
} catch {
|
|
181
|
+
return null;
|
|
182
|
+
}
|
|
183
|
+
if (url.protocol !== "https:" || url.port !== "" || url.username !== "" || url.password !== "") return null;
|
|
184
|
+
if (url.pathname !== "/" || url.search !== "" || url.hash !== "") return null;
|
|
185
|
+
// A script name and an account subdomain, at least: `workers.dev` alone, or `<sub>.workers.dev`, is not a Worker.
|
|
186
|
+
if (!url.hostname.endsWith(".workers.dev") || url.hostname.split(".").length < 4) return null;
|
|
187
|
+
// Every label a DNS label: the parser decodes `%2e%2e` into `..`, which ends in `.workers.dev` and is no host.
|
|
188
|
+
if (!isPublicHostname(url.hostname)) return null;
|
|
189
|
+
return { origin: url.origin, hostname: url.hostname };
|
|
190
|
+
}
|
|
191
|
+
|
|
142
192
|
/**
|
|
143
193
|
* **Where is this Worker publicly reachable, in this environment?** — asked once, answered once.
|
|
144
194
|
*
|
|
@@ -164,10 +214,21 @@ export interface ResolvedOrigin {
|
|
|
164
214
|
* checks that stored value, so a per-environment issuer would make a connection minted in staging
|
|
165
215
|
* unverifiable in production. That may be the better isolation, but it is a decision about trust rather
|
|
166
216
|
* than about reachability, and a helper whose job is "where am I reachable" must not sweep it up.
|
|
217
|
+
*
|
|
218
|
+
* **`stamped` is a feature environment's `BASE_URL`, and is read for nothing else** — see {@link featureOrigin}.
|
|
167
219
|
*/
|
|
168
|
-
export function resolveOrigin(
|
|
220
|
+
export function resolveOrigin(
|
|
221
|
+
environment: string | undefined,
|
|
222
|
+
domains: WorkerDomains | undefined,
|
|
223
|
+
stamped?: string | undefined,
|
|
224
|
+
): ResolvedOrigin {
|
|
169
225
|
const domain = domainFor(domains, environment);
|
|
170
226
|
if (domain) return { origin: baseUrlFor(domain), hostname: domain.pattern, declared: true };
|
|
227
|
+
// A feature environment, and only a feature environment, reads the address provisioning stamped. Every other
|
|
228
|
+
// environment ignores `stamped` outright: a declared one without a domain is unpublished, and `dev` resolves
|
|
229
|
+
// its address from the request.
|
|
230
|
+
const feature = environment === FEATURE_ENVIRONMENT ? featureOrigin(stamped) : null;
|
|
231
|
+
if (feature) return { ...feature, declared: false };
|
|
171
232
|
return { origin: LOCAL_ORIGIN, hostname: "localhost", declared: false };
|
|
172
233
|
}
|
|
173
234
|
|
|
@@ -188,7 +249,16 @@ export function resolveOrigin(environment: string | undefined, domains: WorkerDo
|
|
|
188
249
|
* `AUTH_BASE_URL`, which is part of why `email` and `payments` were missed for days: the constant read
|
|
189
250
|
* as auth's private business when it is the Worker's address, and every capability that needs an origin
|
|
190
251
|
* needs this one.
|
|
252
|
+
*
|
|
253
|
+
* **A feature deployment is answered from its own vars (#643).** `env` is the ambient environment — inside a
|
|
254
|
+
* Worker, its own vars — and it is read for one thing: the `BASE_URL` a feature's provisioning stamped. So the
|
|
255
|
+
* same scaffolded line gives auth's base URL, email's links and payments' return URLs a feature's real
|
|
256
|
+
* `workers.dev` origin, rather than `http://localhost`, with nothing added to the adopter's config.
|
|
191
257
|
*/
|
|
192
|
-
export function originFor(
|
|
193
|
-
|
|
258
|
+
export function originFor(
|
|
259
|
+
environment: string | undefined,
|
|
260
|
+
domains: WorkerDomains | undefined,
|
|
261
|
+
env: AmbientEnv = ambientEnv(),
|
|
262
|
+
): string {
|
|
263
|
+
return resolveOrigin(environment, domains, env[BASE_URL_VAR]).origin;
|
|
194
264
|
}
|