@netlify/zip-it-and-ship-it 14.5.5 → 14.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/config.d.ts CHANGED
@@ -1,6 +1,8 @@
1
+ import type { FunctionRegion } from '@netlify/types';
1
2
  import { z } from 'zod';
2
3
  import { FunctionSource } from './function.js';
3
- export declare const functionConfig: z.ZodObject<{
4
+ export declare const functionConfigShape: z.ZodObject<{
5
+ background: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
4
6
  externalNodeModules: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
5
7
  generator: z.ZodCatch<z.ZodOptional<z.ZodString>>;
6
8
  includedFiles: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
@@ -16,9 +18,12 @@ export declare const functionConfig: z.ZodObject<{
16
18
  }>>>;
17
19
  nodeSourcemap: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
18
20
  nodeVersion: z.ZodCatch<z.ZodOptional<z.ZodString>>;
21
+ memory: z.ZodOptional<z.ZodEffects<z.ZodNumber, number, unknown>>;
22
+ region: z.ZodOptional<z.ZodEffects<z.ZodEnum<[FunctionRegion, ...FunctionRegion[]]>, FunctionRegion, unknown>>;
19
23
  rustTargetDirectory: z.ZodCatch<z.ZodOptional<z.ZodString>>;
20
24
  schedule: z.ZodCatch<z.ZodOptional<z.ZodString>>;
21
25
  timeout: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
26
+ vcpu: z.ZodOptional<z.ZodNumber>;
22
27
  zipGo: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
23
28
  nodeModuleFormat: z.ZodCatch<z.ZodOptional<z.ZodNativeEnum<{
24
29
  readonly COMMONJS: "cjs";
@@ -26,6 +31,7 @@ export declare const functionConfig: z.ZodObject<{
26
31
  }>>>;
27
32
  }, "strip", z.ZodTypeAny, {
28
33
  name?: string | undefined;
34
+ background?: boolean | undefined;
29
35
  externalNodeModules?: string[] | undefined;
30
36
  generator?: string | undefined;
31
37
  includedFiles?: string[] | undefined;
@@ -34,13 +40,17 @@ export declare const functionConfig: z.ZodObject<{
34
40
  nodeBundler?: "none" | "esbuild" | "esbuild_zisi" | "nft" | "zisi" | undefined;
35
41
  nodeSourcemap?: boolean | undefined;
36
42
  nodeVersion?: string | undefined;
43
+ memory?: number | undefined;
44
+ region?: FunctionRegion | undefined;
37
45
  rustTargetDirectory?: string | undefined;
38
46
  schedule?: string | undefined;
39
47
  timeout?: number | undefined;
48
+ vcpu?: number | undefined;
40
49
  zipGo?: boolean | undefined;
41
50
  nodeModuleFormat?: "cjs" | "esm" | undefined;
42
51
  }, {
43
52
  name?: unknown;
53
+ background?: unknown;
44
54
  externalNodeModules?: unknown;
45
55
  generator?: unknown;
46
56
  includedFiles?: unknown;
@@ -49,13 +59,121 @@ export declare const functionConfig: z.ZodObject<{
49
59
  nodeBundler?: unknown;
50
60
  nodeSourcemap?: unknown;
51
61
  nodeVersion?: unknown;
62
+ memory?: unknown;
63
+ region?: unknown;
52
64
  rustTargetDirectory?: unknown;
53
65
  schedule?: unknown;
54
66
  timeout?: unknown;
67
+ vcpu?: number | undefined;
55
68
  zipGo?: unknown;
56
69
  nodeModuleFormat?: unknown;
57
70
  }>;
58
- type FunctionConfig = z.infer<typeof functionConfig>;
71
+ export declare const functionConfig: z.ZodEffects<z.ZodObject<{
72
+ background: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
73
+ externalNodeModules: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
74
+ generator: z.ZodCatch<z.ZodOptional<z.ZodString>>;
75
+ includedFiles: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
76
+ includedFilesBasePath: z.ZodCatch<z.ZodOptional<z.ZodString>>;
77
+ ignoredNodeModules: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
78
+ name: z.ZodCatch<z.ZodOptional<z.ZodString>>;
79
+ nodeBundler: z.ZodCatch<z.ZodOptional<z.ZodNativeEnum<{
80
+ readonly ESBUILD: "esbuild";
81
+ readonly ESBUILD_ZISI: "esbuild_zisi";
82
+ readonly NFT: "nft";
83
+ readonly ZISI: "zisi";
84
+ readonly NONE: "none";
85
+ }>>>;
86
+ nodeSourcemap: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
87
+ nodeVersion: z.ZodCatch<z.ZodOptional<z.ZodString>>;
88
+ memory: z.ZodOptional<z.ZodEffects<z.ZodNumber, number, unknown>>;
89
+ region: z.ZodOptional<z.ZodEffects<z.ZodEnum<[FunctionRegion, ...FunctionRegion[]]>, FunctionRegion, unknown>>;
90
+ rustTargetDirectory: z.ZodCatch<z.ZodOptional<z.ZodString>>;
91
+ schedule: z.ZodCatch<z.ZodOptional<z.ZodString>>;
92
+ timeout: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
93
+ vcpu: z.ZodOptional<z.ZodNumber>;
94
+ zipGo: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
95
+ nodeModuleFormat: z.ZodCatch<z.ZodOptional<z.ZodNativeEnum<{
96
+ readonly COMMONJS: "cjs";
97
+ readonly ESM: "esm";
98
+ }>>>;
99
+ }, "strip", z.ZodTypeAny, {
100
+ name?: string | undefined;
101
+ background?: boolean | undefined;
102
+ externalNodeModules?: string[] | undefined;
103
+ generator?: string | undefined;
104
+ includedFiles?: string[] | undefined;
105
+ includedFilesBasePath?: string | undefined;
106
+ ignoredNodeModules?: string[] | undefined;
107
+ nodeBundler?: "none" | "esbuild" | "esbuild_zisi" | "nft" | "zisi" | undefined;
108
+ nodeSourcemap?: boolean | undefined;
109
+ nodeVersion?: string | undefined;
110
+ memory?: number | undefined;
111
+ region?: FunctionRegion | undefined;
112
+ rustTargetDirectory?: string | undefined;
113
+ schedule?: string | undefined;
114
+ timeout?: number | undefined;
115
+ vcpu?: number | undefined;
116
+ zipGo?: boolean | undefined;
117
+ nodeModuleFormat?: "cjs" | "esm" | undefined;
118
+ }, {
119
+ name?: unknown;
120
+ background?: unknown;
121
+ externalNodeModules?: unknown;
122
+ generator?: unknown;
123
+ includedFiles?: unknown;
124
+ includedFilesBasePath?: unknown;
125
+ ignoredNodeModules?: unknown;
126
+ nodeBundler?: unknown;
127
+ nodeSourcemap?: unknown;
128
+ nodeVersion?: unknown;
129
+ memory?: unknown;
130
+ region?: unknown;
131
+ rustTargetDirectory?: unknown;
132
+ schedule?: unknown;
133
+ timeout?: unknown;
134
+ vcpu?: number | undefined;
135
+ zipGo?: unknown;
136
+ nodeModuleFormat?: unknown;
137
+ }>, {
138
+ name?: string | undefined;
139
+ background?: boolean | undefined;
140
+ externalNodeModules?: string[] | undefined;
141
+ generator?: string | undefined;
142
+ includedFiles?: string[] | undefined;
143
+ includedFilesBasePath?: string | undefined;
144
+ ignoredNodeModules?: string[] | undefined;
145
+ nodeBundler?: "none" | "esbuild" | "esbuild_zisi" | "nft" | "zisi" | undefined;
146
+ nodeSourcemap?: boolean | undefined;
147
+ nodeVersion?: string | undefined;
148
+ memory?: number | undefined;
149
+ region?: FunctionRegion | undefined;
150
+ rustTargetDirectory?: string | undefined;
151
+ schedule?: string | undefined;
152
+ timeout?: number | undefined;
153
+ vcpu?: number | undefined;
154
+ zipGo?: boolean | undefined;
155
+ nodeModuleFormat?: "cjs" | "esm" | undefined;
156
+ }, {
157
+ name?: unknown;
158
+ background?: unknown;
159
+ externalNodeModules?: unknown;
160
+ generator?: unknown;
161
+ includedFiles?: unknown;
162
+ includedFilesBasePath?: unknown;
163
+ ignoredNodeModules?: unknown;
164
+ nodeBundler?: unknown;
165
+ nodeSourcemap?: unknown;
166
+ nodeVersion?: unknown;
167
+ memory?: unknown;
168
+ region?: unknown;
169
+ rustTargetDirectory?: unknown;
170
+ schedule?: unknown;
171
+ timeout?: unknown;
172
+ vcpu?: number | undefined;
173
+ zipGo?: unknown;
174
+ nodeModuleFormat?: unknown;
175
+ }>;
176
+ type FunctionConfig = z.infer<typeof functionConfigShape>;
59
177
  type GlobPattern = string;
60
178
  type Config = Record<GlobPattern, FunctionConfig>;
61
179
  type FunctionWithoutConfig = Omit<FunctionSource, 'config'>;
package/dist/config.js CHANGED
@@ -8,7 +8,43 @@ import { z } from 'zod';
8
8
  import { nodeBundler } from './runtimes/node/bundlers/types.js';
9
9
  import { moduleFormat } from './runtimes/node/utils/module_format.js';
10
10
  import { minimatch } from './utils/matching.js';
11
- export const functionConfig = z.object({
11
+ import { parseMemoryMB } from './utils/parse_memory.js';
12
+ // We only need the list of valid region codes here (to feed into Zod's
13
+ // `enum` for runtime validation). The natural shape would be a literal
14
+ // array, but TypeScript has no way to enforce that an array contains every
15
+ // member of a union type — it can only check that each element belongs to
16
+ // the union, not that none are missing.
17
+ //
18
+ // A Record keyed by the union, however, IS exhaustiveness-checked: with
19
+ // `satisfies Record<FunctionRegion, ...>`, TypeScript refuses to compile
20
+ // if any region in `FunctionRegion` is absent here, or if anything here
21
+ // isn't a valid `FunctionRegion`.
22
+ const FUNCTION_REGION_KEYS = {
23
+ cmh: null,
24
+ dub: null,
25
+ fra: null,
26
+ gru: null,
27
+ iad: null,
28
+ lhr: null,
29
+ nrt: null,
30
+ pdx: null,
31
+ sfo: null,
32
+ sin: null,
33
+ syd: null,
34
+ yul: null,
35
+ };
36
+ const FUNCTION_REGION_CODES = Object.keys(FUNCTION_REGION_KEYS);
37
+ // Accept any casing in source (`iad`, `IAD`, `Iad`) but normalize to lower
38
+ // case before validating and writing to the manifest.
39
+ const functionRegion = z.preprocess((input) => (typeof input === 'string' ? input.toLowerCase() : input), z.enum(FUNCTION_REGION_CODES));
40
+ const FUNCTION_MEMORY_MIN_MB = 1024;
41
+ const FUNCTION_MEMORY_MAX_MB = 4096;
42
+ const functionMemory = z.preprocess((input) => (typeof input === 'string' || typeof input === 'number' ? parseMemoryMB(input) : input), z.number().int().min(FUNCTION_MEMORY_MIN_MB).max(FUNCTION_MEMORY_MAX_MB));
43
+ const FUNCTION_VCPU_MIN = 0.5;
44
+ const FUNCTION_VCPU_MAX = 2;
45
+ const functionVcpu = z.number().min(FUNCTION_VCPU_MIN).max(FUNCTION_VCPU_MAX);
46
+ export const functionConfigShape = z.object({
47
+ background: z.boolean().optional().catch(undefined),
12
48
  externalNodeModules: z.array(z.string()).optional().catch([]),
13
49
  generator: z.string().optional().catch(undefined),
14
50
  includedFiles: z.array(z.string()).optional().catch([]),
@@ -18,15 +54,23 @@ export const functionConfig = z.object({
18
54
  nodeBundler: nodeBundler.optional().catch(undefined),
19
55
  nodeSourcemap: z.boolean().optional().catch(undefined),
20
56
  nodeVersion: z.string().optional().catch(undefined),
57
+ memory: functionMemory.optional(),
58
+ region: functionRegion.optional(),
21
59
  rustTargetDirectory: z.string().optional().catch(undefined),
22
60
  schedule: z.string().optional().catch(undefined),
23
61
  timeout: z.number().optional().catch(undefined),
62
+ vcpu: functionVcpu.optional(),
24
63
  zipGo: z.boolean().optional().catch(undefined),
25
64
  // Temporary configuration property, only meant to be used by the deploy
26
65
  // configuration API. Once we start emitting ESM files for all ESM functions,
27
66
  // we can remove this.
28
67
  nodeModuleFormat: moduleFormat.optional().catch(undefined),
29
68
  });
69
+ const refuseMemoryAndVcpu = (cfg) => !(cfg.memory !== undefined && cfg.vcpu !== undefined);
70
+ export const functionConfig = functionConfigShape.refine(refuseMemoryAndVcpu, {
71
+ message: '`memory` and `vcpu` cannot both be set.',
72
+ path: ['vcpu'],
73
+ });
30
74
  const getConfigForFunction = async ({ config, configFileDirectories, func, }) => {
31
75
  const fromConfig = getFromMainConfig({ config, func });
32
76
  // We try to read from a function config file if the function directory is
@@ -11,15 +11,18 @@ interface ManifestFunction {
11
11
  generator?: string;
12
12
  invocationMode?: InvocationMode;
13
13
  mainFile: string;
14
+ memory?: number;
14
15
  name: string;
15
16
  path: string;
16
17
  priority?: number;
18
+ region?: string;
17
19
  routes?: ExtendedRoute[];
18
20
  runtime: string;
19
21
  runtimeVersion?: string;
20
22
  schedule?: string;
21
23
  timeout?: number;
22
24
  trafficRules?: TrafficRules;
25
+ vcpu?: number;
23
26
  }
24
27
  export interface Manifest {
25
28
  functions: ManifestFunction[];
package/dist/manifest.js CHANGED
@@ -12,7 +12,7 @@ export const createManifest = async ({ functions, path }) => {
12
12
  };
13
13
  await fs.writeFile(path, JSON.stringify(payload));
14
14
  };
15
- const formatFunctionForManifest = ({ bootstrapVersion, bundler, displayName, eventSubscriptions, excludedRoutes, generator, invocationMode, mainFile, name, path, priority, trafficRules, routes, runtime, runtimeVersion, runtimeAPIVersion, schedule, timeout, }) => {
15
+ const formatFunctionForManifest = ({ bootstrapVersion, bundler, displayName, eventSubscriptions, excludedRoutes, generator, invocationMode, mainFile, memory, name, path, priority, region, trafficRules, routes, runtime, runtimeVersion, runtimeAPIVersion, schedule, timeout, vcpu, }) => {
16
16
  const manifestFunction = {
17
17
  bundler,
18
18
  displayName,
@@ -21,13 +21,16 @@ const formatFunctionForManifest = ({ bootstrapVersion, bundler, displayName, eve
21
21
  invocationMode,
22
22
  buildData: { bootstrapVersion, runtimeAPIVersion },
23
23
  mainFile,
24
+ memory,
24
25
  name,
25
26
  priority,
27
+ region,
26
28
  trafficRules,
27
29
  runtimeVersion,
28
30
  path: resolve(path),
29
31
  runtime,
30
32
  schedule,
33
+ vcpu,
31
34
  };
32
35
  if (eventSubscriptions?.length) {
33
36
  manifestFunction.eventSubscriptions = eventSubscriptions;
@@ -21,7 +21,8 @@ declare const httpMethod: z.ZodEnum<["GET", "POST", "PUT", "PATCH", "OPTIONS", "
21
21
  declare const httpMethods: z.ZodEffects<z.ZodEnum<["GET", "POST", "PUT", "PATCH", "OPTIONS", "DELETE", "HEAD"]>, "GET" | "POST" | "PUT" | "PATCH" | "OPTIONS" | "DELETE" | "HEAD", unknown>;
22
22
  export type HttpMethod = z.infer<typeof httpMethod>;
23
23
  export type HttpMethods = z.infer<typeof httpMethods>;
24
- export declare const inSourceConfig: z.ZodObject<Pick<{
24
+ export declare const inSourceConfig: z.ZodEffects<z.ZodObject<Pick<{
25
+ background: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
25
26
  externalNodeModules: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
26
27
  generator: z.ZodCatch<z.ZodOptional<z.ZodString>>;
27
28
  includedFiles: z.ZodCatch<z.ZodOptional<z.ZodArray<z.ZodString, "many">>>;
@@ -37,15 +38,18 @@ export declare const inSourceConfig: z.ZodObject<Pick<{
37
38
  }>>>;
38
39
  nodeSourcemap: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
39
40
  nodeVersion: z.ZodCatch<z.ZodOptional<z.ZodString>>;
41
+ memory: z.ZodOptional<z.ZodEffects<z.ZodNumber, number, unknown>>;
42
+ region: z.ZodOptional<z.ZodEffects<z.ZodEnum<[import("@netlify/types").FunctionRegion, ...import("@netlify/types").FunctionRegion[]]>, import("@netlify/types").FunctionRegion, unknown>>;
40
43
  rustTargetDirectory: z.ZodCatch<z.ZodOptional<z.ZodString>>;
41
44
  schedule: z.ZodCatch<z.ZodOptional<z.ZodString>>;
42
45
  timeout: z.ZodCatch<z.ZodOptional<z.ZodNumber>>;
46
+ vcpu: z.ZodOptional<z.ZodNumber>;
43
47
  zipGo: z.ZodCatch<z.ZodOptional<z.ZodBoolean>>;
44
48
  nodeModuleFormat: z.ZodCatch<z.ZodOptional<z.ZodNativeEnum<{
45
49
  readonly COMMONJS: "cjs";
46
50
  readonly ESM: "esm";
47
51
  }>>>;
48
- }, "name" | "externalNodeModules" | "generator" | "includedFiles" | "ignoredNodeModules" | "nodeBundler" | "nodeVersion" | "schedule" | "timeout"> & {
52
+ }, "name" | "background" | "externalNodeModules" | "generator" | "includedFiles" | "ignoredNodeModules" | "nodeBundler" | "nodeVersion" | "memory" | "region" | "schedule" | "timeout" | "vcpu"> & {
49
53
  method: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodEffects<z.ZodEnum<["GET", "POST", "PUT", "PATCH", "OPTIONS", "DELETE", "HEAD"]>, "GET" | "POST" | "PUT" | "PATCH" | "OPTIONS" | "DELETE" | "HEAD", unknown>, z.ZodArray<z.ZodEffects<z.ZodEnum<["GET", "POST", "PUT", "PATCH", "OPTIONS", "DELETE", "HEAD"]>, "GET" | "POST" | "PUT" | "PATCH" | "OPTIONS" | "DELETE" | "HEAD", unknown>, "many">]>, ("GET" | "POST" | "PUT" | "PATCH" | "OPTIONS" | "DELETE" | "HEAD")[], unknown>>;
50
54
  path: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, string[], string | string[]>>;
51
55
  excludedPath: z.ZodOptional<z.ZodEffects<z.ZodUnion<[z.ZodString, z.ZodArray<z.ZodString, "many">]>, string[], string | string[]>>;
@@ -77,14 +81,18 @@ export declare const inSourceConfig: z.ZodObject<Pick<{
77
81
  }, "strip", z.ZodTypeAny, {
78
82
  name?: string | undefined;
79
83
  path?: string[] | undefined;
84
+ background?: boolean | undefined;
80
85
  externalNodeModules?: string[] | undefined;
81
86
  generator?: string | undefined;
82
87
  includedFiles?: string[] | undefined;
83
88
  ignoredNodeModules?: string[] | undefined;
84
89
  nodeBundler?: "none" | "esbuild" | "esbuild_zisi" | "nft" | "zisi" | undefined;
85
90
  nodeVersion?: string | undefined;
91
+ memory?: number | undefined;
92
+ region?: import("@netlify/types").FunctionRegion | undefined;
86
93
  schedule?: string | undefined;
87
94
  timeout?: number | undefined;
95
+ vcpu?: number | undefined;
88
96
  method?: ("GET" | "POST" | "PUT" | "PATCH" | "OPTIONS" | "DELETE" | "HEAD")[] | undefined;
89
97
  excludedPath?: string[] | undefined;
90
98
  preferStatic?: boolean | undefined;
@@ -99,14 +107,63 @@ export declare const inSourceConfig: z.ZodObject<Pick<{
99
107
  }, {
100
108
  name?: unknown;
101
109
  path?: string | string[] | undefined;
110
+ background?: unknown;
102
111
  externalNodeModules?: unknown;
103
112
  generator?: unknown;
104
113
  includedFiles?: unknown;
105
114
  ignoredNodeModules?: unknown;
106
115
  nodeBundler?: unknown;
107
116
  nodeVersion?: unknown;
117
+ memory?: unknown;
118
+ region?: unknown;
108
119
  schedule?: unknown;
109
120
  timeout?: unknown;
121
+ vcpu?: number | undefined;
122
+ method?: unknown;
123
+ excludedPath?: string | string[] | undefined;
124
+ preferStatic?: unknown;
125
+ rateLimit?: unknown;
126
+ }>, {
127
+ name?: string | undefined;
128
+ path?: string[] | undefined;
129
+ background?: boolean | undefined;
130
+ externalNodeModules?: string[] | undefined;
131
+ generator?: string | undefined;
132
+ includedFiles?: string[] | undefined;
133
+ ignoredNodeModules?: string[] | undefined;
134
+ nodeBundler?: "none" | "esbuild" | "esbuild_zisi" | "nft" | "zisi" | undefined;
135
+ nodeVersion?: string | undefined;
136
+ memory?: number | undefined;
137
+ region?: import("@netlify/types").FunctionRegion | undefined;
138
+ schedule?: string | undefined;
139
+ timeout?: number | undefined;
140
+ vcpu?: number | undefined;
141
+ method?: ("GET" | "POST" | "PUT" | "PATCH" | "OPTIONS" | "DELETE" | "HEAD")[] | undefined;
142
+ excludedPath?: string[] | undefined;
143
+ preferStatic?: boolean | undefined;
144
+ rateLimit?: {
145
+ windowLimit: number;
146
+ windowSize: number;
147
+ to?: string | undefined;
148
+ action?: "rate_limit" | "rewrite" | undefined;
149
+ aggregateBy?: "domain" | "ip" | ("domain" | "ip")[] | undefined;
150
+ algorithm?: "sliding_window" | undefined;
151
+ } | undefined;
152
+ }, {
153
+ name?: unknown;
154
+ path?: string | string[] | undefined;
155
+ background?: unknown;
156
+ externalNodeModules?: unknown;
157
+ generator?: unknown;
158
+ includedFiles?: unknown;
159
+ ignoredNodeModules?: unknown;
160
+ nodeBundler?: unknown;
161
+ nodeVersion?: unknown;
162
+ memory?: unknown;
163
+ region?: unknown;
164
+ schedule?: unknown;
165
+ timeout?: unknown;
166
+ vcpu?: number | undefined;
110
167
  method?: unknown;
111
168
  excludedPath?: string | string[] | undefined;
112
169
  preferStatic?: unknown;
@@ -126,6 +183,7 @@ export declare const parseFile: (sourcePath: string, { functionName }: FindISCDe
126
183
  export declare const parseSource: (source: string, { functionName }: FindISCDeclarationsOptions) => StaticAnalysisResult;
127
184
  export declare const augmentFunctionConfig: (mainFile: string, tomlConfig: FunctionConfig, inSourceConfig?: InSourceConfig) => {
128
185
  name?: string | undefined;
186
+ background?: boolean | undefined;
129
187
  externalNodeModules?: string[] | undefined;
130
188
  generator?: string | undefined;
131
189
  includedFiles?: string[] | undefined;
@@ -134,22 +192,29 @@ export declare const augmentFunctionConfig: (mainFile: string, tomlConfig: Funct
134
192
  nodeBundler?: "none" | "esbuild" | "esbuild_zisi" | "nft" | "zisi" | undefined;
135
193
  nodeSourcemap?: boolean | undefined;
136
194
  nodeVersion?: string | undefined;
195
+ memory?: number | undefined;
196
+ region?: import("@netlify/types").FunctionRegion | undefined;
137
197
  rustTargetDirectory?: string | undefined;
138
198
  schedule?: string | undefined;
139
199
  timeout?: number | undefined;
200
+ vcpu?: number | undefined;
140
201
  zipGo?: boolean | undefined;
141
202
  nodeModuleFormat?: "cjs" | "esm" | undefined;
142
203
  } & {
143
204
  name?: string | undefined;
144
205
  path?: string[] | undefined;
206
+ background?: boolean | undefined;
145
207
  externalNodeModules?: string[] | undefined;
146
208
  generator?: string | undefined;
147
209
  includedFiles?: string[] | undefined;
148
210
  ignoredNodeModules?: string[] | undefined;
149
211
  nodeBundler?: "none" | "esbuild" | "esbuild_zisi" | "nft" | "zisi" | undefined;
150
212
  nodeVersion?: string | undefined;
213
+ memory?: number | undefined;
214
+ region?: import("@netlify/types").FunctionRegion | undefined;
151
215
  schedule?: string | undefined;
152
216
  timeout?: number | undefined;
217
+ vcpu?: number | undefined;
153
218
  method?: ("GET" | "POST" | "PUT" | "PATCH" | "OPTIONS" | "DELETE" | "HEAD")[] | undefined;
154
219
  excludedPath?: string[] | undefined;
155
220
  preferStatic?: boolean | undefined;
@@ -3,7 +3,7 @@ import { dirname } from 'path';
3
3
  // this dependency.
4
4
  import mergeOptions from 'merge-options';
5
5
  import { z } from 'zod';
6
- import { functionConfig } from '../../../config.js';
6
+ import { functionConfigShape } from '../../../config.js';
7
7
  import { INVOCATION_MODE } from '../../../function.js';
8
8
  import { rateLimit } from '../../../rate_limit.js';
9
9
  import { ensureArray } from '../../../utils/ensure_array.js';
@@ -20,17 +20,21 @@ export const IN_SOURCE_CONFIG_MODULE = '@netlify/functions';
20
20
  const httpMethod = z.enum(['GET', 'POST', 'PUT', 'PATCH', 'OPTIONS', 'DELETE', 'HEAD']);
21
21
  const httpMethods = z.preprocess((input) => (typeof input === 'string' ? input.toUpperCase() : input), httpMethod);
22
22
  const path = z.string().startsWith('/', { message: "Must start with a '/'" });
23
- export const inSourceConfig = functionConfig
23
+ export const inSourceConfig = functionConfigShape
24
24
  .pick({
25
+ background: true,
25
26
  externalNodeModules: true,
26
27
  generator: true,
27
28
  includedFiles: true,
28
29
  ignoredNodeModules: true,
30
+ memory: true,
29
31
  name: true,
30
32
  nodeBundler: true,
31
33
  nodeVersion: true,
34
+ region: true,
32
35
  schedule: true,
33
36
  timeout: true,
37
+ vcpu: true,
34
38
  })
35
39
  .extend({
36
40
  method: z
@@ -49,6 +53,10 @@ export const inSourceConfig = functionConfig
49
53
  .optional(),
50
54
  preferStatic: z.boolean().optional().catch(undefined),
51
55
  rateLimit: rateLimit.optional().catch(undefined),
56
+ })
57
+ .refine((cfg) => !(cfg.memory !== undefined && cfg.vcpu !== undefined), {
58
+ message: '`memory` and `vcpu` cannot both be set.',
59
+ path: ['vcpu'],
52
60
  });
53
61
  /**
54
62
  * Extracts event subscription slugs from the default export expression,
@@ -140,6 +148,9 @@ export const parseSource = (source, { functionName }) => {
140
148
  methods: data.method ?? [],
141
149
  prefer_static: data.preferStatic || undefined,
142
150
  }));
151
+ if (data.background) {
152
+ result.invocationMode = INVOCATION_MODE.Background;
153
+ }
143
154
  }
144
155
  else {
145
156
  // TODO: Handle multiple errors.
@@ -106,14 +106,16 @@ const zipFunction = async function ({ archiveFormat, basePath, branch, cache, co
106
106
  // Getting the invocation mode from ISC, in case the function is using the
107
107
  // `stream` helper.
108
108
  let { invocationMode } = staticAnalysisResult;
109
- // If we're using the V2 API, force the invocation to "stream".
110
- if (runtimeAPIVersion === 2) {
111
- invocationMode = INVOCATION_MODE.Stream;
112
- }
113
- // If this is a background function, set the right `invocationMode` value.
109
+ // If this is a background function (filename suffix), set the right
110
+ // `invocationMode` value.
114
111
  if (name.endsWith('-background')) {
115
112
  invocationMode = INVOCATION_MODE.Background;
116
113
  }
114
+ // V2 functions default to streamed invocation unless they were already
115
+ // marked as background (via filename suffix or `config.background: true`).
116
+ if (runtimeAPIVersion === 2 && invocationMode !== INVOCATION_MODE.Background) {
117
+ invocationMode = INVOCATION_MODE.Stream;
118
+ }
117
119
  const outputModuleFormat = extname(finalMainFile) === MODULE_FILE_EXTENSION.MJS ? MODULE_FORMAT.ESM : MODULE_FORMAT.COMMONJS;
118
120
  const priority = isInternal ? Priority.GeneratedFunction : Priority.UserFunction;
119
121
  const trafficRules = mergedConfig?.rateLimit ? getTrafficRulesConfig(mergedConfig.rateLimit) : undefined;
@@ -4,10 +4,13 @@ import type { ExtendedRoute, Route } from './routes.js';
4
4
  export type FunctionResult = Omit<FunctionArchive, 'runtime'> & {
5
5
  bootstrapVersion?: string;
6
6
  eventSubscriptions?: string[];
7
+ memory?: number;
8
+ region?: string;
7
9
  routes?: ExtendedRoute[];
8
10
  excludedRoutes?: Route[];
9
11
  runtime: RuntimeName;
10
12
  schedule?: string;
11
13
  runtimeAPIVersion?: number;
14
+ vcpu?: number;
12
15
  };
13
16
  export declare const formatZipResult: (archive: FunctionArchive) => FunctionResult;
@@ -1,6 +1,8 @@
1
1
  import { removeUndefined } from './remove_undefined.js';
2
2
  // Takes the result of zipping a function and formats it for output.
3
3
  export const formatZipResult = (archive) => {
4
+ const memory = archive.staticAnalysisResult?.config?.memory ?? archive?.config?.memory;
5
+ const vcpu = archive.staticAnalysisResult?.config?.vcpu ?? archive?.config?.vcpu;
4
6
  const functionResult = {
5
7
  ...archive,
6
8
  staticAnalysisResult: undefined,
@@ -8,8 +10,11 @@ export const formatZipResult = (archive) => {
8
10
  routes: archive.staticAnalysisResult?.routes,
9
11
  excludedRoutes: archive.staticAnalysisResult?.excludedRoutes,
10
12
  runtime: archive.runtime.name,
13
+ memory,
14
+ region: archive.staticAnalysisResult?.config?.region ?? archive?.config?.region,
11
15
  schedule: archive.staticAnalysisResult?.config?.schedule ?? archive?.config?.schedule,
12
16
  runtimeAPIVersion: archive.staticAnalysisResult?.runtimeAPIVersion,
17
+ vcpu,
13
18
  };
14
19
  return removeUndefined(functionResult);
15
20
  };
@@ -0,0 +1 @@
1
+ export declare const parseMemoryMB: (input: number | string) => number;
@@ -0,0 +1,17 @@
1
+ const MEMORY_UNIT_TO_MB = { mb: 1, gb: 1024 };
2
+ const MEMORY_PATTERN = /^(\d+(?:\.\d+)?)\s*(mb|gb)?$/;
3
+ // Accepts a bare number (interpreted as MB), a numeric string (`"2048"`), or
4
+ // a human-friendly size with a unit (`"2gb"`, `"1024mb"`, case-insensitive).
5
+ // Returns a normalized integer megabyte count.
6
+ export const parseMemoryMB = (input) => {
7
+ if (typeof input === 'number') {
8
+ return input;
9
+ }
10
+ const match = MEMORY_PATTERN.exec(input.trim().toLowerCase());
11
+ if (!match) {
12
+ return Number.NaN;
13
+ }
14
+ const value = parseFloat(match[1]);
15
+ const unit = match[2] || 'mb';
16
+ return value * MEMORY_UNIT_TO_MB[unit];
17
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@netlify/zip-it-and-ship-it",
3
- "version": "14.5.5",
3
+ "version": "14.6.0",
4
4
  "description": "Zip it and ship it",
5
5
  "main": "./dist/main.js",
6
6
  "type": "module",
@@ -44,13 +44,13 @@
44
44
  "@babel/parser": "^7.22.5",
45
45
  "@babel/types": "^7.28.5",
46
46
  "@netlify/binary-info": "^1.0.0",
47
- "@netlify/serverless-functions-api": "2.15.1",
47
+ "@netlify/serverless-functions-api": "2.16.0",
48
48
  "@vercel/nft": "0.29.4",
49
49
  "archiver": "^7.0.0",
50
50
  "common-path-prefix": "^3.0.0",
51
51
  "copy-file": "^11.0.0",
52
52
  "es-module-lexer": "^1.0.0",
53
- "esbuild": "0.27.3",
53
+ "esbuild": "0.28.0",
54
54
  "execa": "^8.0.0",
55
55
  "fast-glob": "^3.3.3",
56
56
  "filter-obj": "^6.0.0",
@@ -75,6 +75,7 @@
75
75
  "zod": "^3.23.8"
76
76
  },
77
77
  "devDependencies": {
78
+ "@netlify/types": "2.7.0",
78
79
  "@types/archiver": "6.0.4",
79
80
  "@types/is-ci": "3.0.4",
80
81
  "@types/node": "20.19.33",
@@ -99,5 +100,5 @@
99
100
  "engines": {
100
101
  "node": ">=18.14.0"
101
102
  },
102
- "gitHead": "7869bcb26c738222edeb98cadd50f5a488f6c9aa"
103
+ "gitHead": "b41ec05a2415f75122ef97422bf6d0ba3cd3ed63"
103
104
  }