@bleedingdev/modern-js-app-tools-extensions 3.9.0-ultramodern.22 → 3.9.0-ultramodern.23
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 +23 -0
- package/dist/cjs/cloudflare/worker-manifest.js +8 -6
- package/dist/cjs/cloudflare/wrangler-config.js +175 -6
- package/dist/cjs/cloudflare-output-contract.js +2 -1
- package/dist/esm/cloudflare/worker-manifest.mjs +9 -7
- package/dist/esm/cloudflare/wrangler-config.mjs +168 -5
- package/dist/esm/cloudflare-output-contract.mjs +2 -1
- package/dist/esm-node/cloudflare/worker-manifest.mjs +9 -7
- package/dist/esm-node/cloudflare/wrangler-config.mjs +168 -5
- package/dist/esm-node/cloudflare-output-contract.mjs +2 -1
- package/dist/types/cloudflare/worker-manifest.d.ts +7 -2
- package/dist/types/cloudflare/wrangler-config.d.ts +52 -5
- package/dist/types/cloudflare-output-contract.d.ts +1 -1
- package/dist/types/config.d.ts +69 -12
- package/package.json +15 -15
- package/src/cloudflare/worker-manifest.ts +19 -6
- package/src/cloudflare/wrangler-config.ts +305 -5
- package/src/cloudflare-output-contract.ts +3 -0
- package/src/config.ts +71 -12
|
@@ -2,6 +2,7 @@ import path from 'node:path';
|
|
|
2
2
|
import type {
|
|
3
3
|
CloudflareWorkerD1DatabaseConfig,
|
|
4
4
|
CloudflareWorkerServiceBindingConfig,
|
|
5
|
+
CloudflareWorkerVpcServiceConfig,
|
|
5
6
|
JsonValue,
|
|
6
7
|
} from '../config';
|
|
7
8
|
import {
|
|
@@ -108,7 +109,9 @@ const createWranglerCompatibilityFlags = (
|
|
|
108
109
|
// `wrangler deploy --env <name>` uses an environment's own compatibility_date
|
|
109
110
|
// and compatibility_flags instead of the top-level values, so each override
|
|
110
111
|
// is held to the same verified date floor and required flags.
|
|
111
|
-
const createWranglerEnvironments = (
|
|
112
|
+
const createWranglerEnvironments = (
|
|
113
|
+
wranglerEnv: JsonValue | undefined,
|
|
114
|
+
): Record<string, Record<string, JsonValue>> | undefined => {
|
|
112
115
|
if (wranglerEnv === undefined) {
|
|
113
116
|
return undefined;
|
|
114
117
|
}
|
|
@@ -313,6 +316,232 @@ export const createWorkerServiceBindings = (
|
|
|
313
316
|
return services.map(normalizeServiceBinding);
|
|
314
317
|
};
|
|
315
318
|
|
|
319
|
+
const normalizeVpcService = (
|
|
320
|
+
vpcService: CloudflareWorkerVpcServiceConfig,
|
|
321
|
+
index: number,
|
|
322
|
+
) => {
|
|
323
|
+
const binding = assertNonEmptyString(
|
|
324
|
+
vpcService.binding,
|
|
325
|
+
`deploy.worker.vpcServices[${index}].binding`,
|
|
326
|
+
);
|
|
327
|
+
const serviceId = assertNonEmptyString(
|
|
328
|
+
vpcService.serviceId,
|
|
329
|
+
`deploy.worker.vpcServices[${index}].serviceId`,
|
|
330
|
+
);
|
|
331
|
+
const prefix =
|
|
332
|
+
vpcService.prefix === undefined
|
|
333
|
+
? undefined
|
|
334
|
+
: assertNonEmptyString(
|
|
335
|
+
vpcService.prefix,
|
|
336
|
+
`deploy.worker.vpcServices[${index}].prefix`,
|
|
337
|
+
);
|
|
338
|
+
|
|
339
|
+
return { binding, serviceId, ...(prefix === undefined ? {} : { prefix }) };
|
|
340
|
+
};
|
|
341
|
+
|
|
342
|
+
// The worker dispatcher percent-decodes a request path (up to four rounds, as
|
|
343
|
+
// `resolvePrefixPathname` does), matches a prefix on path-segment boundaries
|
|
344
|
+
// and takes the first matching binding, so overlapping prefixes, including
|
|
345
|
+
// encoded aliases of one another, route ambiguously.
|
|
346
|
+
const decodeRoutePrefix = (prefix: string) => {
|
|
347
|
+
let decoded = prefix;
|
|
348
|
+
for (let round = 0; round < 4; round += 1) {
|
|
349
|
+
let next: string;
|
|
350
|
+
try {
|
|
351
|
+
next = decodeURIComponent(decoded);
|
|
352
|
+
} catch {
|
|
353
|
+
return decoded;
|
|
354
|
+
}
|
|
355
|
+
if (next === decoded) {
|
|
356
|
+
return decoded;
|
|
357
|
+
}
|
|
358
|
+
decoded = next;
|
|
359
|
+
}
|
|
360
|
+
return decoded;
|
|
361
|
+
};
|
|
362
|
+
|
|
363
|
+
const normalizeRoutePrefix = (prefix: string) => {
|
|
364
|
+
const decoded = decodeRoutePrefix(prefix);
|
|
365
|
+
return decoded === '/' ? decoded : decoded.replace(/\/+$/u, '');
|
|
366
|
+
};
|
|
367
|
+
|
|
368
|
+
// The dispatcher matches `new URL(request.url).pathname`, so a prefix is
|
|
369
|
+
// routable only if URL parsing keeps it unchanged: no query or fragment, no
|
|
370
|
+
// `.`/`..` segments, nothing URL parsing would re-encode, and no percent-encoding
|
|
371
|
+
// (the dispatcher decodes request paths before matching).
|
|
372
|
+
const isCanonicalRoutePrefix = (prefix: string) =>
|
|
373
|
+
prefix.startsWith('/') &&
|
|
374
|
+
!prefix.includes('\\') &&
|
|
375
|
+
decodeRoutePrefix(prefix) === prefix &&
|
|
376
|
+
new URL(prefix, 'https://route.invalid').pathname === prefix;
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* Names the generated Worker may already expose on `env`, collected
|
|
380
|
+
* conservatively so no Wrangler binding shape is missed: every `binding` field
|
|
381
|
+
* at any depth (assets, D1, KV, Hyperdrive, queue producers, …), the `name` of
|
|
382
|
+
* every array entry (Durable Objects, `send_email`, `ratelimits`, `unsafe` and
|
|
383
|
+
* `logfwdr` bindings, …), and `vars` keys. A non-binding array `name` can only
|
|
384
|
+
* make a VPC name collide, never let a real collision through. Service and VPC
|
|
385
|
+
* bindings are checked separately; per-environment overrides live under `env`.
|
|
386
|
+
*/
|
|
387
|
+
const collectWorkerBindingNames = (config: Record<string, JsonValue>) => {
|
|
388
|
+
const names = new Set<string>();
|
|
389
|
+
const visit = (value: JsonValue, inArray: boolean) => {
|
|
390
|
+
if (Array.isArray(value)) {
|
|
391
|
+
for (const item of value) {
|
|
392
|
+
visit(item, true);
|
|
393
|
+
}
|
|
394
|
+
return;
|
|
395
|
+
}
|
|
396
|
+
if (!isJsonRecord(value)) {
|
|
397
|
+
return;
|
|
398
|
+
}
|
|
399
|
+
for (const field of inArray ? ['binding', 'name'] : ['binding']) {
|
|
400
|
+
const name = value[field];
|
|
401
|
+
if (typeof name === 'string') {
|
|
402
|
+
names.add(name.trim());
|
|
403
|
+
}
|
|
404
|
+
}
|
|
405
|
+
for (const child of Object.values(value)) {
|
|
406
|
+
visit(child, false);
|
|
407
|
+
}
|
|
408
|
+
};
|
|
409
|
+
for (const [key, value] of Object.entries(config)) {
|
|
410
|
+
if (key === 'env' || key === 'services' || key === 'vpc_services') {
|
|
411
|
+
continue;
|
|
412
|
+
}
|
|
413
|
+
if (key === 'vars' && isJsonRecord(value)) {
|
|
414
|
+
for (const name of Object.keys(value)) {
|
|
415
|
+
names.add(name);
|
|
416
|
+
}
|
|
417
|
+
continue;
|
|
418
|
+
}
|
|
419
|
+
visit(value, false);
|
|
420
|
+
}
|
|
421
|
+
return names;
|
|
422
|
+
};
|
|
423
|
+
|
|
424
|
+
const prefixesOverlap = (left: string, right: string) => {
|
|
425
|
+
const [first, second] = [
|
|
426
|
+
normalizeRoutePrefix(left),
|
|
427
|
+
normalizeRoutePrefix(right),
|
|
428
|
+
];
|
|
429
|
+
return (
|
|
430
|
+
first === '/' ||
|
|
431
|
+
second === '/' ||
|
|
432
|
+
first === second ||
|
|
433
|
+
first.startsWith(`${second}/`) ||
|
|
434
|
+
second.startsWith(`${first}/`)
|
|
435
|
+
);
|
|
436
|
+
};
|
|
437
|
+
|
|
438
|
+
/**
|
|
439
|
+
* The prefix the worker's Effect BFF dispatcher owns. It runs before any
|
|
440
|
+
* service binding, so it takes part in route-overlap checks.
|
|
441
|
+
*/
|
|
442
|
+
export const getWorkerEffectBffPrefix = (
|
|
443
|
+
modernConfig: CloudflareModernConfig,
|
|
444
|
+
) => {
|
|
445
|
+
const bffPrefix = modernConfig.bff?.prefix;
|
|
446
|
+
const primaryBffPrefix = Array.isArray(bffPrefix) ? bffPrefix[0] : bffPrefix;
|
|
447
|
+
const isEffectApi =
|
|
448
|
+
Boolean(modernConfig.bff) && modernConfig.bff?.runtimeFramework !== 'hono';
|
|
449
|
+
return isEffectApi && primaryBffPrefix ? primaryBffPrefix : undefined;
|
|
450
|
+
};
|
|
451
|
+
|
|
452
|
+
const effectiveServiceBindings = (
|
|
453
|
+
serviceBindings: ReturnType<typeof createWorkerServiceBindings>,
|
|
454
|
+
) => {
|
|
455
|
+
const bindings: unknown[] = Array.isArray(serviceBindings)
|
|
456
|
+
? serviceBindings
|
|
457
|
+
: [];
|
|
458
|
+
return bindings.flatMap(service =>
|
|
459
|
+
isJsonRecord(service) && typeof service.binding === 'string'
|
|
460
|
+
? [
|
|
461
|
+
{
|
|
462
|
+
binding: service.binding.trim(),
|
|
463
|
+
prefix:
|
|
464
|
+
typeof service.prefix === 'string' ? service.prefix : undefined,
|
|
465
|
+
},
|
|
466
|
+
]
|
|
467
|
+
: [],
|
|
468
|
+
);
|
|
469
|
+
};
|
|
470
|
+
|
|
471
|
+
export const createWorkerVpcServiceBindings = (
|
|
472
|
+
modernConfig: CloudflareModernConfig,
|
|
473
|
+
configuredWranglerVpcServices: JsonValue | undefined,
|
|
474
|
+
serviceBindings: ReturnType<typeof createWorkerServiceBindings>,
|
|
475
|
+
workerBindingNames: ReadonlySet<string>,
|
|
476
|
+
) => {
|
|
477
|
+
const vpcServices = modernConfig.deploy?.worker?.vpcServices;
|
|
478
|
+
|
|
479
|
+
if (vpcServices === undefined) {
|
|
480
|
+
return undefined;
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
if (configuredWranglerVpcServices !== undefined) {
|
|
484
|
+
throw new Error(
|
|
485
|
+
'Use deploy.worker.vpcServices or deploy.worker.wrangler.vpc_services, not both.',
|
|
486
|
+
);
|
|
487
|
+
}
|
|
488
|
+
|
|
489
|
+
if (!Array.isArray(vpcServices)) {
|
|
490
|
+
throw new Error('deploy.worker.vpcServices must be an array.');
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
const services = effectiveServiceBindings(serviceBindings);
|
|
494
|
+
const serviceBindingNames = new Set(services.map(({ binding }) => binding));
|
|
495
|
+
const effectBffPrefix = getWorkerEffectBffPrefix(modernConfig);
|
|
496
|
+
const routes = [
|
|
497
|
+
...(effectBffPrefix === undefined
|
|
498
|
+
? []
|
|
499
|
+
: [{ owner: 'the Effect BFF', prefix: effectBffPrefix }]),
|
|
500
|
+
...services.flatMap(({ binding, prefix }) =>
|
|
501
|
+
prefix === undefined ? [] : [{ owner: `binding "${binding}"`, prefix }],
|
|
502
|
+
),
|
|
503
|
+
];
|
|
504
|
+
const vpcBindingNames = new Set<string>();
|
|
505
|
+
|
|
506
|
+
return vpcServices.map((vpcService, index) => {
|
|
507
|
+
const normalized = normalizeVpcService(vpcService, index);
|
|
508
|
+
if (serviceBindingNames.has(normalized.binding)) {
|
|
509
|
+
throw new Error(
|
|
510
|
+
`deploy.worker.vpcServices[${index}].binding "${normalized.binding}" is already declared by deploy.worker.services.`,
|
|
511
|
+
);
|
|
512
|
+
}
|
|
513
|
+
if (workerBindingNames.has(normalized.binding)) {
|
|
514
|
+
throw new Error(
|
|
515
|
+
`deploy.worker.vpcServices[${index}].binding "${normalized.binding}" is already a binding of this Worker.`,
|
|
516
|
+
);
|
|
517
|
+
}
|
|
518
|
+
if (vpcBindingNames.has(normalized.binding)) {
|
|
519
|
+
throw new Error(
|
|
520
|
+
`deploy.worker.vpcServices[${index}].binding "${normalized.binding}" is declared more than once.`,
|
|
521
|
+
);
|
|
522
|
+
}
|
|
523
|
+
vpcBindingNames.add(normalized.binding);
|
|
524
|
+
if (normalized.prefix !== undefined) {
|
|
525
|
+
const { prefix } = normalized;
|
|
526
|
+
if (!isCanonicalRoutePrefix(prefix)) {
|
|
527
|
+
throw new Error(
|
|
528
|
+
`deploy.worker.vpcServices[${index}].prefix "${prefix}" must be a decoded URL path that starts with "/" (no query, fragment, "." or ".." segments).`,
|
|
529
|
+
);
|
|
530
|
+
}
|
|
531
|
+
const shadow = routes.find(route =>
|
|
532
|
+
prefixesOverlap(route.prefix, prefix),
|
|
533
|
+
);
|
|
534
|
+
if (shadow !== undefined) {
|
|
535
|
+
throw new Error(
|
|
536
|
+
`deploy.worker.vpcServices[${index}].prefix "${prefix}" overlaps the prefix "${shadow.prefix}" of ${shadow.owner}; the worker dispatcher would route one of them ambiguously.`,
|
|
537
|
+
);
|
|
538
|
+
}
|
|
539
|
+
routes.push({ owner: `binding "${normalized.binding}"`, prefix });
|
|
540
|
+
}
|
|
541
|
+
return normalized;
|
|
542
|
+
});
|
|
543
|
+
};
|
|
544
|
+
|
|
316
545
|
const createWranglerServices = (
|
|
317
546
|
serviceBindings: ReturnType<typeof createWorkerServiceBindings>,
|
|
318
547
|
) => {
|
|
@@ -338,9 +567,24 @@ const createWranglerServices = (
|
|
|
338
567
|
|
|
339
568
|
export const createWorkerManifestServiceBindings = (
|
|
340
569
|
serviceBindings: ReturnType<typeof createWorkerServiceBindings>,
|
|
570
|
+
vpcServiceBindings: ReturnType<typeof createWorkerVpcServiceBindings>,
|
|
341
571
|
) => {
|
|
572
|
+
const vpcManifestBindings = (vpcServiceBindings ?? []).flatMap(
|
|
573
|
+
({ binding, prefix, serviceId }) =>
|
|
574
|
+
prefix === undefined
|
|
575
|
+
? []
|
|
576
|
+
: [
|
|
577
|
+
{
|
|
578
|
+
binding,
|
|
579
|
+
interface: 'fetch',
|
|
580
|
+
prefix,
|
|
581
|
+
vpcServiceId: serviceId,
|
|
582
|
+
},
|
|
583
|
+
],
|
|
584
|
+
);
|
|
585
|
+
|
|
342
586
|
if (!Array.isArray(serviceBindings)) {
|
|
343
|
-
return undefined;
|
|
587
|
+
return vpcManifestBindings.length > 0 ? vpcManifestBindings : undefined;
|
|
344
588
|
}
|
|
345
589
|
|
|
346
590
|
const bindings: unknown[] = serviceBindings;
|
|
@@ -375,7 +619,9 @@ export const createWorkerManifestServiceBindings = (
|
|
|
375
619
|
: { fragments: service.fragments }),
|
|
376
620
|
}));
|
|
377
621
|
|
|
378
|
-
|
|
622
|
+
const allBindings = [...manifestBindings, ...vpcManifestBindings];
|
|
623
|
+
|
|
624
|
+
return allBindings.length > 0 ? allBindings : undefined;
|
|
379
625
|
};
|
|
380
626
|
|
|
381
627
|
export const createWranglerConfig = (
|
|
@@ -393,8 +639,7 @@ export const createWranglerConfig = (
|
|
|
393
639
|
wrangler.services,
|
|
394
640
|
);
|
|
395
641
|
const wranglerServices = createWranglerServices(serviceBindings);
|
|
396
|
-
|
|
397
|
-
return {
|
|
642
|
+
const workerConfig = {
|
|
398
643
|
$schema: 'node_modules/wrangler/config-schema.json',
|
|
399
644
|
name: getConfiguredWorkerName(appDirectory, modernConfig),
|
|
400
645
|
...wrangler,
|
|
@@ -411,4 +656,59 @@ export const createWranglerConfig = (
|
|
|
411
656
|
...(d1Databases === undefined ? {} : { d1_databases: d1Databases }),
|
|
412
657
|
...(wranglerServices === undefined ? {} : { services: wranglerServices }),
|
|
413
658
|
};
|
|
659
|
+
const vpcServiceBindings = createWorkerVpcServiceBindings(
|
|
660
|
+
modernConfig,
|
|
661
|
+
wrangler.vpc_services,
|
|
662
|
+
serviceBindings,
|
|
663
|
+
collectWorkerBindingNames(workerConfig),
|
|
664
|
+
);
|
|
665
|
+
|
|
666
|
+
if (vpcServiceBindings === undefined) {
|
|
667
|
+
return workerConfig;
|
|
668
|
+
}
|
|
669
|
+
const vpcServicesConfig = vpcServiceBindings.map(
|
|
670
|
+
({ binding, serviceId }) => ({
|
|
671
|
+
binding,
|
|
672
|
+
service_id: serviceId,
|
|
673
|
+
}),
|
|
674
|
+
);
|
|
675
|
+
|
|
676
|
+
return {
|
|
677
|
+
...workerConfig,
|
|
678
|
+
// Wrangler bindings are not inherited by named environments, so every
|
|
679
|
+
// configured environment receives the typed VPC bindings as well.
|
|
680
|
+
...(environments === undefined
|
|
681
|
+
? {}
|
|
682
|
+
: {
|
|
683
|
+
env: Object.fromEntries(
|
|
684
|
+
Object.entries(environments).map(([name, environment]) => {
|
|
685
|
+
if (environment.vpc_services !== undefined) {
|
|
686
|
+
throw new Error(
|
|
687
|
+
`Use deploy.worker.vpcServices or deploy.worker.wrangler.env.${name}.vpc_services, not both.`,
|
|
688
|
+
);
|
|
689
|
+
}
|
|
690
|
+
// A named environment declares its own (non-inherited) bindings.
|
|
691
|
+
const environmentBindingNames = new Set([
|
|
692
|
+
...collectWorkerBindingNames(environment),
|
|
693
|
+
...effectiveServiceBindings(environment.services).map(
|
|
694
|
+
({ binding }) => binding,
|
|
695
|
+
),
|
|
696
|
+
]);
|
|
697
|
+
const collision = vpcServiceBindings.find(({ binding }) =>
|
|
698
|
+
environmentBindingNames.has(binding),
|
|
699
|
+
);
|
|
700
|
+
if (collision !== undefined) {
|
|
701
|
+
throw new Error(
|
|
702
|
+
`deploy.worker.vpcServices binding "${collision.binding}" is already a binding of deploy.worker.wrangler.env.${name}.`,
|
|
703
|
+
);
|
|
704
|
+
}
|
|
705
|
+
return [
|
|
706
|
+
name,
|
|
707
|
+
{ ...environment, vpc_services: vpcServicesConfig },
|
|
708
|
+
];
|
|
709
|
+
}),
|
|
710
|
+
),
|
|
711
|
+
}),
|
|
712
|
+
vpc_services: vpcServicesConfig,
|
|
713
|
+
};
|
|
414
714
|
};
|
|
@@ -91,8 +91,11 @@ export const CLOUDFLARE_WORKER_NODE_BUILTINS = [
|
|
|
91
91
|
] as const;
|
|
92
92
|
// Platform imports available with the default 2026-06-02 nodejs_compat target.
|
|
93
93
|
// Import availability does not imply support for every Node API operation.
|
|
94
|
+
// `cloudflare:workers` exposes the Worker `env` at module scope, which is how
|
|
95
|
+
// clients built once per isolate reach Hyperdrive, VPC and service bindings.
|
|
94
96
|
export const CLOUDFLARE_WORKER_PLATFORM_MODULES = [
|
|
95
97
|
'cloudflare:sockets',
|
|
98
|
+
'cloudflare:workers',
|
|
96
99
|
] as const;
|
|
97
100
|
export const CLOUDFLARE_REQUIRED_COMPATIBILITY_FLAGS = [
|
|
98
101
|
'nodejs_compat',
|
package/src/config.ts
CHANGED
|
@@ -99,6 +99,19 @@ export interface CloudflareWorkerServiceBindingConfig {
|
|
|
99
99
|
fragments?: CloudflareWorkerServiceBindingFragmentConfig[];
|
|
100
100
|
}
|
|
101
101
|
|
|
102
|
+
export interface CloudflareWorkerVpcServiceConfig {
|
|
103
|
+
/** Worker binding name exposed on the module worker `env` object. */
|
|
104
|
+
binding: string;
|
|
105
|
+
/** Workers VPC service id (`wrangler vpc service create`). */
|
|
106
|
+
serviceId: string;
|
|
107
|
+
/**
|
|
108
|
+
* Optional application path prefix that Modern.js should dispatch to this
|
|
109
|
+
* private origin with `env[binding].fetch(request)`, exactly like a
|
|
110
|
+
* prefixed Worker service binding.
|
|
111
|
+
*/
|
|
112
|
+
prefix?: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
102
115
|
export interface CloudflareWorkerServiceBindingFragmentConfig {
|
|
103
116
|
/** Stable remote id used by the shell's composition contract. */
|
|
104
117
|
remote: string;
|
|
@@ -194,19 +207,65 @@ export interface CloudflareWorkerSecurityConfig {
|
|
|
194
207
|
reason?: string;
|
|
195
208
|
}
|
|
196
209
|
|
|
210
|
+
export interface CloudflareWorkerDeployConfig {
|
|
211
|
+
name?: string;
|
|
212
|
+
/**
|
|
213
|
+
* Cloudflare Workers compatibility date for generated wrangler config.
|
|
214
|
+
* Use YYYY-MM-DD. Defaults to the date validated against the bundled
|
|
215
|
+
* Wrangler version used by UltraModern generated workspaces.
|
|
216
|
+
*/
|
|
217
|
+
compatibilityDate?: string;
|
|
218
|
+
ssr?: boolean;
|
|
219
|
+
security?: CloudflareWorkerSecurityConfig;
|
|
220
|
+
/**
|
|
221
|
+
* Raw Wrangler-compatible config merged into `.output/wrangler.json`.
|
|
222
|
+
* Framework-owned worker invariants still win for `main`, the assets
|
|
223
|
+
* binding/directory/run mode, and required compatibility flags.
|
|
224
|
+
*/
|
|
225
|
+
wrangler?: Record<string, JsonValue>;
|
|
226
|
+
/**
|
|
227
|
+
* Additional app-root files or directories to stage under `.output`.
|
|
228
|
+
* Use this for provider resources such as migrations or generated config.
|
|
229
|
+
*/
|
|
230
|
+
artifacts?: CloudflareWorkerArtifactConfig[];
|
|
231
|
+
/**
|
|
232
|
+
* Additional app-root files or directories to serve as Cloudflare Worker
|
|
233
|
+
* Static Assets under `.output/public`. Use `to: '.'` to copy a
|
|
234
|
+
* source directory's contents into the public asset root.
|
|
235
|
+
*/
|
|
236
|
+
publicAssets?: CloudflareWorkerPublicAssetConfig[];
|
|
237
|
+
/**
|
|
238
|
+
* First-class Cloudflare D1 bindings. Modern.js writes these to
|
|
239
|
+
* `wrangler.json` as `d1_databases` and stages configured migration
|
|
240
|
+
* directories into `.output`.
|
|
241
|
+
*/
|
|
242
|
+
d1Databases?: CloudflareWorkerD1DatabaseConfig[];
|
|
243
|
+
/**
|
|
244
|
+
* First-class Cloudflare service bindings. Modern.js writes these to
|
|
245
|
+
* `wrangler.json` as `services`; when a binding also has `prefix`,
|
|
246
|
+
* the generated Worker dispatches matching requests through
|
|
247
|
+
* `env[binding].fetch(request)`.
|
|
248
|
+
*/
|
|
249
|
+
services?: CloudflareWorkerServiceBindingConfig[];
|
|
250
|
+
/**
|
|
251
|
+
* First-class Workers VPC service bindings to private origins reached
|
|
252
|
+
* through a Cloudflare Tunnel. Modern.js writes these to `wrangler.json`
|
|
253
|
+
* as `vpc_services`; a binding with `prefix` joins the prefix dispatch of
|
|
254
|
+
* `services`.
|
|
255
|
+
*/
|
|
256
|
+
vpcServices?: CloudflareWorkerVpcServiceConfig[];
|
|
257
|
+
/**
|
|
258
|
+
* Dist output paths that must not be copied into Cloudflare public assets.
|
|
259
|
+
* Entries are slash-normalized path prefixes relative to the app dist root.
|
|
260
|
+
* Top-level `api` and `shared` dist directories are excluded when matching
|
|
261
|
+
* source directories exist in the app root because they conventionally
|
|
262
|
+
* contain server-only implementation code.
|
|
263
|
+
*/
|
|
264
|
+
publicAssetExcludes?: string[];
|
|
265
|
+
}
|
|
266
|
+
|
|
197
267
|
export interface CloudflareDeployConfig {
|
|
198
|
-
worker?:
|
|
199
|
-
name?: string;
|
|
200
|
-
compatibilityDate?: string;
|
|
201
|
-
ssr?: boolean;
|
|
202
|
-
security?: CloudflareWorkerSecurityConfig;
|
|
203
|
-
wrangler?: Record<string, JsonValue>;
|
|
204
|
-
artifacts?: CloudflareWorkerArtifactConfig[];
|
|
205
|
-
publicAssets?: CloudflareWorkerPublicAssetConfig[];
|
|
206
|
-
d1Databases?: CloudflareWorkerD1DatabaseConfig[];
|
|
207
|
-
services?: CloudflareWorkerServiceBindingConfig[];
|
|
208
|
-
publicAssetExcludes?: string[];
|
|
209
|
-
};
|
|
268
|
+
worker?: CloudflareWorkerDeployConfig;
|
|
210
269
|
}
|
|
211
270
|
|
|
212
271
|
export interface NodeDeployConfig {
|