@gigadrive/network-config 2.0.4 → 2.1.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/index.mjs CHANGED
@@ -18,22 +18,98 @@ import addFormats from "ajv-formats";
18
18
 
19
19
  // src/build-output-v3/parse.ts
20
20
  import { getFilesForPattern } from "@gigadrive/build-utils";
21
- import fs3 from "fs";
21
+ import { deepMerge } from "@gigadrive/commons";
22
+ import path5 from "path";
23
+
24
+ // src/build-output-v3/determine-repo-root.ts
25
+ import path2 from "path";
26
+ var determineRepoRoot = (projectFolder, config) => {
27
+ if (!config.entrypoints?.length) {
28
+ return projectFolder;
29
+ }
30
+ const filePaths = [];
31
+ for (const entrypoint of config.entrypoints) {
32
+ if (entrypoint.package?.filePathMap) {
33
+ filePaths.push(...Object.keys(entrypoint.package.filePathMap));
34
+ }
35
+ }
36
+ if (filePaths.length === 0) {
37
+ return projectFolder;
38
+ }
39
+ const pathParts = filePaths.map((p) => p.split(path2.sep));
40
+ const firstPath = pathParts[0];
41
+ let commonParts = [];
42
+ for (let i = 0; i < firstPath.length; i++) {
43
+ const part = firstPath[i];
44
+ if (pathParts.every((parts) => parts[i] === part)) {
45
+ commonParts.push(part);
46
+ } else {
47
+ break;
48
+ }
49
+ }
50
+ const commonRoot = commonParts.join(path2.sep);
51
+ if (commonRoot && projectFolder.startsWith(commonRoot) && commonRoot !== projectFolder) {
52
+ return commonRoot;
53
+ }
54
+ return projectFolder;
55
+ };
56
+
57
+ // src/build-output-v3/get-default-path-map.ts
58
+ import fs2 from "fs";
22
59
  import path3 from "path";
60
+ var getDefaultPathMap = (directory) => {
61
+ const result = {};
62
+ if (!fs2.existsSync(directory)) {
63
+ return result;
64
+ }
65
+ const processDirectory = (currentPath, basePath = "") => {
66
+ const files = fs2.readdirSync(currentPath, { withFileTypes: true });
67
+ for (const file of files) {
68
+ const fullPath = path3.join(currentPath, file.name);
69
+ const relativePath = path3.join(basePath, file.name);
70
+ if (file.isDirectory()) {
71
+ processDirectory(fullPath, relativePath);
72
+ } else {
73
+ result[fullPath] = relativePath;
74
+ }
75
+ }
76
+ };
77
+ processDirectory(directory);
78
+ return result;
79
+ };
80
+
81
+ // src/build-output-v3/get-monorepo-files.ts
82
+ function getMonorepoFiles(directory, filePathMaps) {
83
+ const result = [];
84
+ for (const filePathMap of filePathMaps ?? []) {
85
+ if (!filePathMap) {
86
+ continue;
87
+ }
88
+ for (const file of Object.keys(filePathMap)) {
89
+ if (!file.startsWith(directory)) {
90
+ result.push(file);
91
+ }
92
+ }
93
+ }
94
+ return result;
95
+ }
96
+
97
+ // src/build-output-v3/read-config-file.ts
98
+ import fs4 from "fs";
23
99
 
24
100
  // src/parse-raw-config.ts
25
- import fs2 from "fs";
26
- import path2 from "path";
101
+ import fs3 from "fs";
102
+ import path4 from "path";
27
103
  import { parse as parseYaml } from "yaml";
