@vercel/build-utils 10.6.0 → 10.6.2
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/CHANGELOG.md +16 -0
- package/dist/get-prefixed-env-vars.js +2 -1
- package/dist/index.js +218 -5
- package/dist/lambda.d.ts +35 -3
- package/dist/lambda.js +137 -2
- package/dist/prerender.js +1 -2
- package/dist/schemas.d.ts +79 -0
- package/dist/schemas.js +78 -0
- package/dist/types.d.ts +63 -9
- package/package.json +2 -1
package/CHANGELOG.md
CHANGED
@@ -1,5 +1,21 @@
|
|
1
1
|
# @vercel/build-utils
|
2
2
|
|
3
|
+
## 10.6.2
|
4
|
+
|
5
|
+
### Patch Changes
|
6
|
+
|
7
|
+
- Add CloudEventTrigger support for Lambda functions ([#13503](https://github.com/vercel/vercel/pull/13503))
|
8
|
+
|
9
|
+
## 10.6.1
|
10
|
+
|
11
|
+
### Patch Changes
|
12
|
+
|
13
|
+
- next package uses @vercel/routing-utils HasField rather than redefining & stricter validation. ([#13409](https://github.com/vercel/vercel/pull/13409))
|
14
|
+
|
15
|
+
- Make architecture a defined property on Lambda classes to apply when creating ([#13398](https://github.com/vercel/vercel/pull/13398))
|
16
|
+
|
17
|
+
- [env-vars] expose VERCEL_PROJECT_ID as NEXT_PUBLIC_VERCEL_PROJECT_ID ([#13431](https://github.com/vercel/vercel/pull/13431))
|
18
|
+
|
3
19
|
## 10.6.0
|
4
20
|
|
5
21
|
### Minor Changes
|
package/dist/index.js
CHANGED
@@ -22372,6 +22372,23 @@ async function download(files, basePath, meta) {
|
|
22372
22372
|
}
|
22373
22373
|
|
22374
22374
|
// src/lambda.ts
|
22375
|
+
function isCloudEventQueueTrigger(trigger) {
|
22376
|
+
return trigger.type === "com.vercel.queue.v1";
|
22377
|
+
}
|
22378
|
+
function getDefaultLambdaArchitecture(architecture) {
|
22379
|
+
if (architecture) {
|
22380
|
+
return architecture;
|
22381
|
+
}
|
22382
|
+
switch (process.arch) {
|
22383
|
+
case "arm":
|
22384
|
+
case "arm64": {
|
22385
|
+
return "arm64";
|
22386
|
+
}
|
22387
|
+
default: {
|
22388
|
+
return "x86_64";
|
22389
|
+
}
|
22390
|
+
}
|
22391
|
+
}
|
22375
22392
|
var Lambda = class {
|
22376
22393
|
constructor(opts) {
|
22377
22394
|
const {
|
@@ -22388,7 +22405,8 @@ var Lambda = class {
|
|
22388
22405
|
supportsResponseStreaming,
|
22389
22406
|
experimentalResponseStreaming,
|
22390
22407
|
operationType,
|
22391
|
-
framework
|
22408
|
+
framework,
|
22409
|
+
experimentalTriggers
|
22392
22410
|
} = opts;
|
22393
22411
|
if ("files" in opts) {
|
22394
22412
|
(0, import_assert4.default)(typeof opts.files === "object", '"files" must be an object');
|
@@ -22456,12 +22474,128 @@ var Lambda = class {
|
|
22456
22474
|
);
|
22457
22475
|
}
|
22458
22476
|
}
|
22477
|
+
if (experimentalTriggers !== void 0) {
|
22478
|
+
(0, import_assert4.default)(
|
22479
|
+
Array.isArray(experimentalTriggers),
|
22480
|
+
'"experimentalTriggers" is not an Array'
|
22481
|
+
);
|
22482
|
+
for (let i = 0; i < experimentalTriggers.length; i++) {
|
22483
|
+
const trigger = experimentalTriggers[i];
|
22484
|
+
const prefix = `"experimentalTriggers[${i}]"`;
|
22485
|
+
(0, import_assert4.default)(
|
22486
|
+
typeof trigger === "object" && trigger !== null,
|
22487
|
+
`${prefix} is not an object`
|
22488
|
+
);
|
22489
|
+
(0, import_assert4.default)(
|
22490
|
+
trigger.triggerVersion === 1,
|
22491
|
+
`${prefix}.triggerVersion must be 1`
|
22492
|
+
);
|
22493
|
+
(0, import_assert4.default)(
|
22494
|
+
trigger.specversion === "1.0",
|
22495
|
+
`${prefix}.specversion must be "1.0"`
|
22496
|
+
);
|
22497
|
+
(0, import_assert4.default)(
|
22498
|
+
typeof trigger.type === "string",
|
22499
|
+
`${prefix}.type is not a string`
|
22500
|
+
);
|
22501
|
+
(0, import_assert4.default)(trigger.type.length > 0, `${prefix}.type cannot be empty`);
|
22502
|
+
if (isCloudEventQueueTrigger(trigger)) {
|
22503
|
+
(0, import_assert4.default)(
|
22504
|
+
typeof trigger.queue === "object" && trigger.queue !== null,
|
22505
|
+
`${prefix}.queue is required and must be an object for queue triggers`
|
22506
|
+
);
|
22507
|
+
const queue = trigger.queue;
|
22508
|
+
const queuePrefix = `${prefix}.queue`;
|
22509
|
+
(0, import_assert4.default)(
|
22510
|
+
typeof queue.topic === "string",
|
22511
|
+
`${queuePrefix}.topic is required and must be a string`
|
22512
|
+
);
|
22513
|
+
(0, import_assert4.default)(
|
22514
|
+
queue.topic.length > 0,
|
22515
|
+
`${queuePrefix}.topic cannot be empty`
|
22516
|
+
);
|
22517
|
+
(0, import_assert4.default)(
|
22518
|
+
typeof queue.consumer === "string",
|
22519
|
+
`${queuePrefix}.consumer is required and must be a string`
|
22520
|
+
);
|
22521
|
+
(0, import_assert4.default)(
|
22522
|
+
queue.consumer.length > 0,
|
22523
|
+
`${queuePrefix}.consumer cannot be empty`
|
22524
|
+
);
|
22525
|
+
}
|
22526
|
+
const binding = trigger.httpBinding;
|
22527
|
+
const bindingPrefix = `${prefix}.httpBinding`;
|
22528
|
+
(0, import_assert4.default)(
|
22529
|
+
typeof binding === "object" && binding !== null,
|
22530
|
+
`${bindingPrefix} is required and must be an object`
|
22531
|
+
);
|
22532
|
+
(0, import_assert4.default)(
|
22533
|
+
binding.mode === "structured",
|
22534
|
+
`${bindingPrefix}.mode must be "structured"`
|
22535
|
+
);
|
22536
|
+
if (binding.method !== void 0) {
|
22537
|
+
const validMethods = ["GET", "POST", "HEAD"];
|
22538
|
+
(0, import_assert4.default)(
|
22539
|
+
validMethods.includes(binding.method),
|
22540
|
+
`${bindingPrefix}.method must be one of: ${validMethods.join(", ")}`
|
22541
|
+
);
|
22542
|
+
}
|
22543
|
+
if (binding.pathname !== void 0) {
|
22544
|
+
(0, import_assert4.default)(
|
22545
|
+
typeof binding.pathname === "string",
|
22546
|
+
`${bindingPrefix}.pathname must be a string`
|
22547
|
+
);
|
22548
|
+
(0, import_assert4.default)(
|
22549
|
+
binding.pathname.length > 0,
|
22550
|
+
`${bindingPrefix}.pathname cannot be empty`
|
22551
|
+
);
|
22552
|
+
(0, import_assert4.default)(
|
22553
|
+
binding.pathname.startsWith("/"),
|
22554
|
+
`${bindingPrefix}.pathname must start with '/'`
|
22555
|
+
);
|
22556
|
+
}
|
22557
|
+
if (isCloudEventQueueTrigger(trigger)) {
|
22558
|
+
const queue = trigger.queue;
|
22559
|
+
const queuePrefix = `${prefix}.queue`;
|
22560
|
+
if (queue.maxAttempts !== void 0) {
|
22561
|
+
(0, import_assert4.default)(
|
22562
|
+
typeof queue.maxAttempts === "number",
|
22563
|
+
`${queuePrefix}.maxAttempts must be a number`
|
22564
|
+
);
|
22565
|
+
(0, import_assert4.default)(
|
22566
|
+
Number.isInteger(queue.maxAttempts) && queue.maxAttempts >= 0,
|
22567
|
+
`${queuePrefix}.maxAttempts must be a non-negative integer`
|
22568
|
+
);
|
22569
|
+
}
|
22570
|
+
if (queue.retryAfterSeconds !== void 0) {
|
22571
|
+
(0, import_assert4.default)(
|
22572
|
+
typeof queue.retryAfterSeconds === "number",
|
22573
|
+
`${queuePrefix}.retryAfterSeconds must be a number`
|
22574
|
+
);
|
22575
|
+
(0, import_assert4.default)(
|
22576
|
+
queue.retryAfterSeconds > 0,
|
22577
|
+
`${queuePrefix}.retryAfterSeconds must be a positive number`
|
22578
|
+
);
|
22579
|
+
}
|
22580
|
+
if (queue.initialDelaySeconds !== void 0) {
|
22581
|
+
(0, import_assert4.default)(
|
22582
|
+
typeof queue.initialDelaySeconds === "number",
|
22583
|
+
`${queuePrefix}.initialDelaySeconds must be a number`
|
22584
|
+
);
|
22585
|
+
(0, import_assert4.default)(
|
22586
|
+
queue.initialDelaySeconds >= 0,
|
22587
|
+
`${queuePrefix}.initialDelaySeconds must be a non-negative number`
|
22588
|
+
);
|
22589
|
+
}
|
22590
|
+
}
|
22591
|
+
}
|
22592
|
+
}
|
22459
22593
|
this.type = "Lambda";
|
22460
22594
|
this.operationType = operationType;
|
22461
22595
|
this.files = "files" in opts ? opts.files : void 0;
|
22462
22596
|
this.handler = handler;
|
22463
22597
|
this.runtime = runtime;
|
22464
|
-
this.architecture = architecture;
|
22598
|
+
this.architecture = getDefaultLambdaArchitecture(architecture);
|
22465
22599
|
this.memory = memory;
|
22466
22600
|
this.maxDuration = maxDuration;
|
22467
22601
|
this.environment = environment;
|
@@ -22473,6 +22607,7 @@ var Lambda = class {
|
|
22473
22607
|
this.supportsResponseStreaming = supportsResponseStreaming ?? experimentalResponseStreaming;
|
22474
22608
|
this.framework = framework;
|
22475
22609
|
this.experimentalAllowBundling = "experimentalAllowBundling" in opts ? opts.experimentalAllowBundling : void 0;
|
22610
|
+
this.experimentalTriggers = experimentalTriggers;
|
22476
22611
|
}
|
22477
22612
|
async createZip() {
|
22478
22613
|
let { zipBuffer } = this;
|
@@ -22629,8 +22764,7 @@ var Prerender = class {
|
|
22629
22764
|
}
|
22630
22765
|
if (experimentalBypassFor !== void 0) {
|
22631
22766
|
if (!Array.isArray(experimentalBypassFor) || experimentalBypassFor.some(
|
22632
|
-
(field) => typeof field !== "object" ||
|
22633
|
-
field.type !== "host" && typeof field.key !== "string" || typeof field.type !== "string" || field.value !== void 0 && typeof field.value !== "string"
|
22767
|
+
(field) => typeof field !== "object" || typeof field.type !== "string" || field.type === "host" && "key" in field || field.type !== "host" && typeof field.key !== "string" || field.value !== void 0 && typeof field.value !== "string" && (typeof field.value !== "object" || field.value === null || Array.isArray(field.value))
|
22634
22768
|
)) {
|
22635
22769
|
throw new Error(
|
22636
22770
|
"The `experimentalBypassFor` argument for `Prerender` must be Array of objects with fields `type`, `key` and optionally `value`."
|
@@ -24087,7 +24221,8 @@ function getPrefixedEnvVars({
|
|
24087
24221
|
"VERCEL_REGION",
|
24088
24222
|
"VERCEL_BRANCH_URL",
|
24089
24223
|
"VERCEL_PROJECT_PRODUCTION_URL",
|
24090
|
-
"VERCEL_DEPLOYMENT_ID"
|
24224
|
+
"VERCEL_DEPLOYMENT_ID",
|
24225
|
+
"VERCEL_PROJECT_ID"
|
24091
24226
|
];
|
24092
24227
|
const newEnvs = {};
|
24093
24228
|
if (envPrefix && envs.VERCEL_URL) {
|
@@ -24258,6 +24393,80 @@ function hasProp(obj, key) {
|
|
24258
24393
|
}
|
24259
24394
|
|
24260
24395
|
// src/schemas.ts
|
24396
|
+
var cloudEventTriggerSchema = {
|
24397
|
+
type: "object",
|
24398
|
+
properties: {
|
24399
|
+
triggerVersion: {
|
24400
|
+
type: "number",
|
24401
|
+
const: 1
|
24402
|
+
},
|
24403
|
+
specversion: {
|
24404
|
+
type: "string",
|
24405
|
+
const: "1.0"
|
24406
|
+
},
|
24407
|
+
type: {
|
24408
|
+
type: "string",
|
24409
|
+
minLength: 1
|
24410
|
+
},
|
24411
|
+
httpBinding: {
|
24412
|
+
type: "object",
|
24413
|
+
properties: {
|
24414
|
+
mode: {
|
24415
|
+
type: "string",
|
24416
|
+
const: "structured"
|
24417
|
+
},
|
24418
|
+
method: {
|
24419
|
+
type: "string",
|
24420
|
+
enum: ["GET", "POST", "HEAD"]
|
24421
|
+
},
|
24422
|
+
pathname: {
|
24423
|
+
type: "string",
|
24424
|
+
minLength: 1,
|
24425
|
+
pattern: "^/"
|
24426
|
+
}
|
24427
|
+
},
|
24428
|
+
required: ["mode"],
|
24429
|
+
additionalProperties: false
|
24430
|
+
},
|
24431
|
+
queue: {
|
24432
|
+
type: "object",
|
24433
|
+
properties: {
|
24434
|
+
topic: {
|
24435
|
+
type: "string",
|
24436
|
+
minLength: 1
|
24437
|
+
},
|
24438
|
+
consumer: {
|
24439
|
+
type: "string",
|
24440
|
+
minLength: 1
|
24441
|
+
},
|
24442
|
+
maxAttempts: {
|
24443
|
+
type: "number",
|
24444
|
+
minimum: 0
|
24445
|
+
},
|
24446
|
+
retryAfterSeconds: {
|
24447
|
+
type: "number",
|
24448
|
+
exclusiveMinimum: 0
|
24449
|
+
},
|
24450
|
+
initialDelaySeconds: {
|
24451
|
+
type: "number",
|
24452
|
+
minimum: 0
|
24453
|
+
}
|
24454
|
+
},
|
24455
|
+
required: ["topic", "consumer"],
|
24456
|
+
additionalProperties: false
|
24457
|
+
}
|
24458
|
+
},
|
24459
|
+
required: ["triggerVersion", "specversion", "type", "httpBinding"],
|
24460
|
+
additionalProperties: false,
|
24461
|
+
if: {
|
24462
|
+
properties: {
|
24463
|
+
type: { const: "com.vercel.queue.v1" }
|
24464
|
+
}
|
24465
|
+
},
|
24466
|
+
then: {
|
24467
|
+
required: ["triggerVersion", "specversion", "type", "httpBinding", "queue"]
|
24468
|
+
}
|
24469
|
+
};
|
24261
24470
|
var functionsSchema = {
|
24262
24471
|
type: "object",
|
24263
24472
|
minProperties: 1,
|
@@ -24292,6 +24501,10 @@ var functionsSchema = {
|
|
24292
24501
|
excludeFiles: {
|
24293
24502
|
type: "string",
|
24294
24503
|
maxLength: 256
|
24504
|
+
},
|
24505
|
+
experimentalTriggers: {
|
24506
|
+
type: "array",
|
24507
|
+
items: cloudEventTriggerSchema
|
24295
24508
|
}
|
24296
24509
|
}
|
24297
24510
|
}
|
package/dist/lambda.d.ts
CHANGED
@@ -1,5 +1,6 @@
|
|
1
1
|
/// <reference types="node" />
|
2
|
-
import type { Config, Env, Files, FunctionFramework } from './types';
|
2
|
+
import type { Config, Env, Files, FunctionFramework, CloudEventTrigger, CloudEventTriggerBase, CloudEventQueueTrigger } from './types';
|
3
|
+
export type { CloudEventTrigger, CloudEventTriggerBase, CloudEventQueueTrigger, };
|
3
4
|
export type LambdaOptions = LambdaOptionsWithFiles | LambdaOptionsWithZipBuffer;
|
4
5
|
export type LambdaArchitecture = 'x86_64' | 'arm64';
|
5
6
|
export interface LambdaOptionsBase {
|
@@ -20,6 +21,22 @@ export interface LambdaOptionsBase {
|
|
20
21
|
experimentalResponseStreaming?: boolean;
|
21
22
|
operationType?: string;
|
22
23
|
framework?: FunctionFramework;
|
24
|
+
/**
|
25
|
+
* Experimental CloudEvents trigger definitions that this Lambda can receive.
|
26
|
+
* Defines what types of CloudEvents this Lambda can handle as an HTTP endpoint.
|
27
|
+
* Currently supports HTTP protocol binding in structured mode only.
|
28
|
+
* Only supports CloudEvents specification version 1.0.
|
29
|
+
*
|
30
|
+
* The delivery configuration provides HINTS to the system about preferred
|
31
|
+
* execution behavior (concurrency, retries) but these are NOT guarantees.
|
32
|
+
* The system may disregard these hints based on resource constraints.
|
33
|
+
*
|
34
|
+
* IMPORTANT: HTTP request-response semantics remain synchronous regardless
|
35
|
+
* of delivery configuration. Callers receive immediate responses.
|
36
|
+
*
|
37
|
+
* @experimental This feature is experimental and may change.
|
38
|
+
*/
|
39
|
+
experimentalTriggers?: CloudEventTrigger[];
|
23
40
|
}
|
24
41
|
export interface LambdaOptionsWithFiles extends LambdaOptionsBase {
|
25
42
|
files: Files;
|
@@ -49,7 +66,7 @@ export declare class Lambda {
|
|
49
66
|
files?: Files;
|
50
67
|
handler: string;
|
51
68
|
runtime: string;
|
52
|
-
architecture
|
69
|
+
architecture: LambdaArchitecture;
|
53
70
|
memory?: number;
|
54
71
|
maxDuration?: number;
|
55
72
|
environment: Env;
|
@@ -64,6 +81,22 @@ export declare class Lambda {
|
|
64
81
|
supportsResponseStreaming?: boolean;
|
65
82
|
framework?: FunctionFramework;
|
66
83
|
experimentalAllowBundling?: boolean;
|
84
|
+
/**
|
85
|
+
* Experimental CloudEvents trigger definitions that this Lambda can receive.
|
86
|
+
* Defines what types of CloudEvents this Lambda can handle as an HTTP endpoint.
|
87
|
+
* Currently supports HTTP protocol binding in structured mode only.
|
88
|
+
* Only supports CloudEvents specification version 1.0.
|
89
|
+
*
|
90
|
+
* The delivery configuration provides HINTS to the system about preferred
|
91
|
+
* execution behavior (concurrency, retries) but these are NOT guarantees.
|
92
|
+
* The system may disregard these hints based on resource constraints.
|
93
|
+
*
|
94
|
+
* IMPORTANT: HTTP request-response semantics remain synchronous regardless
|
95
|
+
* of delivery configuration. Callers receive immediate responses.
|
96
|
+
*
|
97
|
+
* @experimental This feature is experimental and may change.
|
98
|
+
*/
|
99
|
+
experimentalTriggers?: CloudEventTrigger[];
|
67
100
|
constructor(opts: LambdaOptions);
|
68
101
|
createZip(): Promise<Buffer>;
|
69
102
|
/**
|
@@ -78,4 +111,3 @@ export declare class Lambda {
|
|
78
111
|
export declare function createLambda(opts: LambdaOptions): Promise<Lambda>;
|
79
112
|
export declare function createZip(files: Files): Promise<Buffer>;
|
80
113
|
export declare function getLambdaOptionsFromFunction({ sourceFile, config, }: GetLambdaOptionsFromFunctionOptions): Promise<Pick<LambdaOptions, 'architecture' | 'memory' | 'maxDuration'>>;
|
81
|
-
export {};
|
package/dist/lambda.js
CHANGED
@@ -41,6 +41,23 @@ var import_minimatch = __toESM(require("minimatch"));
|
|
41
41
|
var import_fs_extra = require("fs-extra");
|
42
42
|
var import_download = require("./fs/download");
|
43
43
|
var import_stream_to_buffer = __toESM(require("./fs/stream-to-buffer"));
|
44
|
+
function isCloudEventQueueTrigger(trigger) {
|
45
|
+
return trigger.type === "com.vercel.queue.v1";
|
46
|
+
}
|
47
|
+
function getDefaultLambdaArchitecture(architecture) {
|
48
|
+
if (architecture) {
|
49
|
+
return architecture;
|
50
|
+
}
|
51
|
+
switch (process.arch) {
|
52
|
+
case "arm":
|
53
|
+
case "arm64": {
|
54
|
+
return "arm64";
|
55
|
+
}
|
56
|
+
default: {
|
57
|
+
return "x86_64";
|
58
|
+
}
|
59
|
+
}
|
60
|
+
}
|
44
61
|
class Lambda {
|
45
62
|
constructor(opts) {
|
46
63
|
const {
|
@@ -57,7 +74,8 @@ class Lambda {
|
|
57
74
|
supportsResponseStreaming,
|
58
75
|
experimentalResponseStreaming,
|
59
76
|
operationType,
|
60
|
-
framework
|
77
|
+
framework,
|
78
|
+
experimentalTriggers
|
61
79
|
} = opts;
|
62
80
|
if ("files" in opts) {
|
63
81
|
(0, import_assert.default)(typeof opts.files === "object", '"files" must be an object');
|
@@ -125,12 +143,128 @@ class Lambda {
|
|
125
143
|
);
|
126
144
|
}
|
127
145
|
}
|
146
|
+
if (experimentalTriggers !== void 0) {
|
147
|
+
(0, import_assert.default)(
|
148
|
+
Array.isArray(experimentalTriggers),
|
149
|
+
'"experimentalTriggers" is not an Array'
|
150
|
+
);
|
151
|
+
for (let i = 0; i < experimentalTriggers.length; i++) {
|
152
|
+
const trigger = experimentalTriggers[i];
|
153
|
+
const prefix = `"experimentalTriggers[${i}]"`;
|
154
|
+
(0, import_assert.default)(
|
155
|
+
typeof trigger === "object" && trigger !== null,
|
156
|
+
`${prefix} is not an object`
|
157
|
+
);
|
158
|
+
(0, import_assert.default)(
|
159
|
+
trigger.triggerVersion === 1,
|
160
|
+
`${prefix}.triggerVersion must be 1`
|
161
|
+
);
|
162
|
+
(0, import_assert.default)(
|
163
|
+
trigger.specversion === "1.0",
|
164
|
+
`${prefix}.specversion must be "1.0"`
|
165
|
+
);
|
166
|
+
(0, import_assert.default)(
|
167
|
+
typeof trigger.type === "string",
|
168
|
+
`${prefix}.type is not a string`
|
169
|
+
);
|
170
|
+
(0, import_assert.default)(trigger.type.length > 0, `${prefix}.type cannot be empty`);
|
171
|
+
if (isCloudEventQueueTrigger(trigger)) {
|
172
|
+
(0, import_assert.default)(
|
173
|
+
typeof trigger.queue === "object" && trigger.queue !== null,
|
174
|
+
`${prefix}.queue is required and must be an object for queue triggers`
|
175
|
+
);
|
176
|
+
const queue = trigger.queue;
|
177
|
+
const queuePrefix = `${prefix}.queue`;
|
178
|
+
(0, import_assert.default)(
|
179
|
+
typeof queue.topic === "string",
|
180
|
+
`${queuePrefix}.topic is required and must be a string`
|
181
|
+
);
|
182
|
+
(0, import_assert.default)(
|
183
|
+
queue.topic.length > 0,
|
184
|
+
`${queuePrefix}.topic cannot be empty`
|
185
|
+
);
|
186
|
+
(0, import_assert.default)(
|
187
|
+
typeof queue.consumer === "string",
|
188
|
+
`${queuePrefix}.consumer is required and must be a string`
|
189
|
+
);
|
190
|
+
(0, import_assert.default)(
|
191
|
+
queue.consumer.length > 0,
|
192
|
+
`${queuePrefix}.consumer cannot be empty`
|
193
|
+
);
|
194
|
+
}
|
195
|
+
const binding = trigger.httpBinding;
|
196
|
+
const bindingPrefix = `${prefix}.httpBinding`;
|
197
|
+
(0, import_assert.default)(
|
198
|
+
typeof binding === "object" && binding !== null,
|
199
|
+
`${bindingPrefix} is required and must be an object`
|
200
|
+
);
|
201
|
+
(0, import_assert.default)(
|
202
|
+
binding.mode === "structured",
|
203
|
+
`${bindingPrefix}.mode must be "structured"`
|
204
|
+
);
|
205
|
+
if (binding.method !== void 0) {
|
206
|
+
const validMethods = ["GET", "POST", "HEAD"];
|
207
|
+
(0, import_assert.default)(
|
208
|
+
validMethods.includes(binding.method),
|
209
|
+
`${bindingPrefix}.method must be one of: ${validMethods.join(", ")}`
|
210
|
+
);
|
211
|
+
}
|
212
|
+
if (binding.pathname !== void 0) {
|
213
|
+
(0, import_assert.default)(
|
214
|
+
typeof binding.pathname === "string",
|
215
|
+
`${bindingPrefix}.pathname must be a string`
|
216
|
+
);
|
217
|
+
(0, import_assert.default)(
|
218
|
+
binding.pathname.length > 0,
|
219
|
+
`${bindingPrefix}.pathname cannot be empty`
|
220
|
+
);
|
221
|
+
(0, import_assert.default)(
|
222
|
+
binding.pathname.startsWith("/"),
|
223
|
+
`${bindingPrefix}.pathname must start with '/'`
|
224
|
+
);
|
225
|
+
}
|
226
|
+
if (isCloudEventQueueTrigger(trigger)) {
|
227
|
+
const queue = trigger.queue;
|
228
|
+
const queuePrefix = `${prefix}.queue`;
|
229
|
+
if (queue.maxAttempts !== void 0) {
|
230
|
+
(0, import_assert.default)(
|
231
|
+
typeof queue.maxAttempts === "number",
|
232
|
+
`${queuePrefix}.maxAttempts must be a number`
|
233
|
+
);
|
234
|
+
(0, import_assert.default)(
|
235
|
+
Number.isInteger(queue.maxAttempts) && queue.maxAttempts >= 0,
|
236
|
+
`${queuePrefix}.maxAttempts must be a non-negative integer`
|
237
|
+
);
|
238
|
+
}
|
239
|
+
if (queue.retryAfterSeconds !== void 0) {
|
240
|
+
(0, import_assert.default)(
|
241
|
+
typeof queue.retryAfterSeconds === "number",
|
242
|
+
`${queuePrefix}.retryAfterSeconds must be a number`
|
243
|
+
);
|
244
|
+
(0, import_assert.default)(
|
245
|
+
queue.retryAfterSeconds > 0,
|
246
|
+
`${queuePrefix}.retryAfterSeconds must be a positive number`
|
247
|
+
);
|
248
|
+
}
|
249
|
+
if (queue.initialDelaySeconds !== void 0) {
|
250
|
+
(0, import_assert.default)(
|
251
|
+
typeof queue.initialDelaySeconds === "number",
|
252
|
+
`${queuePrefix}.initialDelaySeconds must be a number`
|
253
|
+
);
|
254
|
+
(0, import_assert.default)(
|
255
|
+
queue.initialDelaySeconds >= 0,
|
256
|
+
`${queuePrefix}.initialDelaySeconds must be a non-negative number`
|
257
|
+
);
|
258
|
+
}
|
259
|
+
}
|
260
|
+
}
|
261
|
+
}
|
128
262
|
this.type = "Lambda";
|
129
263
|
this.operationType = operationType;
|
130
264
|
this.files = "files" in opts ? opts.files : void 0;
|
131
265
|
this.handler = handler;
|
132
266
|
this.runtime = runtime;
|
133
|
-
this.architecture = architecture;
|
267
|
+
this.architecture = getDefaultLambdaArchitecture(architecture);
|
134
268
|
this.memory = memory;
|
135
269
|
this.maxDuration = maxDuration;
|
136
270
|
this.environment = environment;
|
@@ -142,6 +276,7 @@ class Lambda {
|
|
142
276
|
this.supportsResponseStreaming = supportsResponseStreaming ?? experimentalResponseStreaming;
|
143
277
|
this.framework = framework;
|
144
278
|
this.experimentalAllowBundling = "experimentalAllowBundling" in opts ? opts.experimentalAllowBundling : void 0;
|
279
|
+
this.experimentalTriggers = experimentalTriggers;
|
145
280
|
}
|
146
281
|
async createZip() {
|
147
282
|
let { zipBuffer } = this;
|
package/dist/prerender.js
CHANGED
@@ -76,8 +76,7 @@ class Prerender {
|
|
76
76
|
}
|
77
77
|
if (experimentalBypassFor !== void 0) {
|
78
78
|
if (!Array.isArray(experimentalBypassFor) || experimentalBypassFor.some(
|
79
|
-
(field) => typeof field !== "object" ||
|
80
|
-
field.type !== "host" && typeof field.key !== "string" || typeof field.type !== "string" || field.value !== void 0 && typeof field.value !== "string"
|
79
|
+
(field) => typeof field !== "object" || typeof field.type !== "string" || field.type === "host" && "key" in field || field.type !== "host" && typeof field.key !== "string" || field.value !== void 0 && typeof field.value !== "string" && (typeof field.value !== "object" || field.value === null || Array.isArray(field.value))
|
81
80
|
)) {
|
82
81
|
throw new Error(
|
83
82
|
"The `experimentalBypassFor` argument for `Prerender` must be Array of objects with fields `type`, `key` and optionally `value`."
|
package/dist/schemas.d.ts
CHANGED
@@ -33,6 +33,85 @@ export declare const functionsSchema: {
|
|
33
33
|
type: string;
|
34
34
|
maxLength: number;
|
35
35
|
};
|
36
|
+
experimentalTriggers: {
|
37
|
+
type: string;
|
38
|
+
items: {
|
39
|
+
type: string;
|
40
|
+
properties: {
|
41
|
+
triggerVersion: {
|
42
|
+
type: string;
|
43
|
+
const: number;
|
44
|
+
};
|
45
|
+
specversion: {
|
46
|
+
type: string;
|
47
|
+
const: string;
|
48
|
+
};
|
49
|
+
type: {
|
50
|
+
type: string;
|
51
|
+
minLength: number;
|
52
|
+
};
|
53
|
+
httpBinding: {
|
54
|
+
type: string;
|
55
|
+
properties: {
|
56
|
+
mode: {
|
57
|
+
type: string;
|
58
|
+
const: string;
|
59
|
+
};
|
60
|
+
method: {
|
61
|
+
type: string;
|
62
|
+
enum: string[];
|
63
|
+
};
|
64
|
+
pathname: {
|
65
|
+
type: string;
|
66
|
+
minLength: number;
|
67
|
+
pattern: string;
|
68
|
+
};
|
69
|
+
};
|
70
|
+
required: string[];
|
71
|
+
additionalProperties: boolean;
|
72
|
+
};
|
73
|
+
queue: {
|
74
|
+
type: string;
|
75
|
+
properties: {
|
76
|
+
topic: {
|
77
|
+
type: string;
|
78
|
+
minLength: number;
|
79
|
+
};
|
80
|
+
consumer: {
|
81
|
+
type: string;
|
82
|
+
minLength: number;
|
83
|
+
};
|
84
|
+
maxAttempts: {
|
85
|
+
type: string;
|
86
|
+
minimum: number;
|
87
|
+
};
|
88
|
+
retryAfterSeconds: {
|
89
|
+
type: string;
|
90
|
+
exclusiveMinimum: number;
|
91
|
+
};
|
92
|
+
initialDelaySeconds: {
|
93
|
+
type: string;
|
94
|
+
minimum: number;
|
95
|
+
};
|
96
|
+
};
|
97
|
+
required: string[];
|
98
|
+
additionalProperties: boolean;
|
99
|
+
};
|
100
|
+
};
|
101
|
+
required: string[];
|
102
|
+
additionalProperties: boolean;
|
103
|
+
if: {
|
104
|
+
properties: {
|
105
|
+
type: {
|
106
|
+
const: string;
|
107
|
+
};
|
108
|
+
};
|
109
|
+
};
|
110
|
+
then: {
|
111
|
+
required: string[];
|
112
|
+
};
|
113
|
+
};
|
114
|
+
};
|
36
115
|
};
|
37
116
|
};
|
38
117
|
};
|
package/dist/schemas.js
CHANGED
@@ -22,6 +22,80 @@ __export(schemas_exports, {
|
|
22
22
|
functionsSchema: () => functionsSchema
|
23
23
|
});
|
24
24
|
module.exports = __toCommonJS(schemas_exports);
|
25
|
+
const cloudEventTriggerSchema = {
|
26
|
+
type: "object",
|
27
|
+
properties: {
|
28
|
+
triggerVersion: {
|
29
|
+
type: "number",
|
30
|
+
const: 1
|
31
|
+
},
|
32
|
+
specversion: {
|
33
|
+
type: "string",
|
34
|
+
const: "1.0"
|
35
|
+
},
|
36
|
+
type: {
|
37
|
+
type: "string",
|
38
|
+
minLength: 1
|
39
|
+
},
|
40
|
+
httpBinding: {
|
41
|
+
type: "object",
|
42
|
+
properties: {
|
43
|
+
mode: {
|
44
|
+
type: "string",
|
45
|
+
const: "structured"
|
46
|
+
},
|
47
|
+
method: {
|
48
|
+
type: "string",
|
49
|
+
enum: ["GET", "POST", "HEAD"]
|
50
|
+
},
|
51
|
+
pathname: {
|
52
|
+
type: "string",
|
53
|
+
minLength: 1,
|
54
|
+
pattern: "^/"
|
55
|
+
}
|
56
|
+
},
|
57
|
+
required: ["mode"],
|
58
|
+
additionalProperties: false
|
59
|
+
},
|
60
|
+
queue: {
|
61
|
+
type: "object",
|
62
|
+
properties: {
|
63
|
+
topic: {
|
64
|
+
type: "string",
|
65
|
+
minLength: 1
|
66
|
+
},
|
67
|
+
consumer: {
|
68
|
+
type: "string",
|
69
|
+
minLength: 1
|
70
|
+
},
|
71
|
+
maxAttempts: {
|
72
|
+
type: "number",
|
73
|
+
minimum: 0
|
74
|
+
},
|
75
|
+
retryAfterSeconds: {
|
76
|
+
type: "number",
|
77
|
+
exclusiveMinimum: 0
|
78
|
+
},
|
79
|
+
initialDelaySeconds: {
|
80
|
+
type: "number",
|
81
|
+
minimum: 0
|
82
|
+
}
|
83
|
+
},
|
84
|
+
required: ["topic", "consumer"],
|
85
|
+
additionalProperties: false
|
86
|
+
}
|
87
|
+
},
|
88
|
+
required: ["triggerVersion", "specversion", "type", "httpBinding"],
|
89
|
+
additionalProperties: false,
|
90
|
+
if: {
|
91
|
+
properties: {
|
92
|
+
type: { const: "com.vercel.queue.v1" }
|
93
|
+
}
|
94
|
+
},
|
95
|
+
then: {
|
96
|
+
required: ["triggerVersion", "specversion", "type", "httpBinding", "queue"]
|
97
|
+
}
|
98
|
+
};
|
25
99
|
const functionsSchema = {
|
26
100
|
type: "object",
|
27
101
|
minProperties: 1,
|
@@ -56,6 +130,10 @@ const functionsSchema = {
|
|
56
130
|
excludeFiles: {
|
57
131
|
type: "string",
|
58
132
|
maxLength: 256
|
133
|
+
},
|
134
|
+
experimentalTriggers: {
|
135
|
+
type: "array",
|
136
|
+
items: cloudEventTriggerSchema
|
59
137
|
}
|
60
138
|
}
|
61
139
|
}
|
package/dist/types.d.ts
CHANGED
@@ -6,6 +6,7 @@ import type { Lambda, LambdaArchitecture } from './lambda';
|
|
6
6
|
import type { Prerender } from './prerender';
|
7
7
|
import type { EdgeFunction } from './edge-function';
|
8
8
|
import type { Span } from './trace';
|
9
|
+
import type { HasField } from '@vercel/routing-utils';
|
9
10
|
export interface Env {
|
10
11
|
[name: string]: string | undefined;
|
11
12
|
}
|
@@ -44,14 +45,7 @@ export interface Config {
|
|
44
45
|
middleware?: boolean;
|
45
46
|
[key: string]: unknown;
|
46
47
|
}
|
47
|
-
export type HasField
|
48
|
-
type: 'host';
|
49
|
-
value: string;
|
50
|
-
} | {
|
51
|
-
type: 'header' | 'cookie' | 'query';
|
52
|
-
key: string;
|
53
|
-
value?: string;
|
54
|
-
}>;
|
48
|
+
export type { HasField };
|
55
49
|
export interface Meta {
|
56
50
|
isDev?: boolean;
|
57
51
|
devCacheDir?: string;
|
@@ -328,6 +322,7 @@ export interface BuilderFunctions {
|
|
328
322
|
runtime?: string;
|
329
323
|
includeFiles?: string;
|
330
324
|
excludeFiles?: string;
|
325
|
+
experimentalTriggers?: CloudEventTrigger[];
|
331
326
|
};
|
332
327
|
}
|
333
328
|
export interface ProjectSettings {
|
@@ -502,4 +497,63 @@ export interface Chain {
|
|
502
497
|
*/
|
503
498
|
headers: Record<string, string>;
|
504
499
|
}
|
505
|
-
|
500
|
+
/**
|
501
|
+
* Base CloudEvent trigger definition for HTTP protocol binding.
|
502
|
+
* Defines what types of CloudEvents this Lambda can receive as an HTTP endpoint.
|
503
|
+
*
|
504
|
+
* @see https://github.com/cloudevents/spec/blob/main/cloudevents/spec.md
|
505
|
+
* @see https://github.com/cloudevents/spec/blob/main/cloudevents/bindings/http-protocol-binding.md
|
506
|
+
* @see https://github.com/cloudevents/spec/blob/main/subscriptions/spec.md
|
507
|
+
*/
|
508
|
+
export interface CloudEventTriggerBase<T extends string = string> {
|
509
|
+
/** Vercel trigger specification version - must be 1 (REQUIRED) */
|
510
|
+
triggerVersion: 1;
|
511
|
+
/** CloudEvents specification version - must be "1.0" (REQUIRED) */
|
512
|
+
specversion: '1.0';
|
513
|
+
/** Event type pattern this trigger handles (REQUIRED) */
|
514
|
+
type: T;
|
515
|
+
/** HTTP binding configuration (REQUIRED) */
|
516
|
+
httpBinding: {
|
517
|
+
/** HTTP binding mode - only structured mode is supported (REQUIRED) */
|
518
|
+
mode: 'structured';
|
519
|
+
/** HTTP method for this trigger endpoint (OPTIONAL, default: 'POST') */
|
520
|
+
method?: 'GET' | 'POST' | 'HEAD';
|
521
|
+
/** HTTP pathname for this trigger endpoint (OPTIONAL) */
|
522
|
+
pathname?: string;
|
523
|
+
};
|
524
|
+
}
|
525
|
+
/**
|
526
|
+
* CloudEvent queue trigger for Vercel's queue system.
|
527
|
+
* Handles "com.vercel.queue.v1" events with queue-specific configuration.
|
528
|
+
*/
|
529
|
+
export interface CloudEventQueueTrigger extends CloudEventTriggerBase<'com.vercel.queue.v1'> {
|
530
|
+
/**
|
531
|
+
* Queue configuration for this trigger (REQUIRED)
|
532
|
+
*/
|
533
|
+
queue: {
|
534
|
+
/** Name of the queue topic to consume from (REQUIRED) */
|
535
|
+
topic: string;
|
536
|
+
/** Name of the consumer group for this trigger (REQUIRED) */
|
537
|
+
consumer: string;
|
538
|
+
/**
|
539
|
+
* Maximum number of retry attempts for failed executions (OPTIONAL)
|
540
|
+
* Behavior when not specified depends on the server's default configuration.
|
541
|
+
*/
|
542
|
+
maxAttempts?: number;
|
543
|
+
/**
|
544
|
+
* Delay in seconds before retrying failed executions (OPTIONAL)
|
545
|
+
* Behavior when not specified depends on the server's default configuration.
|
546
|
+
*/
|
547
|
+
retryAfterSeconds?: number;
|
548
|
+
/**
|
549
|
+
* Initial delay in seconds before first execution attempt (OPTIONAL)
|
550
|
+
* Must be 0 or greater. Use 0 for no initial delay.
|
551
|
+
* Behavior when not specified depends on the server's default configuration.
|
552
|
+
*/
|
553
|
+
initialDelaySeconds?: number;
|
554
|
+
};
|
555
|
+
}
|
556
|
+
/**
|
557
|
+
* Union type of all supported CloudEvent trigger types.
|
558
|
+
*/
|
559
|
+
export type CloudEventTrigger = CloudEventTriggerBase | CloudEventQueueTrigger;
|
package/package.json
CHANGED
@@ -1,6 +1,6 @@
|
|
1
1
|
{
|
2
2
|
"name": "@vercel/build-utils",
|
3
|
-
"version": "10.6.
|
3
|
+
"version": "10.6.2",
|
4
4
|
"license": "Apache-2.0",
|
5
5
|
"main": "./dist/index.js",
|
6
6
|
"types": "./dist/index.d.js",
|
@@ -27,6 +27,7 @@
|
|
27
27
|
"@types/semver": "6.0.0",
|
28
28
|
"@types/yazl": "2.4.2",
|
29
29
|
"@vercel/error-utils": "2.0.3",
|
30
|
+
"@vercel/routing-utils": "5.1.0",
|
30
31
|
"aggregate-error": "3.0.1",
|
31
32
|
"async-retry": "1.2.3",
|
32
33
|
"async-sema": "2.1.4",
|