@b9g/platform 0.1.3 → 0.1.5
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 +94 -28
- package/package.json +45 -87
- package/src/config.d.ts +105 -0
- package/src/config.js +463 -0
- package/src/cookie-store.d.ts +80 -0
- package/src/cookie-store.js +231 -0
- package/src/index.d.ts +189 -9
- package/src/index.js +242 -49
- package/src/runtime.d.ts +426 -0
- package/src/runtime.js +997 -0
- package/src/single-threaded.d.ts +57 -0
- package/src/single-threaded.js +107 -0
- package/src/worker-pool.d.ts +22 -32
- package/src/worker-pool.js +214 -100
- package/src/adapter-registry.d.ts +0 -53
- package/src/adapter-registry.js +0 -71
- package/src/base-platform.d.ts +0 -49
- package/src/base-platform.js +0 -114
- package/src/detection.d.ts +0 -36
- package/src/detection.js +0 -126
- package/src/directory-storage.d.ts +0 -41
- package/src/directory-storage.js +0 -53
- package/src/filesystem.d.ts +0 -16
- package/src/filesystem.js +0 -20
- package/src/registry.d.ts +0 -31
- package/src/registry.js +0 -74
- package/src/service-worker.d.ts +0 -175
- package/src/service-worker.js +0 -245
- package/src/types.d.ts +0 -246
- package/src/types.js +0 -36
- package/src/utils.d.ts +0 -33
- package/src/utils.js +0 -139
- package/src/worker-web.js +0 -119
package/src/config.js
ADDED
|
@@ -0,0 +1,463 @@
|
|
|
1
|
+
/// <reference types="./config.d.ts" />
|
|
2
|
+
// src/config.ts
|
|
3
|
+
import { readFileSync } from "fs";
|
|
4
|
+
import { resolve } from "path";
|
|
5
|
+
function getEnv() {
|
|
6
|
+
if (typeof import.meta !== "undefined" && import.meta.env) {
|
|
7
|
+
return import.meta.env;
|
|
8
|
+
}
|
|
9
|
+
if (typeof process !== "undefined" && process.env) {
|
|
10
|
+
return process.env;
|
|
11
|
+
}
|
|
12
|
+
return {};
|
|
13
|
+
}
|
|
14
|
+
var Tokenizer = class {
|
|
15
|
+
#input;
|
|
16
|
+
#pos;
|
|
17
|
+
constructor(input) {
|
|
18
|
+
this.#input = input;
|
|
19
|
+
this.#pos = 0;
|
|
20
|
+
}
|
|
21
|
+
#peek() {
|
|
22
|
+
return this.#input[this.#pos] || "";
|
|
23
|
+
}
|
|
24
|
+
#advance() {
|
|
25
|
+
return this.#input[this.#pos++] || "";
|
|
26
|
+
}
|
|
27
|
+
#skipWhitespace() {
|
|
28
|
+
while (/\s/.test(this.#peek())) {
|
|
29
|
+
this.#advance();
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
next() {
|
|
33
|
+
this.#skipWhitespace();
|
|
34
|
+
const start = this.#pos;
|
|
35
|
+
const ch = this.#peek();
|
|
36
|
+
if (!ch) {
|
|
37
|
+
return { type: "EOF" /* EOF */, value: null, start, end: start };
|
|
38
|
+
}
|
|
39
|
+
if (ch === '"') {
|
|
40
|
+
this.#advance();
|
|
41
|
+
let value = "";
|
|
42
|
+
while (this.#peek() && this.#peek() !== '"') {
|
|
43
|
+
if (this.#peek() === "\\") {
|
|
44
|
+
this.#advance();
|
|
45
|
+
const next = this.#advance();
|
|
46
|
+
if (next === "n")
|
|
47
|
+
value += "\n";
|
|
48
|
+
else if (next === "t")
|
|
49
|
+
value += " ";
|
|
50
|
+
else
|
|
51
|
+
value += next;
|
|
52
|
+
} else {
|
|
53
|
+
value += this.#advance();
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
if (this.#peek() !== '"') {
|
|
57
|
+
throw new Error(`Unterminated string at position ${start}`);
|
|
58
|
+
}
|
|
59
|
+
this.#advance();
|
|
60
|
+
return { type: "STRING" /* STRING */, value, start, end: this.#pos };
|
|
61
|
+
}
|
|
62
|
+
if (/\d/.test(ch)) {
|
|
63
|
+
let value = "";
|
|
64
|
+
while (/\d/.test(this.#peek())) {
|
|
65
|
+
value += this.#advance();
|
|
66
|
+
}
|
|
67
|
+
return {
|
|
68
|
+
type: "NUMBER" /* NUMBER */,
|
|
69
|
+
value: parseInt(value, 10),
|
|
70
|
+
start,
|
|
71
|
+
end: this.#pos
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
if (ch === "=" && this.#input[this.#pos + 1] === "=" && this.#input[this.#pos + 2] === "=") {
|
|
75
|
+
this.#pos += 3;
|
|
76
|
+
return { type: "===" /* EQ_STRICT */, value: "===", start, end: this.#pos };
|
|
77
|
+
}
|
|
78
|
+
if (ch === "!" && this.#input[this.#pos + 1] === "=" && this.#input[this.#pos + 2] === "=") {
|
|
79
|
+
this.#pos += 3;
|
|
80
|
+
return { type: "!==" /* NE_STRICT */, value: "!==", start, end: this.#pos };
|
|
81
|
+
}
|
|
82
|
+
if (ch === "=" && this.#input[this.#pos + 1] === "=") {
|
|
83
|
+
this.#pos += 2;
|
|
84
|
+
return { type: "==" /* EQ */, value: "==", start, end: this.#pos };
|
|
85
|
+
}
|
|
86
|
+
if (ch === "!" && this.#input[this.#pos + 1] === "=") {
|
|
87
|
+
this.#pos += 2;
|
|
88
|
+
return { type: "!=" /* NE */, value: "!=", start, end: this.#pos };
|
|
89
|
+
}
|
|
90
|
+
if (ch === "|" && this.#input[this.#pos + 1] === "|") {
|
|
91
|
+
this.#pos += 2;
|
|
92
|
+
return { type: "||" /* OR */, value: "||", start, end: this.#pos };
|
|
93
|
+
}
|
|
94
|
+
if (ch === "&" && this.#input[this.#pos + 1] === "&") {
|
|
95
|
+
this.#pos += 2;
|
|
96
|
+
return { type: "&&" /* AND */, value: "&&", start, end: this.#pos };
|
|
97
|
+
}
|
|
98
|
+
if (ch === "?") {
|
|
99
|
+
this.#advance();
|
|
100
|
+
return { type: "?" /* QUESTION */, value: "?", start, end: this.#pos };
|
|
101
|
+
}
|
|
102
|
+
if (ch === "!") {
|
|
103
|
+
this.#advance();
|
|
104
|
+
return { type: "!" /* NOT */, value: "!", start, end: this.#pos };
|
|
105
|
+
}
|
|
106
|
+
if (ch === "(") {
|
|
107
|
+
this.#advance();
|
|
108
|
+
return { type: "(" /* LPAREN */, value: "(", start, end: this.#pos };
|
|
109
|
+
}
|
|
110
|
+
if (ch === ")") {
|
|
111
|
+
this.#advance();
|
|
112
|
+
return { type: ")" /* RPAREN */, value: ")", start, end: this.#pos };
|
|
113
|
+
}
|
|
114
|
+
if (ch === ":") {
|
|
115
|
+
const next = this.#input[this.#pos + 1];
|
|
116
|
+
if (next !== "/" && !/\d/.test(next)) {
|
|
117
|
+
this.#advance();
|
|
118
|
+
return { type: ":" /* COLON */, value: ":", start, end: this.#pos };
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
if (/\S/.test(ch) && !/[?!()=|&]/.test(ch)) {
|
|
122
|
+
let value = "";
|
|
123
|
+
while (/\S/.test(this.#peek()) && !/[?!()=|&]/.test(this.#peek())) {
|
|
124
|
+
if (this.#peek() === ":") {
|
|
125
|
+
const next = this.#input[this.#pos + 1];
|
|
126
|
+
if (next !== "/" && !/\d/.test(next)) {
|
|
127
|
+
break;
|
|
128
|
+
}
|
|
129
|
+
}
|
|
130
|
+
value += this.#advance();
|
|
131
|
+
}
|
|
132
|
+
if (value === "true")
|
|
133
|
+
return { type: "TRUE" /* TRUE */, value: true, start, end: this.#pos };
|
|
134
|
+
if (value === "false")
|
|
135
|
+
return { type: "FALSE" /* FALSE */, value: false, start, end: this.#pos };
|
|
136
|
+
if (value === "null")
|
|
137
|
+
return { type: "NULL" /* NULL */, value: null, start, end: this.#pos };
|
|
138
|
+
if (value === "undefined")
|
|
139
|
+
return {
|
|
140
|
+
type: "UNDEFINED" /* UNDEFINED */,
|
|
141
|
+
value: void 0,
|
|
142
|
+
start,
|
|
143
|
+
end: this.#pos
|
|
144
|
+
};
|
|
145
|
+
return { type: "IDENTIFIER" /* IDENTIFIER */, value, start, end: this.#pos };
|
|
146
|
+
}
|
|
147
|
+
throw new Error(`Unexpected character '${ch}' at position ${start}`);
|
|
148
|
+
}
|
|
149
|
+
};
|
|
150
|
+
var Parser = class {
|
|
151
|
+
#tokens;
|
|
152
|
+
#pos;
|
|
153
|
+
#env;
|
|
154
|
+
#strict;
|
|
155
|
+
constructor(input, env, strict) {
|
|
156
|
+
const tokenizer = new Tokenizer(input);
|
|
157
|
+
this.#tokens = [];
|
|
158
|
+
let token;
|
|
159
|
+
do {
|
|
160
|
+
token = tokenizer.next();
|
|
161
|
+
this.#tokens.push(token);
|
|
162
|
+
} while (token.type !== "EOF" /* EOF */);
|
|
163
|
+
this.#pos = 0;
|
|
164
|
+
this.#env = env;
|
|
165
|
+
this.#strict = strict;
|
|
166
|
+
}
|
|
167
|
+
#peek() {
|
|
168
|
+
return this.#tokens[this.#pos];
|
|
169
|
+
}
|
|
170
|
+
#advance() {
|
|
171
|
+
return this.#tokens[this.#pos++];
|
|
172
|
+
}
|
|
173
|
+
#expect(type) {
|
|
174
|
+
const token = this.#peek();
|
|
175
|
+
if (token.type !== type) {
|
|
176
|
+
throw new Error(
|
|
177
|
+
`Expected ${type} but got ${token.type} at position ${token.start}`
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
return this.#advance();
|
|
181
|
+
}
|
|
182
|
+
parse() {
|
|
183
|
+
const result = this.#parseExpr();
|
|
184
|
+
this.#expect("EOF" /* EOF */);
|
|
185
|
+
return result;
|
|
186
|
+
}
|
|
187
|
+
// Expr := Ternary
|
|
188
|
+
#parseExpr() {
|
|
189
|
+
return this.#parseTernary();
|
|
190
|
+
}
|
|
191
|
+
// Ternary := LogicalOr ('?' Expr ':' Expr)?
|
|
192
|
+
#parseTernary() {
|
|
193
|
+
let left = this.#parseLogicalOr();
|
|
194
|
+
if (this.#peek().type === "?" /* QUESTION */) {
|
|
195
|
+
this.#advance();
|
|
196
|
+
const trueBranch = this.#parseExpr();
|
|
197
|
+
this.#expect(":" /* COLON */);
|
|
198
|
+
const falseBranch = this.#parseExpr();
|
|
199
|
+
return left ? trueBranch : falseBranch;
|
|
200
|
+
}
|
|
201
|
+
return left;
|
|
202
|
+
}
|
|
203
|
+
// LogicalOr := LogicalAnd ('||' LogicalAnd)*
|
|
204
|
+
#parseLogicalOr() {
|
|
205
|
+
let left = this.#parseLogicalAnd();
|
|
206
|
+
while (this.#peek().type === "||" /* OR */) {
|
|
207
|
+
this.#advance();
|
|
208
|
+
const right = this.#parseLogicalAnd();
|
|
209
|
+
left = left || right;
|
|
210
|
+
}
|
|
211
|
+
return left;
|
|
212
|
+
}
|
|
213
|
+
// LogicalAnd := Equality ('&&' Equality)*
|
|
214
|
+
#parseLogicalAnd() {
|
|
215
|
+
let left = this.#parseEquality();
|
|
216
|
+
while (this.#peek().type === "&&" /* AND */) {
|
|
217
|
+
this.#advance();
|
|
218
|
+
const right = this.#parseEquality();
|
|
219
|
+
left = left && right;
|
|
220
|
+
}
|
|
221
|
+
return left;
|
|
222
|
+
}
|
|
223
|
+
// Equality := Unary (('===' | '!==' | '==' | '!=') Unary)*
|
|
224
|
+
#parseEquality() {
|
|
225
|
+
let left = this.#parseUnary();
|
|
226
|
+
while (true) {
|
|
227
|
+
const token = this.#peek();
|
|
228
|
+
if (token.type === "===" /* EQ_STRICT */) {
|
|
229
|
+
this.#advance();
|
|
230
|
+
const right = this.#parseUnary();
|
|
231
|
+
left = left === right;
|
|
232
|
+
} else if (token.type === "!==" /* NE_STRICT */) {
|
|
233
|
+
this.#advance();
|
|
234
|
+
const right = this.#parseUnary();
|
|
235
|
+
left = left !== right;
|
|
236
|
+
} else if (token.type === "==" /* EQ */) {
|
|
237
|
+
this.#advance();
|
|
238
|
+
const right = this.#parseUnary();
|
|
239
|
+
left = left == right;
|
|
240
|
+
} else if (token.type === "!=" /* NE */) {
|
|
241
|
+
this.#advance();
|
|
242
|
+
const right = this.#parseUnary();
|
|
243
|
+
left = left != right;
|
|
244
|
+
} else {
|
|
245
|
+
break;
|
|
246
|
+
}
|
|
247
|
+
}
|
|
248
|
+
return left;
|
|
249
|
+
}
|
|
250
|
+
// Unary := '!' Unary | Primary
|
|
251
|
+
#parseUnary() {
|
|
252
|
+
if (this.#peek().type === "!" /* NOT */) {
|
|
253
|
+
this.#advance();
|
|
254
|
+
return !this.#parseUnary();
|
|
255
|
+
}
|
|
256
|
+
return this.#parsePrimary();
|
|
257
|
+
}
|
|
258
|
+
// Primary := EnvVar | Literal | '(' Expr ')'
|
|
259
|
+
#parsePrimary() {
|
|
260
|
+
const token = this.#peek();
|
|
261
|
+
if (token.type === "(" /* LPAREN */) {
|
|
262
|
+
this.#advance();
|
|
263
|
+
const value = this.#parseExpr();
|
|
264
|
+
this.#expect(")" /* RPAREN */);
|
|
265
|
+
return value;
|
|
266
|
+
}
|
|
267
|
+
if (token.type === "STRING" /* STRING */) {
|
|
268
|
+
this.#advance();
|
|
269
|
+
return token.value;
|
|
270
|
+
}
|
|
271
|
+
if (token.type === "NUMBER" /* NUMBER */) {
|
|
272
|
+
this.#advance();
|
|
273
|
+
return token.value;
|
|
274
|
+
}
|
|
275
|
+
if (token.type === "TRUE" /* TRUE */) {
|
|
276
|
+
this.#advance();
|
|
277
|
+
return true;
|
|
278
|
+
}
|
|
279
|
+
if (token.type === "FALSE" /* FALSE */) {
|
|
280
|
+
this.#advance();
|
|
281
|
+
return false;
|
|
282
|
+
}
|
|
283
|
+
if (token.type === "NULL" /* NULL */) {
|
|
284
|
+
this.#advance();
|
|
285
|
+
return null;
|
|
286
|
+
}
|
|
287
|
+
if (token.type === "UNDEFINED" /* UNDEFINED */) {
|
|
288
|
+
this.#advance();
|
|
289
|
+
return void 0;
|
|
290
|
+
}
|
|
291
|
+
if (token.type === "IDENTIFIER" /* IDENTIFIER */) {
|
|
292
|
+
this.#advance();
|
|
293
|
+
const name = token.value;
|
|
294
|
+
if (/^[A-Z][A-Z0-9_]*$/.test(name)) {
|
|
295
|
+
const value = this.#env[name];
|
|
296
|
+
if (this.#strict && value === void 0) {
|
|
297
|
+
throw new Error(
|
|
298
|
+
`Undefined environment variable: ${name}
|
|
299
|
+
Fix:
|
|
300
|
+
1. Set the env var: export ${name}=value
|
|
301
|
+
2. Add a fallback: ${name} || defaultValue
|
|
302
|
+
3. Add null check: ${name} == null ? ... : ...
|
|
303
|
+
4. Use empty string for falsy: export ${name}=""`
|
|
304
|
+
);
|
|
305
|
+
}
|
|
306
|
+
if (typeof value === "string" && /^\d+$/.test(value)) {
|
|
307
|
+
return parseInt(value, 10);
|
|
308
|
+
}
|
|
309
|
+
return value;
|
|
310
|
+
}
|
|
311
|
+
return name;
|
|
312
|
+
}
|
|
313
|
+
throw new Error(
|
|
314
|
+
`Unexpected token ${token.type} at position ${token.start}`
|
|
315
|
+
);
|
|
316
|
+
}
|
|
317
|
+
};
|
|
318
|
+
function parseConfigExpr(expr, env = getEnv(), options = {}) {
|
|
319
|
+
const strict = options.strict !== false;
|
|
320
|
+
try {
|
|
321
|
+
const parser = new Parser(expr, env, strict);
|
|
322
|
+
return parser.parse();
|
|
323
|
+
} catch (error) {
|
|
324
|
+
throw new Error(
|
|
325
|
+
`Invalid config expression: ${expr}
|
|
326
|
+
Error: ${error instanceof Error ? error.message : String(error)}`
|
|
327
|
+
);
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
function processConfigValue(value, env = getEnv(), options = {}) {
|
|
331
|
+
if (typeof value === "string") {
|
|
332
|
+
if (/(\|\||&&|===|!==|==|!=|[?:!]|^[A-Z][A-Z0-9_]*$)/.test(value)) {
|
|
333
|
+
return parseConfigExpr(value, env, options);
|
|
334
|
+
}
|
|
335
|
+
return value;
|
|
336
|
+
}
|
|
337
|
+
if (Array.isArray(value)) {
|
|
338
|
+
return value.map((item) => processConfigValue(item, env, options));
|
|
339
|
+
}
|
|
340
|
+
if (value !== null && typeof value === "object") {
|
|
341
|
+
const processed = {};
|
|
342
|
+
for (const [key, val] of Object.entries(value)) {
|
|
343
|
+
processed[key] = processConfigValue(val, env, options);
|
|
344
|
+
}
|
|
345
|
+
return processed;
|
|
346
|
+
}
|
|
347
|
+
return value;
|
|
348
|
+
}
|
|
349
|
+
function matchPattern(name, config) {
|
|
350
|
+
if (config[name]) {
|
|
351
|
+
return config[name];
|
|
352
|
+
}
|
|
353
|
+
const patterns = [];
|
|
354
|
+
for (const [pattern, cfg] of Object.entries(config)) {
|
|
355
|
+
if (pattern === "*")
|
|
356
|
+
continue;
|
|
357
|
+
if (pattern.endsWith("*")) {
|
|
358
|
+
const prefix = pattern.slice(0, -1);
|
|
359
|
+
if (name.startsWith(prefix)) {
|
|
360
|
+
patterns.push({
|
|
361
|
+
pattern,
|
|
362
|
+
config: cfg,
|
|
363
|
+
prefixLength: prefix.length
|
|
364
|
+
});
|
|
365
|
+
}
|
|
366
|
+
}
|
|
367
|
+
}
|
|
368
|
+
if (patterns.length > 0) {
|
|
369
|
+
patterns.sort((a, b) => b.prefixLength - a.prefixLength);
|
|
370
|
+
return patterns[0].config;
|
|
371
|
+
}
|
|
372
|
+
return config["*"];
|
|
373
|
+
}
|
|
374
|
+
function loadConfig(cwd) {
|
|
375
|
+
const env = getEnv();
|
|
376
|
+
let rawConfig = {};
|
|
377
|
+
try {
|
|
378
|
+
const shovelPath = `${cwd}/shovel.json`;
|
|
379
|
+
const content = readFileSync(shovelPath, "utf-8");
|
|
380
|
+
rawConfig = JSON.parse(content);
|
|
381
|
+
} catch (error) {
|
|
382
|
+
try {
|
|
383
|
+
const pkgPath = `${cwd}/package.json`;
|
|
384
|
+
const content = readFileSync(pkgPath, "utf-8");
|
|
385
|
+
const pkgJSON = JSON.parse(content);
|
|
386
|
+
rawConfig = pkgJSON.shovel || {};
|
|
387
|
+
} catch (error2) {
|
|
388
|
+
}
|
|
389
|
+
}
|
|
390
|
+
const processed = processConfigValue(rawConfig, env, {
|
|
391
|
+
strict: true
|
|
392
|
+
});
|
|
393
|
+
const config = {
|
|
394
|
+
port: typeof processed.port === "number" ? processed.port : 3e3,
|
|
395
|
+
host: processed.host || "localhost",
|
|
396
|
+
workers: typeof processed.workers === "number" ? processed.workers : 1,
|
|
397
|
+
caches: processed.caches || {},
|
|
398
|
+
buckets: processed.buckets || {}
|
|
399
|
+
};
|
|
400
|
+
return config;
|
|
401
|
+
}
|
|
402
|
+
function getCacheConfig(config, name) {
|
|
403
|
+
return matchPattern(name, config.caches) || {};
|
|
404
|
+
}
|
|
405
|
+
function getBucketConfig(config, name) {
|
|
406
|
+
return matchPattern(name, config.buckets) || {};
|
|
407
|
+
}
|
|
408
|
+
var WELL_KNOWN_BUCKET_PATHS = {
|
|
409
|
+
static: (baseDir) => resolve(baseDir, "../static"),
|
|
410
|
+
server: (baseDir) => baseDir
|
|
411
|
+
};
|
|
412
|
+
function createBucketFactory(options) {
|
|
413
|
+
const { baseDir, config } = options;
|
|
414
|
+
return async (name) => {
|
|
415
|
+
const bucketConfig = config ? getBucketConfig(config, name) : {};
|
|
416
|
+
let bucketPath;
|
|
417
|
+
if (bucketConfig.path) {
|
|
418
|
+
bucketPath = String(bucketConfig.path);
|
|
419
|
+
} else if (WELL_KNOWN_BUCKET_PATHS[name]) {
|
|
420
|
+
bucketPath = WELL_KNOWN_BUCKET_PATHS[name](baseDir);
|
|
421
|
+
} else {
|
|
422
|
+
bucketPath = resolve(baseDir, `../${name}`);
|
|
423
|
+
}
|
|
424
|
+
const provider = String(bucketConfig.provider || "node");
|
|
425
|
+
switch (provider) {
|
|
426
|
+
case "memory": {
|
|
427
|
+
const { MemoryBucket } = await import("@b9g/filesystem/memory.js");
|
|
428
|
+
return new MemoryBucket(name);
|
|
429
|
+
}
|
|
430
|
+
case "node":
|
|
431
|
+
default: {
|
|
432
|
+
const { NodeBucket } = await import("@b9g/filesystem/node.js");
|
|
433
|
+
return new NodeBucket(bucketPath);
|
|
434
|
+
}
|
|
435
|
+
}
|
|
436
|
+
};
|
|
437
|
+
}
|
|
438
|
+
function createCacheFactory(options = {}) {
|
|
439
|
+
const { config } = options;
|
|
440
|
+
return async (name) => {
|
|
441
|
+
const cacheConfig = config ? getCacheConfig(config, name) : {};
|
|
442
|
+
const provider = String(cacheConfig.provider || "memory");
|
|
443
|
+
switch (provider) {
|
|
444
|
+
case "memory":
|
|
445
|
+
default: {
|
|
446
|
+
const { MemoryCache } = await import("@b9g/cache/memory.js");
|
|
447
|
+
return new MemoryCache(name, {
|
|
448
|
+
maxEntries: typeof cacheConfig.maxEntries === "number" ? cacheConfig.maxEntries : 1e3
|
|
449
|
+
});
|
|
450
|
+
}
|
|
451
|
+
}
|
|
452
|
+
};
|
|
453
|
+
}
|
|
454
|
+
export {
|
|
455
|
+
createBucketFactory,
|
|
456
|
+
createCacheFactory,
|
|
457
|
+
getBucketConfig,
|
|
458
|
+
getCacheConfig,
|
|
459
|
+
loadConfig,
|
|
460
|
+
matchPattern,
|
|
461
|
+
parseConfigExpr,
|
|
462
|
+
processConfigValue
|
|
463
|
+
};
|
|
@@ -0,0 +1,80 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cookie Store API Implementation
|
|
3
|
+
* https://cookiestore.spec.whatwg.org/
|
|
4
|
+
*
|
|
5
|
+
* Provides asynchronous cookie management for ServiceWorker contexts
|
|
6
|
+
*/
|
|
7
|
+
declare global {
|
|
8
|
+
interface CookieListItem {
|
|
9
|
+
domain?: string;
|
|
10
|
+
path?: string;
|
|
11
|
+
expires?: number;
|
|
12
|
+
secure?: boolean;
|
|
13
|
+
sameSite?: CookieSameSite;
|
|
14
|
+
partitioned?: boolean;
|
|
15
|
+
}
|
|
16
|
+
}
|
|
17
|
+
export type CookieSameSite = globalThis.CookieSameSite;
|
|
18
|
+
export type CookieInit = globalThis.CookieInit;
|
|
19
|
+
export type CookieStoreGetOptions = globalThis.CookieStoreGetOptions;
|
|
20
|
+
export type CookieStoreDeleteOptions = globalThis.CookieStoreDeleteOptions;
|
|
21
|
+
export type CookieListItem = globalThis.CookieListItem;
|
|
22
|
+
export type CookieList = CookieListItem[];
|
|
23
|
+
/**
|
|
24
|
+
* Parse Cookie header value into key-value pairs
|
|
25
|
+
* Cookie: name=value; name2=value2
|
|
26
|
+
*/
|
|
27
|
+
export declare function parseCookieHeader(cookieHeader: string): Map<string, string>;
|
|
28
|
+
/**
|
|
29
|
+
* Serialize cookie into Set-Cookie header value
|
|
30
|
+
*/
|
|
31
|
+
export declare function serializeCookie(cookie: CookieInit): string;
|
|
32
|
+
/**
|
|
33
|
+
* Parse Set-Cookie header into CookieListItem
|
|
34
|
+
*/
|
|
35
|
+
export declare function parseSetCookieHeader(setCookieHeader: string): CookieListItem;
|
|
36
|
+
/**
|
|
37
|
+
* RequestCookieStore - Cookie Store implementation for ServiceWorker contexts
|
|
38
|
+
*
|
|
39
|
+
* This implementation:
|
|
40
|
+
* - Reads cookies from the incoming Request's Cookie header
|
|
41
|
+
* - Tracks changes (set/delete operations)
|
|
42
|
+
* - Exports changes as Set-Cookie headers for the Response
|
|
43
|
+
*
|
|
44
|
+
* It follows the Cookie Store API spec but is designed for server-side
|
|
45
|
+
* request handling rather than browser contexts.
|
|
46
|
+
*/
|
|
47
|
+
export declare class RequestCookieStore extends EventTarget {
|
|
48
|
+
#private;
|
|
49
|
+
onchange: ((this: RequestCookieStore, ev: Event) => any) | null;
|
|
50
|
+
constructor(request?: Request);
|
|
51
|
+
/**
|
|
52
|
+
* Get a single cookie by name
|
|
53
|
+
*/
|
|
54
|
+
get(nameOrOptions: string | CookieStoreGetOptions): Promise<CookieListItem | null>;
|
|
55
|
+
/**
|
|
56
|
+
* Get all cookies matching the filter
|
|
57
|
+
*/
|
|
58
|
+
getAll(nameOrOptions?: string | CookieStoreGetOptions): Promise<CookieList>;
|
|
59
|
+
/**
|
|
60
|
+
* Set a cookie
|
|
61
|
+
*/
|
|
62
|
+
set(nameOrOptions: string | CookieInit, value?: string): Promise<void>;
|
|
63
|
+
/**
|
|
64
|
+
* Delete a cookie
|
|
65
|
+
*/
|
|
66
|
+
delete(nameOrOptions: string | CookieStoreDeleteOptions): Promise<void>;
|
|
67
|
+
/**
|
|
68
|
+
* Get Set-Cookie headers for all changes
|
|
69
|
+
* This should be called when constructing the Response
|
|
70
|
+
*/
|
|
71
|
+
getSetCookieHeaders(): string[];
|
|
72
|
+
/**
|
|
73
|
+
* Check if there are any pending changes
|
|
74
|
+
*/
|
|
75
|
+
hasChanges(): boolean;
|
|
76
|
+
/**
|
|
77
|
+
* Clear all pending changes (for testing/reset)
|
|
78
|
+
*/
|
|
79
|
+
clearChanges(): void;
|
|
80
|
+
}
|