28
104
  var parseRawConfig = async (filePath, { disableVersionCheck = false } = {}) => {
29
- if (!fs2.existsSync(filePath)) {
105
+ if (!fs3.existsSync(filePath)) {
30
106
  throw new Error(`Config file not found at ${filePath}`);
31
107
  }
32
- const fileContents = fs2.readFileSync(filePath, "utf8");
108
+ const fileContents = fs3.readFileSync(filePath, "utf8");
33
109
  if (fileContents.length === 0) {
34
110
  throw new Error(`Config file is empty at ${filePath}`);
35
111
  }
36
- const fileExtension = path2.extname(filePath).toLowerCase();
112
+ const fileExtension = path4.extname(filePath).toLowerCase();
37
113
  let parsed;
38
114
  try {
39
115
  if (fileExtension === ".json") {
@@ -57,150 +133,176 @@ var parseRawConfig = async (filePath, { disableVersionCheck = false } = {}) => {
57
133
  return parsed;
58
134
  };
59
135
 
136
+ // src/build-output-v3/read-config-file.ts
137
+ var readConfigFile = async (configFilePath) => {
138
+ if (!fs4.existsSync(configFilePath)) {
139
+ return null;
140
+ }
141
+ const parsed = await parseRawConfig(configFilePath, { disableVersionCheck: true });
142
+ return parsed;
143
+ };
144
+
145
+ // src/build-output-v3/translate-vercel-region.ts
146
+ var translateVercelRegion = (region) => {
147
+ const regionMap = {
148
+ arn1: "eu-north-1",
149
+ bom1: "ap-south-1",
150
+ cdg1: "eu-west-3",
151
+ cle1: "us-east-2",
152
+ cpt1: "af-south-1",
153
+ dub1: "eu-west-1",
154
+ fra1: "eu-central-1",
155
+ gru1: "sa-east-1",
156
+ hkg1: "ap-east-1",
157
+ hnd1: "ap-northeast-1",
158
+ iad1: "us-east-1",
159
+ icn1: "ap-northeast-2",
160
+ kix1: "ap-northeast-3",
161
+ lhr1: "eu-west-2",
162
+ pdx1: "us-west-2",
163
+ sfo1: "us-west-1",
164
+ sin1: "ap-southeast-1",
165
+ syd1: "ap-southeast-2"
166
+ };
167
+ return regionMap[region.toLowerCase()] ?? "us-east-1";
168
+ };
169
+
170
+ // src/build-output-v3/translate-vercel-runtime.ts
171
+ var translateVercelRuntime = (runtime) => {
172
+ switch (runtime) {
173
+ case "nodejs12.x":
174
+ case "nodejs14.x":
175
+ case "nodejs16.x":
176
+ case "nodejs18.x":
177
+ return "node-18";
178
+ case "nodejs20.x":
179
+ case "nodejs22.x":
180
+ return "node-20";
181
+ default:
182
+ return null;
183
+ }
184
+ };
185
+
60
186
  // src/build-output-v3/parse.ts
61
187
  var configPath = ".vercel/output/config.json";
62
- var functionConfigsPattern = ".vercel/output/functions/*.func/.vc-config.json";
188
+ var functionsFolder = ".vercel/output/functions";
189
+ var functionConfigsPattern = `${functionsFolder}/**/*.func/.vc-config.json`;
63
190
  var parseVercelBuildOutputV3 = async (parseResult, projectFolder) => {
64
- const config = await readConfigFile(path3.join(projectFolder, configPath));
191
+ const config = await readConfigFile(path5.join(projectFolder, configPath));
65
192
  if (!config || config.version < 3) {
66
193
  return parseResult;
67
194
  }
68
- await loadFunctions(config, parseResult, projectFolder);
69
- await loadAssetOverrides(config, parseResult);
70
- return parseResult;
195
+ const functionData = await loadFunctions(config, parseResult, projectFolder);
196
+ const assetOverrides = await loadAssetOverrides(config, parseResult);
197
+ return deepMerge(parseResult, functionData, assetOverrides);
71
198
  };
72
199
  var loadAssetOverrides = async (config, parseResult) => {
73
- if (!parseResult.assets) {
74
- parseResult.assets = {
75
- paths: [],
76
- prefixToStrip: ""
77
- };
78
- }
79
- parseResult.assets.overrides = {
80
- ...parseResult.assets.overrides ?? {},
81
- ...config.overrides
200
+ return {
201
+ assets: {
202
+ overrides: {
203
+ ...parseResult.assets?.overrides ?? {},
204
+ ...config.overrides
205
+ }
206
+ }
82
207
  };
83
208
  };
84
209
  var loadFunctions = async (config, parseResult, projectFolder) => {
85
210
  const functionConfigs = await getFilesForPattern(functionConfigsPattern, projectFolder);
211
+ const result = {
212
+ entrypoints: [],
213
+ routes: [],
214
+ regions: []
215
+ };
86
216
  for (const functionConfigPath of functionConfigs) {
87
- const functionConfig = await readConfigFile(path3.join(projectFolder, functionConfigPath));
217
+ const functionConfig = await readConfigFile(path5.join(projectFolder, functionConfigPath));
88
218
  if (!functionConfig) {
89
219
  parseResult.errors.push(`Failed to read function config at ${functionConfigPath}`);
90
220
  continue;
91
221
  }
92
- const functionName = path3.basename(path3.dirname(functionConfigPath)).replace(/\.func$/, "");
222
+ const functionPathRelative = path5.dirname(functionConfigPath).replace(functionsFolder, "");
223
+ const functionName = functionPathRelative.replace(/^\/|\.func$/g, "");
93
224
  const runtime = translateVercelRuntime(functionConfig.runtime);
94
225
  if (!runtime) {
95
226
  parseResult.errors.push(`Unsupported runtime for function ${functionName}: ${functionConfig.runtime}`);
96
227
  continue;
97
228
  }
98
229
  const functionDirectory = `.vercel/output/functions/${functionName}.func`;
99
- const handler = functionConfig.handler;
100
- const maxDuration = functionConfig.maxDuration;
101
- const memory = functionConfig.memory;
102
- parseResult.regions = Array.from(
103
- /* @__PURE__ */ new Set([
104
- ...parseResult.regions ?? [],
105
- ...(functionConfig.regions ?? ["us-east-1"]).map((r) => translateVercelRegion(r))
106
- ])
107
- );
230
+ const {
231
+ handler,
232
+ maxDuration,
233
+ memory,
234
+ regions = [],
235
+ environment,
236
+ filePathMap: configFilePathMap = {}
237
+ } = functionConfig;
238
+ const translatedRegions = regions.length > 0 ? regions.map(translateVercelRegion) : ["us-east-1"];
239
+ result.regions = Array.from(/* @__PURE__ */ new Set([...parseResult.regions, ...translatedRegions]));
108
240
  const environmentVariables = {};
109
- const functionEnv = functionConfig.environment;
110
- if (functionEnv != null && typeof functionEnv === "object") {
111
- for (const env of Object.values(functionEnv)) {
112
- for (const [key, value] of Object.entries(env)) {
113
- environmentVariables[key] = value;
114
- }
241
+ if (environment && typeof environment === "object") {
242
+ for (const env of Object.values(environment)) {
243
+ Object.assign(environmentVariables, env);
115
244
  }
116
245
  }
117
- const streaming = runtime == null || runtime.startsWith("node-") || runtime.startsWith("bun-");
118
- const filePathMap = {};
119
- for (const [key, value] of Object.entries(functionConfig.filePathMap ?? {})) {
120
- filePathMap[path3.join(projectFolder, key)] = value;
246
+ const streaming = runtime.startsWith("node-") || runtime.startsWith("bun-");
247
+ let filePathMap = {};
248
+ for (const [key, value] of Object.entries(configFilePathMap)) {
249
+ filePathMap[path5.join(projectFolder, key)] = value;
250
+ }
251
+ if (Object.keys(filePathMap).length === 0) {
252
+ filePathMap = getDefaultPathMap(path5.join(projectFolder, functionDirectory));
121
253
  }
122
- parseResult.entrypoints.push({
254
+ if (!result.entrypoints) {
255
+ result.entrypoints = [];
256
+ }
257
+ result.entrypoints.push({
123
258
  displayName: functionName,
124
259
  runtime,
125
- path: handler,
260
+ path: path5.join(functionDirectory, handler),
126
261
  memory: memory ?? 1024,
127
262
  maxDuration: maxDuration ?? 15,
128
263
  environmentVariables,
129
264
  streaming,
130
265
  package: {
131
- rootOverwrite: path3.join(projectFolder, functionDirectory),
132
266
  filePathMap
133
267
  }
134
268
  });
135
269
  const handlerType = streaming ? "SERVERLESS_FUNCTION_STREAMING" : "SERVERLESS_FUNCTION";
136
- [
137
- {
138
- path: `/${functionName}`,
139
- methods: ["ANY"],
140
- headers: {},
141
- destination: handler,
142
- handler: handlerType
143
- },
144
- ...config.routes?.filter((r) => r.dest === `/${functionName}`).map((r) => ({
270
+ const defaultRoute = {
271
+ path: `/${functionName}`,
272
+ methods: ["ANY"],
273
+ headers: {},
274
+ destination: handler,
275
+ handler: handlerType
276
+ };
277
+ const configRoutes = config.routes?.filter((r) => r.dest === `/${functionName}`).map(
278
+ (r) => ({
145
279
  path: r.src ?? `/${functionName}`,
146
280
  methods: ["ANY"],
147
281
  headers: {},
148
282
  destination: handler,
149
283
  handler: handlerType
150
- })) ?? []
151
- ].forEach((route) => {
152
- parseResult.routes.push(route);
153
- });
154
- }
155
- };
156
- var readConfigFile = async (configFilePath) => {
157
- if (!fs3.existsSync(configFilePath)) {
158
- return null;
159
- }
160
- const parsed = await parseRawConfig(configFilePath, { disableVersionCheck: true });
161
- return parsed;
162
- };
163
- var translateVercelRuntime = (runtime) => {
164
- switch (runtime) {
165
- case "nodejs12.x":
166
- case "nodejs14.x":
167
- case "nodejs16.x":
168
- case "nodejs18.x":
169
- return "node-18";
170
- case "nodejs20.x":
171
- case "nodejs22.x":
172
- return "node-20";
173
- default:
174
- return null;
284
+ })
285
+ ) ?? [];
286
+ if (!result.routes) {
287
+ result.routes = [];
288
+ }
289
+ result.routes.push(defaultRoute, ...configRoutes);
175
290
  }
176
- };
177
- var translateVercelRegion = (region) => {
178
- const regionMap = {
179
- arn1: "eu-north-1",
180
- bom1: "ap-south-1",
181
- cdg1: "eu-west-3",
182
- cle1: "us-east-2",
183
- cpt1: "af-south-1",
184
- dub1: "eu-west-1",
185
- fra1: "eu-central-1",
186
- gru1: "sa-east-1",
187
- hkg1: "ap-east-1",
188
- hnd1: "ap-northeast-1",
189
- iad1: "us-east-1",
190
- icn1: "ap-northeast-2",
191
- kix1: "ap-northeast-3",
192
- lhr1: "eu-west-2",
193
- pdx1: "us-west-2",
194
- sfo1: "us-west-1",
195
- sin1: "ap-southeast-1",
196
- syd1: "ap-southeast-2"
291
+ return {
292
+ ...result,
293
+ userArchive: {
294
+ rootOverwrite: determineRepoRoot(projectFolder, result),
295
+ fileWhitelist: [
296
+ `${projectFolder}/*`,
297
+ ...getMonorepoFiles(projectFolder, result.entrypoints?.map((e) => e.package?.filePathMap ?? {}) ?? [])
298
+ ]
299
+ }
197
300
  };
198
- return regionMap[region.toLowerCase()] ?? "us-east-1";
199
301
  };
200
302
 
201
303
  // src/v4/parse.ts
202
304
  import { getFilesForPattern as getFilesForPattern2 } from "@gigadrive/build-utils";
203
- import fs4 from "fs";
305
+ import fs5 from "fs";
204
306
  import { minimatch } from "minimatch";
205
307
 
206
308
  // src/regions.ts
@@ -235,16 +337,16 @@ var parseConfigV4 = async (config, projectFolder) => {
235
337
  const errors = [];
236
338
  const warnings = [];
237
339
  if (config.functions != null) {
238
- for (const [path4, func] of Object.entries(config.functions)) {
239
- const settings = getFunctionSettings(path4, config);
340
+ for (const [path6, func] of Object.entries(config.functions)) {
341
+ const settings = getFunctionSettings(path6, config);
240
342
  if (settings == null) {
241
- throw new Error(`Settings invalid for function at path '${path4}'`);
343
+ throw new Error(`Settings invalid for function at path '${path6}'`);
242
344
  }
243
- (await getFilesForPattern2(path4, projectFolder, func.excludeFiles)).forEach((file) => {
345
+ (await getFilesForPattern2(path6, projectFolder, func.excludeFiles)).forEach((file) => {
244
346
  if (entrypoints.find((entrypoint) => entrypoint.path === file)) {
245
347
  return;
246
348
  }
247
- if (config.functions != null && Object.keys(config.functions).find((func2) => func2 === file && func2 !== path4)) {
349
+ if (config.functions != null && Object.keys(config.functions).find((func2) => func2 === file && func2 !== path6)) {
248
350
  return;
249
351
  }
250
352
  entrypoints.push({
@@ -262,11 +364,11 @@ var parseConfigV4 = async (config, projectFolder) => {
262
364
  const assets = [];
263
365
  if (config.assets != null) {
264
366
  const assetsPath = `${projectFolder}/${config.assets}`;
265
- if (fs4.existsSync(assetsPath) && fs4.statSync(assetsPath).isDirectory()) {
266
- for (const asset of fs4.readdirSync(`${projectFolder}/${config.assets}`, {
367
+ if (fs5.existsSync(assetsPath) && fs5.statSync(assetsPath).isDirectory()) {
368
+ for (const asset of fs5.readdirSync(`${projectFolder}/${config.assets}`, {
267
369
  recursive: true
268
370
  })) {
269
- if (fs4.statSync(`${projectFolder}/${config.assets}/${asset}`).isDirectory()) {
371
+ if (fs5.statSync(`${projectFolder}/${config.assets}/${asset}`).isDirectory()) {
270
372
  continue;
271
373
  }
272
374
  const disallowedExtensions = [".htaccess", ".htpasswd"];
@@ -307,10 +409,10 @@ var parseConfigV4 = async (config, projectFolder) => {
307
409
  })
308
410
  };
309
411
  };
310
- var getFunctionSettings = (path4, config) => {
412
+ var getFunctionSettings = (path6, config) => {
311
413
  let functionSettings;
312
414
  for (const [key, value] of Object.entries(config.functions ?? {})) {
313
- if (minimatch(path4, key) || new RegExp(key).test(path4)) {
415
+ if (minimatch(path6, key) || new RegExp(key).test(path6)) {
314
416
  if (functionSettings == null) {
315
417
  functionSettings = {
316
418
  memory: 128,