@ganju/utils 0.0.3 → 0.0.4
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/constants.d.ts +6 -2
- package/dist/constants.d.ts.map +1 -1
- package/dist/constants.js +45 -12
- package/dist/customCodeToken.d.ts +40 -5
- package/dist/customCodeToken.d.ts.map +1 -1
- package/dist/customCodeToken.js +77 -6
- package/dist/index.d.ts +8 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -0
- package/package.json +1 -1
- package/src/constants.ts +48 -12
- package/src/customCodeToken.ts +85 -5
- package/src/index.ts +5 -1
package/dist/constants.d.ts
CHANGED
|
@@ -519,6 +519,10 @@ export declare const constants: {
|
|
|
519
519
|
CUSTOM_CODE_MAX_FILE_PATH: number;
|
|
520
520
|
CUSTOM_CODE_VERSION_STATUSES: ("draft" | "published" | "archived")[];
|
|
521
521
|
CUSTOM_CODE_SCRIPT_NAME_PREFIX: string;
|
|
522
|
+
CUSTOM_CODE_SCRIPT_NAME_MAX: number;
|
|
523
|
+
CUSTOM_CODE_UPLOAD_SUFFIX_CHARS: number;
|
|
524
|
+
CUSTOM_CODE_SWEEP_GRACE_MS: number;
|
|
525
|
+
CUSTOM_CODE_SWEEP_MAX_DELETES: number;
|
|
522
526
|
CUSTOM_CODE_PREVIEW_SCRIPT_SUFFIX: string;
|
|
523
527
|
CUSTOM_CODE_PREVIEW_TOKEN_TTL_MS: number;
|
|
524
528
|
CUSTOM_CODE_TEST_TIMEOUT_MS: number;
|
|
@@ -560,8 +564,8 @@ export declare const constants: {
|
|
|
560
564
|
CUSTOM_CODE_BROKER_SERVICE_ENV: string;
|
|
561
565
|
CUSTOM_CODE_COMPATIBILITY_DATE: string;
|
|
562
566
|
CUSTOM_CODE_SCRIPT_CPU_MS: number;
|
|
563
|
-
|
|
564
|
-
|
|
567
|
+
CUSTOM_CODE_REGISTER_TIMEOUT_MS: number;
|
|
568
|
+
CUSTOM_CODE_REGISTER_INTERVAL_MS: number;
|
|
565
569
|
CUSTOM_CODE_MAX_LOGS: number;
|
|
566
570
|
CUSTOM_CODE_MAX_LOG_LENGTH: number;
|
|
567
571
|
CUSTOM_CODE_SEND_FILE_TARGET_GMAIL: "gmail";
|
package/dist/constants.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AA6JA,QAAA,MAAM,yBAAyB,EAAiB,UAAU,CAAC;AAC3D,QAAA,MAAM,+BAA+B,EAAuB,gBAAgB,CAAC;AAC7E,QAAA,MAAM,8BAA8B,EAAsB,eAAe,CAAC;AAC1E,QAAA,MAAM,wBAAwB,EAAgB,SAAS,CAAC;AAuCxD,QAAA,MAAM,sBAAsB,EAAiB,UAAU,CAAC;AACxD,QAAA,MAAM,4BAA4B,EAAuB,gBAAgB,CAAC;AAC1E,QAAA,MAAM,oBAAoB,EAAe,QAAQ,CAAC;AAClD,QAAA,MAAM,oBAAoB,EAAe,QAAQ,CAAC;AAmYlD,QAAA,MAAM,sBAAsB,EAAkB,WAAW,CAAC;AAC1D,QAAA,MAAM,mBAAmB,EAAe,QAAQ,CAAC;AAGjD,QAAA,MAAM,mBAAmB,EAAe,QAAQ,CAAC;AAkTjD,MAAM,MAAM,mBAAmB,GAC3B;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC3D;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,GAC9D;IACE,GAAG,EAAE,MAAM,CAAC;IACZ,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,EAAE,QAAQ,CAAC;IACf,OAAO,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,MAAM,CAAA;KAAE,EAAE,CAAC;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAC;CACf,GACD;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,UAAU,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"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"}
|
package/dist/constants.js
CHANGED
|
@@ -1041,9 +1041,36 @@ const CUSTOM_CODE_MAIN_MODULE = 'index.js';
|
|
|
1041
1041
|
// object read on every deploy.
|
|
1042
1042
|
const CUSTOM_CODE_MAX_FILES = 25;
|
|
1043
1043
|
const CUSTOM_CODE_MAX_FILE_PATH = 100;
|
|
1044
|
-
// WfP script name: `artifact_<artifactId>`. The id, never the slug —
|
|
1045
|
-
// user-editable and a rename would orphan the deployed script.
|
|
1044
|
+
// WfP script name: `artifact_<artifactId>_<upload>`. The id, never the slug —
|
|
1045
|
+
// slugs are user-editable and a rename would orphan the deployed script.
|
|
1046
|
+
//
|
|
1047
|
+
// The trailing segment is minted per upload rather than derived from anything,
|
|
1048
|
+
// which is the whole point: uploading over a name that already exists is not
|
|
1049
|
+
// read-your-writes, so a deploy that replaces a script can serve the previous
|
|
1050
|
+
// edition for up to half a minute. A name nothing has ever used cannot, and
|
|
1051
|
+
// costs nothing to mint. Everything a publish used to do to survive that race —
|
|
1052
|
+
// waiting on an edition marker, refusing with a 503, putting the previous bundle
|
|
1053
|
+
// back when validation failed — went with the reuse that caused it.
|
|
1046
1054
|
const CUSTOM_CODE_SCRIPT_NAME_PREFIX = 'artifact_';
|
|
1055
|
+
// Worker names cap at 63 characters, and `artifact_<uuid>` already spends 45.
|
|
1056
|
+
// That leaves 17 for a separator and a suffix, so a second uuid does not fit and
|
|
1057
|
+
// neither does a hex-32 digest. Twelve hex characters is 48 bits against a
|
|
1058
|
+
// namespace holding at most a few hundred names for any one artifact — not a
|
|
1059
|
+
// collision worth checking for, and an upload to a name in use would fail loudly
|
|
1060
|
+
// rather than quietly serve the wrong code.
|
|
1061
|
+
const CUSTOM_CODE_SCRIPT_NAME_MAX = 63;
|
|
1062
|
+
const CUSTOM_CODE_UPLOAD_SUFFIX_CHARS = 12;
|
|
1063
|
+
// How long a superseded script stays in the namespace before the hourly sweep
|
|
1064
|
+
// may collect it.
|
|
1065
|
+
//
|
|
1066
|
+
// Deleting at publish time would race the thing it deletes: a tool call that
|
|
1067
|
+
// resolved the old pointer a moment earlier is still in flight, and the pointer
|
|
1068
|
+
// moving does not recall it. An hour is far longer than any call can take, and
|
|
1069
|
+
// the wait costs $0.02 per script per month against an allowance of 1,000.
|
|
1070
|
+
const CUSTOM_CODE_SWEEP_GRACE_MS = 60 * 60 * 1_000;
|
|
1071
|
+
// Deletes per sweep. A backlog drains over several hourly runs rather than
|
|
1072
|
+
// making one run unbounded — the same shape the retention purge uses.
|
|
1073
|
+
const CUSTOM_CODE_SWEEP_MAX_DELETES = 200;
|
|
1047
1074
|
// A second script per artifact, `artifact_<id>_preview`, that the Test panel
|
|
1048
1075
|
// deploys a draft into and calls.
|
|
1049
1076
|
//
|
|
@@ -1228,15 +1255,17 @@ const CUSTOM_CODE_COMPATIBILITY_DATE = '2025-11-17';
|
|
|
1228
1255
|
// tighter than our own workers' 30s — this is the technical cap that bounds
|
|
1229
1256
|
// what one adversarial call can cost us, so an infinite loop in a customer's
|
|
1230
1257
|
// tool is billed as five seconds rather than as whatever it wanted.
|
|
1231
|
-
// How long
|
|
1232
|
-
//
|
|
1258
|
+
// How long a deploy waits for a freshly minted script name to become
|
|
1259
|
+
// dispatchable, and how often it asks.
|
|
1233
1260
|
//
|
|
1234
|
-
//
|
|
1235
|
-
//
|
|
1236
|
-
//
|
|
1237
|
-
//
|
|
1238
|
-
|
|
1239
|
-
|
|
1261
|
+
// Every upload goes to a name that has never been used, which is
|
|
1262
|
+
// read-your-writes: ~2s end to end against the deployed namespace, against the
|
|
1263
|
+
// 20-41s a replacement could take. So this bounds how long a brand-new name
|
|
1264
|
+
// takes to register, never how long an old edition takes to stop answering —
|
|
1265
|
+
// there is no old edition. It is short for that reason, and a script that
|
|
1266
|
+
// answers with the wrong edition now fails outright instead of being waited on.
|
|
1267
|
+
const CUSTOM_CODE_REGISTER_TIMEOUT_MS = 8_000;
|
|
1268
|
+
const CUSTOM_CODE_REGISTER_INTERVAL_MS = 500;
|
|
1240
1269
|
const CUSTOM_CODE_SCRIPT_CPU_MS = 5_000;
|
|
1241
1270
|
// The ctx.log() caps also live in ./sdkConstants — the buffer that enforces them
|
|
1242
1271
|
// runs inside the isolate.
|
|
@@ -2139,6 +2168,10 @@ exports.constants = {
|
|
|
2139
2168
|
CUSTOM_CODE_MAX_FILE_PATH,
|
|
2140
2169
|
CUSTOM_CODE_VERSION_STATUSES,
|
|
2141
2170
|
CUSTOM_CODE_SCRIPT_NAME_PREFIX,
|
|
2171
|
+
CUSTOM_CODE_SCRIPT_NAME_MAX,
|
|
2172
|
+
CUSTOM_CODE_UPLOAD_SUFFIX_CHARS,
|
|
2173
|
+
CUSTOM_CODE_SWEEP_GRACE_MS,
|
|
2174
|
+
CUSTOM_CODE_SWEEP_MAX_DELETES,
|
|
2142
2175
|
CUSTOM_CODE_PREVIEW_SCRIPT_SUFFIX,
|
|
2143
2176
|
CUSTOM_CODE_PREVIEW_TOKEN_TTL_MS,
|
|
2144
2177
|
CUSTOM_CODE_TEST_TIMEOUT_MS,
|
|
@@ -2180,8 +2213,8 @@ exports.constants = {
|
|
|
2180
2213
|
CUSTOM_CODE_BROKER_SERVICE_ENV,
|
|
2181
2214
|
CUSTOM_CODE_COMPATIBILITY_DATE,
|
|
2182
2215
|
CUSTOM_CODE_SCRIPT_CPU_MS,
|
|
2183
|
-
|
|
2184
|
-
|
|
2216
|
+
CUSTOM_CODE_REGISTER_TIMEOUT_MS,
|
|
2217
|
+
CUSTOM_CODE_REGISTER_INTERVAL_MS,
|
|
2185
2218
|
CUSTOM_CODE_MAX_LOGS: sdkConstants_1.CUSTOM_CODE_MAX_LOGS,
|
|
2186
2219
|
CUSTOM_CODE_MAX_LOG_LENGTH: sdkConstants_1.CUSTOM_CODE_MAX_LOG_LENGTH,
|
|
2187
2220
|
CUSTOM_CODE_SEND_FILE_TARGET_GMAIL,
|
|
@@ -24,18 +24,53 @@ export declare const mintCustomCodeToken: (payload: Omit<CustomCodeTokenPayload,
|
|
|
24
24
|
*/
|
|
25
25
|
export declare const verifyCustomCodeToken: (token: string, secret: string, now?: number) => Promise<CustomCodeTokenPayload | null>;
|
|
26
26
|
/**
|
|
27
|
-
* The dispatch-namespace script name for an artifact: `artifact_<id>`.
|
|
27
|
+
* The legacy dispatch-namespace script name for an artifact: `artifact_<id>`.
|
|
28
28
|
*
|
|
29
29
|
* The id, never the slug — slugs are user-editable and a rename would orphan the
|
|
30
30
|
* deployed script while the database still pointed at a live version.
|
|
31
|
+
*
|
|
32
|
+
* Nothing uploads to this name any more; every deploy mints its own. It survives
|
|
33
|
+
* as the fallback for a version published before `script_name` existed, whose
|
|
34
|
+
* bundle really is sitting under this name. Tightening a rule must never stop an
|
|
35
|
+
* already-published version from serving, because that failure is invisible to
|
|
36
|
+
* whoever owns it — the same reason the boot loop still accepts a stored tool key
|
|
37
|
+
* the current catalog no longer offers.
|
|
31
38
|
*/
|
|
32
39
|
export declare const customCodeScriptName: (artifactId: string) => string;
|
|
33
40
|
/**
|
|
34
|
-
* The script name
|
|
41
|
+
* The legacy preview script name: `artifact_<id>_preview`.
|
|
35
42
|
*
|
|
36
|
-
*
|
|
37
|
-
*
|
|
38
|
-
*
|
|
43
|
+
* Kept for the same reason as the one above, and for one more: it is the prefix
|
|
44
|
+
* the sweep matches to recognise a preview script left behind by a test run that
|
|
45
|
+
* did not clean up after itself.
|
|
39
46
|
*/
|
|
40
47
|
export declare const customCodePreviewScriptName: (artifactId: string) => string;
|
|
48
|
+
/**
|
|
49
|
+
* A dispatch-namespace name no upload has ever used:
|
|
50
|
+
* `artifact_<id>_<12 hex chars>`.
|
|
51
|
+
*
|
|
52
|
+
* Minted rather than derived, and that is the entire design. Uploading over an
|
|
53
|
+
* existing name is not read-your-writes — a replacement can serve the previous
|
|
54
|
+
* edition for tens of seconds — so a deploy that always writes to a new name is
|
|
55
|
+
* correct by construction rather than by waiting to see whether it worked.
|
|
56
|
+
*
|
|
57
|
+
* The suffix deliberately carries no meaning. The two candidates that did are
|
|
58
|
+
* both wrong: the bundle digest collides whenever a deploy reverts to bytes that
|
|
59
|
+
* shipped before, which is exactly what a rollback is, and the version id is one
|
|
60
|
+
* string across every re-upload of a single draft, which is every test run of it.
|
|
61
|
+
*
|
|
62
|
+
* Twelve hex characters is what fits. Worker names cap at 63 and
|
|
63
|
+
* `artifact_<uuid>` spends 45 of them.
|
|
64
|
+
*/
|
|
65
|
+
export declare const customCodeUploadName: (artifactId: string) => string;
|
|
66
|
+
/**
|
|
67
|
+
* A preview name no test run has ever used:
|
|
68
|
+
* `artifact_<id>_preview_<12 hex chars>`.
|
|
69
|
+
*
|
|
70
|
+
* The sharper version of the same race. Every test used to deploy over one
|
|
71
|
+
* preview name, so a test could report the run before it — which reads as "my
|
|
72
|
+
* edit did nothing" from the one tool whose whole job is to say what an edit
|
|
73
|
+
* does. Nothing stores this: it is minted, used, and deleted inside one request.
|
|
74
|
+
*/
|
|
75
|
+
export declare const customCodePreviewUploadName: (artifactId: string) => string;
|
|
41
76
|
//# sourceMappingURL=customCodeToken.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"customCodeToken.d.ts","sourceRoot":"","sources":["../src/customCodeToken.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,sBAAsB;IAGrC,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IAGnB,SAAS,EAAE,MAAM,CAAC;IAIlB,GAAG,EAAE,MAAM,CAAC;IAOZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA0BD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,SAAS,IAAI,CAAC,sBAAsB,EAAE,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,GAAG;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,EACD,QAAQ,MAAM,EACd,WAAU,MAAmB,KAC5B,OAAO,CAAC,MAAM,CAmBhB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,MAAM,EACb,QAAQ,MAAM,EACd,MAAM,MAAM,KACX,OAAO,CAAC,sBAAsB,GAAG,IAAI,CA+DvC,CAAC;AAEF
|
|
1
|
+
{"version":3,"file":"customCodeToken.d.ts","sourceRoot":"","sources":["../src/customCodeToken.ts"],"names":[],"mappings":"AAuBA,MAAM,WAAW,sBAAsB;IAGrC,CAAC,EAAE,MAAM,CAAC;IACV,UAAU,EAAE,MAAM,CAAC;IAGnB,SAAS,EAAE,MAAM,CAAC;IAIlB,GAAG,EAAE,MAAM,CAAC;IAOZ,OAAO,CAAC,EAAE,OAAO,CAAC;IAGlB,GAAG,CAAC,EAAE,MAAM,CAAC;CACd;AA0BD;;;;GAIG;AACH,eAAO,MAAM,mBAAmB,GAC9B,SAAS,IAAI,CAAC,sBAAsB,EAAE,GAAG,GAAG,KAAK,GAAG,KAAK,CAAC,GAAG;IAC3D,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB,EACD,QAAQ,MAAM,EACd,WAAU,MAAmB,KAC5B,OAAO,CAAC,MAAM,CAmBhB,CAAC;AAEF;;;;;;;GAOG;AACH,eAAO,MAAM,qBAAqB,GAChC,OAAO,MAAM,EACb,QAAQ,MAAM,EACd,MAAM,MAAM,KACX,OAAO,CAAC,sBAAsB,GAAG,IAAI,CA+DvC,CAAC;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,oBAAoB,GAAI,YAAY,MAAM,KAAG,MACE,CAAC;AAE7D;;;;;;GAMG;AACH,eAAO,MAAM,2BAA2B,GAAI,YAAY,MAAM,KAAG,MACoB,CAAC;AAEtF;;;;;;;;;;;;;;;;GAgBG;AACH,eAAO,MAAM,oBAAoB,GAAI,YAAY,MAAM,KAAG,MACR,CAAC;AAEnD;;;;;;;;GAQG;AACH,eAAO,MAAM,2BAA2B,GAAI,YAAY,MAAM,KAAG,MACR,CAAC"}
|
package/dist/customCodeToken.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.customCodePreviewScriptName = exports.customCodeScriptName = exports.verifyCustomCodeToken = exports.mintCustomCodeToken = void 0;
|
|
3
|
+
exports.customCodePreviewUploadName = exports.customCodeUploadName = exports.customCodePreviewScriptName = exports.customCodeScriptName = exports.verifyCustomCodeToken = exports.mintCustomCodeToken = void 0;
|
|
4
4
|
const base64_1 = require("./base64");
|
|
5
5
|
const constants_1 = require("./constants");
|
|
6
6
|
const encoder = new TextEncoder();
|
|
@@ -97,19 +97,90 @@ const verifyCustomCodeToken = async (token, secret, now) => {
|
|
|
97
97
|
};
|
|
98
98
|
exports.verifyCustomCodeToken = verifyCustomCodeToken;
|
|
99
99
|
/**
|
|
100
|
-
* The dispatch-namespace script name for an artifact: `artifact_<id>`.
|
|
100
|
+
* The legacy dispatch-namespace script name for an artifact: `artifact_<id>`.
|
|
101
101
|
*
|
|
102
102
|
* The id, never the slug — slugs are user-editable and a rename would orphan the
|
|
103
103
|
* deployed script while the database still pointed at a live version.
|
|
104
|
+
*
|
|
105
|
+
* Nothing uploads to this name any more; every deploy mints its own. It survives
|
|
106
|
+
* as the fallback for a version published before `script_name` existed, whose
|
|
107
|
+
* bundle really is sitting under this name. Tightening a rule must never stop an
|
|
108
|
+
* already-published version from serving, because that failure is invisible to
|
|
109
|
+
* whoever owns it — the same reason the boot loop still accepts a stored tool key
|
|
110
|
+
* the current catalog no longer offers.
|
|
104
111
|
*/
|
|
105
112
|
const customCodeScriptName = (artifactId) => `${constants_1.constants.CUSTOM_CODE_SCRIPT_NAME_PREFIX}${artifactId}`;
|
|
106
113
|
exports.customCodeScriptName = customCodeScriptName;
|
|
107
114
|
/**
|
|
108
|
-
* The script name
|
|
115
|
+
* The legacy preview script name: `artifact_<id>_preview`.
|
|
109
116
|
*
|
|
110
|
-
*
|
|
111
|
-
*
|
|
112
|
-
*
|
|
117
|
+
* Kept for the same reason as the one above, and for one more: it is the prefix
|
|
118
|
+
* the sweep matches to recognise a preview script left behind by a test run that
|
|
119
|
+
* did not clean up after itself.
|
|
113
120
|
*/
|
|
114
121
|
const customCodePreviewScriptName = (artifactId) => `${(0, exports.customCodeScriptName)(artifactId)}${constants_1.constants.CUSTOM_CODE_PREVIEW_SCRIPT_SUFFIX}`;
|
|
115
122
|
exports.customCodePreviewScriptName = customCodePreviewScriptName;
|
|
123
|
+
/**
|
|
124
|
+
* A dispatch-namespace name no upload has ever used:
|
|
125
|
+
* `artifact_<id>_<12 hex chars>`.
|
|
126
|
+
*
|
|
127
|
+
* Minted rather than derived, and that is the entire design. Uploading over an
|
|
128
|
+
* existing name is not read-your-writes — a replacement can serve the previous
|
|
129
|
+
* edition for tens of seconds — so a deploy that always writes to a new name is
|
|
130
|
+
* correct by construction rather than by waiting to see whether it worked.
|
|
131
|
+
*
|
|
132
|
+
* The suffix deliberately carries no meaning. The two candidates that did are
|
|
133
|
+
* both wrong: the bundle digest collides whenever a deploy reverts to bytes that
|
|
134
|
+
* shipped before, which is exactly what a rollback is, and the version id is one
|
|
135
|
+
* string across every re-upload of a single draft, which is every test run of it.
|
|
136
|
+
*
|
|
137
|
+
* Twelve hex characters is what fits. Worker names cap at 63 and
|
|
138
|
+
* `artifact_<uuid>` spends 45 of them.
|
|
139
|
+
*/
|
|
140
|
+
const customCodeUploadName = (artifactId) => mintUploadName((0, exports.customCodeScriptName)(artifactId));
|
|
141
|
+
exports.customCodeUploadName = customCodeUploadName;
|
|
142
|
+
/**
|
|
143
|
+
* A preview name no test run has ever used:
|
|
144
|
+
* `artifact_<id>_preview_<12 hex chars>`.
|
|
145
|
+
*
|
|
146
|
+
* The sharper version of the same race. Every test used to deploy over one
|
|
147
|
+
* preview name, so a test could report the run before it — which reads as "my
|
|
148
|
+
* edit did nothing" from the one tool whose whole job is to say what an edit
|
|
149
|
+
* does. Nothing stores this: it is minted, used, and deleted inside one request.
|
|
150
|
+
*/
|
|
151
|
+
const customCodePreviewUploadName = (artifactId) => mintUploadName((0, exports.customCodePreviewScriptName)(artifactId));
|
|
152
|
+
exports.customCodePreviewUploadName = customCodePreviewUploadName;
|
|
153
|
+
/**
|
|
154
|
+
* Append `_<hex>` to a base name, spending whatever the 63-character ceiling
|
|
155
|
+
* leaves and no more.
|
|
156
|
+
*
|
|
157
|
+
* The budget is genuinely tight, and the two names spend it differently:
|
|
158
|
+
*
|
|
159
|
+
* | name | base | separator | suffix | total |
|
|
160
|
+
* |---|---|---|---|---|
|
|
161
|
+
* | live | `artifact_<uuid>` = 45 | 1 | 12 | 58 |
|
|
162
|
+
* | preview | + `_preview` = 53 | 1 | 8 | 62 |
|
|
163
|
+
*
|
|
164
|
+
* Twelve hex characters is 48 bits and eight is 32, against a namespace holding
|
|
165
|
+
* a few hundred names for any one artifact — and a preview name lives for the
|
|
166
|
+
* seconds one test run takes. Neither is a collision worth checking for, and an
|
|
167
|
+
* upload to a name already in use fails loudly rather than quietly serving the
|
|
168
|
+
* wrong code, which is the failure that matters.
|
|
169
|
+
*
|
|
170
|
+
* The ceiling is asserted rather than assumed: it is one number away from being
|
|
171
|
+
* silently exceeded by a longer prefix, and a name Cloudflare refuses would
|
|
172
|
+
* surface as a failed publish with nothing explaining why.
|
|
173
|
+
*/
|
|
174
|
+
const mintUploadName = (base) => {
|
|
175
|
+
const available = constants_1.constants.CUSTOM_CODE_SCRIPT_NAME_MAX - base.length - 1;
|
|
176
|
+
// Even, because each byte renders as two hex characters.
|
|
177
|
+
const chars = Math.min(constants_1.constants.CUSTOM_CODE_UPLOAD_SUFFIX_CHARS, available) & ~1;
|
|
178
|
+
if (chars < 4) {
|
|
179
|
+
throw new Error(`A dispatch script name based on "${base}" leaves no room for a unique suffix.`);
|
|
180
|
+
}
|
|
181
|
+
const bytes = new Uint8Array(chars / 2);
|
|
182
|
+
crypto.getRandomValues(bytes);
|
|
183
|
+
return `${base}_${Array.from(bytes)
|
|
184
|
+
.map(byte => byte.toString(16).padStart(2, '0'))
|
|
185
|
+
.join('')}`;
|
|
186
|
+
};
|
package/dist/index.d.ts
CHANGED
|
@@ -2206,6 +2206,10 @@ export declare const utils: {
|
|
|
2206
2206
|
CUSTOM_CODE_MAX_FILE_PATH: number;
|
|
2207
2207
|
CUSTOM_CODE_VERSION_STATUSES: ("draft" | "published" | "archived")[];
|
|
2208
2208
|
CUSTOM_CODE_SCRIPT_NAME_PREFIX: string;
|
|
2209
|
+
CUSTOM_CODE_SCRIPT_NAME_MAX: number;
|
|
2210
|
+
CUSTOM_CODE_UPLOAD_SUFFIX_CHARS: number;
|
|
2211
|
+
CUSTOM_CODE_SWEEP_GRACE_MS: number;
|
|
2212
|
+
CUSTOM_CODE_SWEEP_MAX_DELETES: number;
|
|
2209
2213
|
CUSTOM_CODE_PREVIEW_SCRIPT_SUFFIX: string;
|
|
2210
2214
|
CUSTOM_CODE_PREVIEW_TOKEN_TTL_MS: number;
|
|
2211
2215
|
CUSTOM_CODE_TEST_TIMEOUT_MS: number;
|
|
@@ -2247,8 +2251,8 @@ export declare const utils: {
|
|
|
2247
2251
|
CUSTOM_CODE_BROKER_SERVICE_ENV: string;
|
|
2248
2252
|
CUSTOM_CODE_COMPATIBILITY_DATE: string;
|
|
2249
2253
|
CUSTOM_CODE_SCRIPT_CPU_MS: number;
|
|
2250
|
-
|
|
2251
|
-
|
|
2254
|
+
CUSTOM_CODE_REGISTER_TIMEOUT_MS: number;
|
|
2255
|
+
CUSTOM_CODE_REGISTER_INTERVAL_MS: number;
|
|
2252
2256
|
CUSTOM_CODE_MAX_LOGS: number;
|
|
2253
2257
|
CUSTOM_CODE_MAX_LOG_LENGTH: number;
|
|
2254
2258
|
CUSTOM_CODE_SEND_FILE_TARGET_GMAIL: "gmail";
|
|
@@ -2353,6 +2357,8 @@ export declare const utils: {
|
|
|
2353
2357
|
verifyCustomCodeToken: (token: string, secret: string, now?: number) => Promise<CustomCodeTokenPayload | null>;
|
|
2354
2358
|
customCodeScriptName: (artifactId: string) => string;
|
|
2355
2359
|
customCodePreviewScriptName: (artifactId: string) => string;
|
|
2360
|
+
customCodeUploadName: (artifactId: string) => string;
|
|
2361
|
+
customCodePreviewUploadName: (artifactId: string) => string;
|
|
2356
2362
|
oauthProviders: Record<string, OAuthProviderConfig>;
|
|
2357
2363
|
resolveAttachment: (resource: AttachmentResource, readObject: (key: string) => Promise<ArrayBuffer | null>, verb?: "attach" | "upload") => Promise<ResolveAttachmentResult>;
|
|
2358
2364
|
isExposedResource: (resource: ExposableResource) => boolean;
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EACV,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACzB,MAAM,UAAU,CAAC;AAElB,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,UAAU,CAAC;AAC1C,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,aAAa,CAAC;AAyCvD,OAAO,KAAK,EAAE,cAAc,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AACtE,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EAClB,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,iCAAiC,EAClC,MAAM,gBAAgB,CAAC;AACxB,OAAO,KAAK,EACV,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACpB,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,8BAA8B,EAC/B,MAAM,aAAa,CAAC;AACrB,OAAO,KAAK,EACV,kBAAkB,EAClB,mBAAmB,EACnB,gCAAgC,EACjC,MAAM,eAAe,CAAC;AACvB,OAAO,KAAK,EACV,mBAAmB,EACnB,oBAAoB,EACpB,iCAAiC,EAClC,MAAM,gBAAgB,CAAC;AAKxB,OAAO,EACL,UAAU,EAGX,MAAM,wBAAwB,CAAC;AAChC,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;aArGf,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;kBAhHiB,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;mBA0DF,CAAC;oBAEd,CAAC;;;;aA0BkB,CAAC;mBAA8B,CAAC;WACvC,CAAC;gBACf,CAAC;gBAA4B,CAAA;;;mBAoBK,CAAC;oBACjC,CAAC;;;;;;;;;;;;;;;kBA3Dc,CAAC;;;;;;;sBAqCR,CAAC;;;;;;;;;CA2Of,CAAC;AAEF,YAAY,EACV,iBAAiB,EACjB,gBAAgB,EAChB,YAAY,EACZ,WAAW,EACX,qBAAqB,EACrB,YAAY,EACZ,OAAO,EACP,mBAAmB,EACnB,UAAU,EACV,eAAe,EACf,cAAc,EACd,gBAAgB,EAChB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,gBAAgB,EAChB,kBAAkB,EAClB,mBAAmB,EACnB,cAAc,EACd,gBAAgB,EAChB,iBAAiB,EACjB,8BAA8B,EAC9B,mBAAmB,EACnB,oBAAoB,EACpB,iCAAiC,EACjC,kBAAkB,EAClB,mBAAmB,EACnB,gCAAgC,EAChC,mBAAmB,EACnB,oBAAoB,EACpB,iCAAiC,EACjC,SAAS,EACT,SAAS,EACT,aAAa,EACb,aAAa,EACb,iBAAiB,EACjB,yBAAyB,EACzB,uBAAuB,EACvB,qBAAqB,EACrB,cAAc,EACd,gBAAgB,EAChB,yBAAyB,EACzB,eAAe,EACf,eAAe,EACf,sBAAsB,EACtB,qBAAqB,EACrB,kBAAkB,EAClB,MAAM,EACN,kBAAkB,EAClB,YAAY,EACZ,sBAAsB,EACtB,mBAAmB,EACnB,sBAAsB,EACtB,kBAAkB,EAClB,sBAAsB,EACtB,0BAA0B,EAC1B,wBAAwB,EACxB,iBAAiB,EACjB,oBAAoB,EACpB,sBAAsB,EACtB,kBAAkB,EAClB,kBAAkB,EAClB,wBAAwB,EACxB,sBAAsB,EACtB,mBAAmB,EACnB,kBAAkB,EAClB,kBAAkB,EAClB,uBAAuB,EACvB,iBAAiB,EACjB,gBAAgB,EAChB,UAAU,EACX,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -89,6 +89,8 @@ exports.utils = {
|
|
|
89
89
|
verifyCustomCodeToken: customCodeToken_1.verifyCustomCodeToken,
|
|
90
90
|
customCodeScriptName: customCodeToken_1.customCodeScriptName,
|
|
91
91
|
customCodePreviewScriptName: customCodeToken_1.customCodePreviewScriptName,
|
|
92
|
+
customCodeUploadName: customCodeToken_1.customCodeUploadName,
|
|
93
|
+
customCodePreviewUploadName: customCodeToken_1.customCodePreviewUploadName,
|
|
92
94
|
oauthProviders: oauthProviders_1.oauthProviders,
|
|
93
95
|
resolveAttachment: attachment_1.resolveAttachment,
|
|
94
96
|
isExposedResource: exposedResource_1.isExposedResource,
|
package/package.json
CHANGED
package/src/constants.ts
CHANGED
|
@@ -1239,10 +1239,40 @@ const CUSTOM_CODE_MAIN_MODULE = 'index.js';
|
|
|
1239
1239
|
const CUSTOM_CODE_MAX_FILES = 25;
|
|
1240
1240
|
const CUSTOM_CODE_MAX_FILE_PATH = 100;
|
|
1241
1241
|
|
|
1242
|
-
// WfP script name: `artifact_<artifactId>`. The id, never the slug —
|
|
1243
|
-
// user-editable and a rename would orphan the deployed script.
|
|
1242
|
+
// WfP script name: `artifact_<artifactId>_<upload>`. The id, never the slug —
|
|
1243
|
+
// slugs are user-editable and a rename would orphan the deployed script.
|
|
1244
|
+
//
|
|
1245
|
+
// The trailing segment is minted per upload rather than derived from anything,
|
|
1246
|
+
// which is the whole point: uploading over a name that already exists is not
|
|
1247
|
+
// read-your-writes, so a deploy that replaces a script can serve the previous
|
|
1248
|
+
// edition for up to half a minute. A name nothing has ever used cannot, and
|
|
1249
|
+
// costs nothing to mint. Everything a publish used to do to survive that race —
|
|
1250
|
+
// waiting on an edition marker, refusing with a 503, putting the previous bundle
|
|
1251
|
+
// back when validation failed — went with the reuse that caused it.
|
|
1244
1252
|
const CUSTOM_CODE_SCRIPT_NAME_PREFIX = 'artifact_';
|
|
1245
1253
|
|
|
1254
|
+
// Worker names cap at 63 characters, and `artifact_<uuid>` already spends 45.
|
|
1255
|
+
// That leaves 17 for a separator and a suffix, so a second uuid does not fit and
|
|
1256
|
+
// neither does a hex-32 digest. Twelve hex characters is 48 bits against a
|
|
1257
|
+
// namespace holding at most a few hundred names for any one artifact — not a
|
|
1258
|
+
// collision worth checking for, and an upload to a name in use would fail loudly
|
|
1259
|
+
// rather than quietly serve the wrong code.
|
|
1260
|
+
const CUSTOM_CODE_SCRIPT_NAME_MAX = 63;
|
|
1261
|
+
const CUSTOM_CODE_UPLOAD_SUFFIX_CHARS = 12;
|
|
1262
|
+
|
|
1263
|
+
// How long a superseded script stays in the namespace before the hourly sweep
|
|
1264
|
+
// may collect it.
|
|
1265
|
+
//
|
|
1266
|
+
// Deleting at publish time would race the thing it deletes: a tool call that
|
|
1267
|
+
// resolved the old pointer a moment earlier is still in flight, and the pointer
|
|
1268
|
+
// moving does not recall it. An hour is far longer than any call can take, and
|
|
1269
|
+
// the wait costs $0.02 per script per month against an allowance of 1,000.
|
|
1270
|
+
const CUSTOM_CODE_SWEEP_GRACE_MS = 60 * 60 * 1_000;
|
|
1271
|
+
|
|
1272
|
+
// Deletes per sweep. A backlog drains over several hourly runs rather than
|
|
1273
|
+
// making one run unbounded — the same shape the retention purge uses.
|
|
1274
|
+
const CUSTOM_CODE_SWEEP_MAX_DELETES = 200;
|
|
1275
|
+
|
|
1246
1276
|
// A second script per artifact, `artifact_<id>_preview`, that the Test panel
|
|
1247
1277
|
// deploys a draft into and calls.
|
|
1248
1278
|
//
|
|
@@ -1453,15 +1483,17 @@ const CUSTOM_CODE_COMPATIBILITY_DATE = '2025-11-17';
|
|
|
1453
1483
|
// tighter than our own workers' 30s — this is the technical cap that bounds
|
|
1454
1484
|
// what one adversarial call can cost us, so an infinite loop in a customer's
|
|
1455
1485
|
// tool is billed as five seconds rather than as whatever it wanted.
|
|
1456
|
-
// How long
|
|
1457
|
-
//
|
|
1486
|
+
// How long a deploy waits for a freshly minted script name to become
|
|
1487
|
+
// dispatchable, and how often it asks.
|
|
1458
1488
|
//
|
|
1459
|
-
//
|
|
1460
|
-
//
|
|
1461
|
-
//
|
|
1462
|
-
//
|
|
1463
|
-
|
|
1464
|
-
|
|
1489
|
+
// Every upload goes to a name that has never been used, which is
|
|
1490
|
+
// read-your-writes: ~2s end to end against the deployed namespace, against the
|
|
1491
|
+
// 20-41s a replacement could take. So this bounds how long a brand-new name
|
|
1492
|
+
// takes to register, never how long an old edition takes to stop answering —
|
|
1493
|
+
// there is no old edition. It is short for that reason, and a script that
|
|
1494
|
+
// answers with the wrong edition now fails outright instead of being waited on.
|
|
1495
|
+
const CUSTOM_CODE_REGISTER_TIMEOUT_MS = 8_000;
|
|
1496
|
+
const CUSTOM_CODE_REGISTER_INTERVAL_MS = 500;
|
|
1465
1497
|
|
|
1466
1498
|
const CUSTOM_CODE_SCRIPT_CPU_MS = 5_000;
|
|
1467
1499
|
|
|
@@ -2465,6 +2497,10 @@ export const constants = {
|
|
|
2465
2497
|
CUSTOM_CODE_MAX_FILE_PATH,
|
|
2466
2498
|
CUSTOM_CODE_VERSION_STATUSES,
|
|
2467
2499
|
CUSTOM_CODE_SCRIPT_NAME_PREFIX,
|
|
2500
|
+
CUSTOM_CODE_SCRIPT_NAME_MAX,
|
|
2501
|
+
CUSTOM_CODE_UPLOAD_SUFFIX_CHARS,
|
|
2502
|
+
CUSTOM_CODE_SWEEP_GRACE_MS,
|
|
2503
|
+
CUSTOM_CODE_SWEEP_MAX_DELETES,
|
|
2468
2504
|
CUSTOM_CODE_PREVIEW_SCRIPT_SUFFIX,
|
|
2469
2505
|
CUSTOM_CODE_PREVIEW_TOKEN_TTL_MS,
|
|
2470
2506
|
CUSTOM_CODE_TEST_TIMEOUT_MS,
|
|
@@ -2506,8 +2542,8 @@ export const constants = {
|
|
|
2506
2542
|
CUSTOM_CODE_BROKER_SERVICE_ENV,
|
|
2507
2543
|
CUSTOM_CODE_COMPATIBILITY_DATE,
|
|
2508
2544
|
CUSTOM_CODE_SCRIPT_CPU_MS,
|
|
2509
|
-
|
|
2510
|
-
|
|
2545
|
+
CUSTOM_CODE_REGISTER_TIMEOUT_MS,
|
|
2546
|
+
CUSTOM_CODE_REGISTER_INTERVAL_MS,
|
|
2511
2547
|
CUSTOM_CODE_MAX_LOGS,
|
|
2512
2548
|
CUSTOM_CODE_MAX_LOG_LENGTH,
|
|
2513
2549
|
CUSTOM_CODE_SEND_FILE_TARGET_GMAIL,
|
package/src/customCodeToken.ts
CHANGED
|
@@ -179,20 +179,100 @@ export const verifyCustomCodeToken = async (
|
|
|
179
179
|
};
|
|
180
180
|
|
|
181
181
|
/**
|
|
182
|
-
* The dispatch-namespace script name for an artifact: `artifact_<id>`.
|
|
182
|
+
* The legacy dispatch-namespace script name for an artifact: `artifact_<id>`.
|
|
183
183
|
*
|
|
184
184
|
* The id, never the slug — slugs are user-editable and a rename would orphan the
|
|
185
185
|
* deployed script while the database still pointed at a live version.
|
|
186
|
+
*
|
|
187
|
+
* Nothing uploads to this name any more; every deploy mints its own. It survives
|
|
188
|
+
* as the fallback for a version published before `script_name` existed, whose
|
|
189
|
+
* bundle really is sitting under this name. Tightening a rule must never stop an
|
|
190
|
+
* already-published version from serving, because that failure is invisible to
|
|
191
|
+
* whoever owns it — the same reason the boot loop still accepts a stored tool key
|
|
192
|
+
* the current catalog no longer offers.
|
|
186
193
|
*/
|
|
187
194
|
export const customCodeScriptName = (artifactId: string): string =>
|
|
188
195
|
`${constants.CUSTOM_CODE_SCRIPT_NAME_PREFIX}${artifactId}`;
|
|
189
196
|
|
|
190
197
|
/**
|
|
191
|
-
* The script name
|
|
198
|
+
* The legacy preview script name: `artifact_<id>_preview`.
|
|
192
199
|
*
|
|
193
|
-
*
|
|
194
|
-
*
|
|
195
|
-
*
|
|
200
|
+
* Kept for the same reason as the one above, and for one more: it is the prefix
|
|
201
|
+
* the sweep matches to recognise a preview script left behind by a test run that
|
|
202
|
+
* did not clean up after itself.
|
|
196
203
|
*/
|
|
197
204
|
export const customCodePreviewScriptName = (artifactId: string): string =>
|
|
198
205
|
`${customCodeScriptName(artifactId)}${constants.CUSTOM_CODE_PREVIEW_SCRIPT_SUFFIX}`;
|
|
206
|
+
|
|
207
|
+
/**
|
|
208
|
+
* A dispatch-namespace name no upload has ever used:
|
|
209
|
+
* `artifact_<id>_<12 hex chars>`.
|
|
210
|
+
*
|
|
211
|
+
* Minted rather than derived, and that is the entire design. Uploading over an
|
|
212
|
+
* existing name is not read-your-writes — a replacement can serve the previous
|
|
213
|
+
* edition for tens of seconds — so a deploy that always writes to a new name is
|
|
214
|
+
* correct by construction rather than by waiting to see whether it worked.
|
|
215
|
+
*
|
|
216
|
+
* The suffix deliberately carries no meaning. The two candidates that did are
|
|
217
|
+
* both wrong: the bundle digest collides whenever a deploy reverts to bytes that
|
|
218
|
+
* shipped before, which is exactly what a rollback is, and the version id is one
|
|
219
|
+
* string across every re-upload of a single draft, which is every test run of it.
|
|
220
|
+
*
|
|
221
|
+
* Twelve hex characters is what fits. Worker names cap at 63 and
|
|
222
|
+
* `artifact_<uuid>` spends 45 of them.
|
|
223
|
+
*/
|
|
224
|
+
export const customCodeUploadName = (artifactId: string): string =>
|
|
225
|
+
mintUploadName(customCodeScriptName(artifactId));
|
|
226
|
+
|
|
227
|
+
/**
|
|
228
|
+
* A preview name no test run has ever used:
|
|
229
|
+
* `artifact_<id>_preview_<12 hex chars>`.
|
|
230
|
+
*
|
|
231
|
+
* The sharper version of the same race. Every test used to deploy over one
|
|
232
|
+
* preview name, so a test could report the run before it — which reads as "my
|
|
233
|
+
* edit did nothing" from the one tool whose whole job is to say what an edit
|
|
234
|
+
* does. Nothing stores this: it is minted, used, and deleted inside one request.
|
|
235
|
+
*/
|
|
236
|
+
export const customCodePreviewUploadName = (artifactId: string): string =>
|
|
237
|
+
mintUploadName(customCodePreviewScriptName(artifactId));
|
|
238
|
+
|
|
239
|
+
/**
|
|
240
|
+
* Append `_<hex>` to a base name, spending whatever the 63-character ceiling
|
|
241
|
+
* leaves and no more.
|
|
242
|
+
*
|
|
243
|
+
* The budget is genuinely tight, and the two names spend it differently:
|
|
244
|
+
*
|
|
245
|
+
* | name | base | separator | suffix | total |
|
|
246
|
+
* |---|---|---|---|---|
|
|
247
|
+
* | live | `artifact_<uuid>` = 45 | 1 | 12 | 58 |
|
|
248
|
+
* | preview | + `_preview` = 53 | 1 | 8 | 62 |
|
|
249
|
+
*
|
|
250
|
+
* Twelve hex characters is 48 bits and eight is 32, against a namespace holding
|
|
251
|
+
* a few hundred names for any one artifact — and a preview name lives for the
|
|
252
|
+
* seconds one test run takes. Neither is a collision worth checking for, and an
|
|
253
|
+
* upload to a name already in use fails loudly rather than quietly serving the
|
|
254
|
+
* wrong code, which is the failure that matters.
|
|
255
|
+
*
|
|
256
|
+
* The ceiling is asserted rather than assumed: it is one number away from being
|
|
257
|
+
* silently exceeded by a longer prefix, and a name Cloudflare refuses would
|
|
258
|
+
* surface as a failed publish with nothing explaining why.
|
|
259
|
+
*/
|
|
260
|
+
const mintUploadName = (base: string): string => {
|
|
261
|
+
const available = constants.CUSTOM_CODE_SCRIPT_NAME_MAX - base.length - 1;
|
|
262
|
+
// Even, because each byte renders as two hex characters.
|
|
263
|
+
const chars =
|
|
264
|
+
Math.min(constants.CUSTOM_CODE_UPLOAD_SUFFIX_CHARS, available) & ~1;
|
|
265
|
+
|
|
266
|
+
if (chars < 4) {
|
|
267
|
+
throw new Error(
|
|
268
|
+
`A dispatch script name based on "${base}" leaves no room for a unique suffix.`
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
|
|
272
|
+
const bytes = new Uint8Array(chars / 2);
|
|
273
|
+
crypto.getRandomValues(bytes);
|
|
274
|
+
|
|
275
|
+
return `${base}_${Array.from(bytes)
|
|
276
|
+
.map(byte => byte.toString(16).padStart(2, '0'))
|
|
277
|
+
.join('')}`;
|
|
278
|
+
};
|
package/src/index.ts
CHANGED
|
@@ -102,7 +102,9 @@ import {
|
|
|
102
102
|
mintCustomCodeToken,
|
|
103
103
|
verifyCustomCodeToken,
|
|
104
104
|
customCodeScriptName,
|
|
105
|
-
customCodePreviewScriptName
|
|
105
|
+
customCodePreviewScriptName,
|
|
106
|
+
customCodeUploadName,
|
|
107
|
+
customCodePreviewUploadName
|
|
106
108
|
} from './customCodeToken';
|
|
107
109
|
import type { CustomCodeTokenPayload } from './customCodeToken';
|
|
108
110
|
import { oauthProviders } from './oauthProviders';
|
|
@@ -257,6 +259,8 @@ export const utils = {
|
|
|
257
259
|
verifyCustomCodeToken,
|
|
258
260
|
customCodeScriptName,
|
|
259
261
|
customCodePreviewScriptName,
|
|
262
|
+
customCodeUploadName,
|
|
263
|
+
customCodePreviewUploadName,
|
|
260
264
|
oauthProviders,
|
|
261
265
|
resolveAttachment,
|
|
262
266
|
isExposedResource,
|