@easel-sh/cli 0.1.0-alpha.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/cli.d.ts +3 -0
- package/dist/cli.d.ts.map +1 -0
- package/dist/cli.js +195 -0
- package/dist/cli.js.map +1 -0
- package/dist/commands/create-lambda-gateway.d.ts +11 -0
- package/dist/commands/create-lambda-gateway.d.ts.map +1 -0
- package/dist/commands/create-lambda-gateway.js +409 -0
- package/dist/commands/create-lambda-gateway.js.map +1 -0
- package/dist/commands/generate-manifest.d.ts +7 -0
- package/dist/commands/generate-manifest.d.ts.map +1 -0
- package/dist/commands/generate-manifest.js +145 -0
- package/dist/commands/generate-manifest.js.map +1 -0
- package/dist/commands/list-functions.d.ts +7 -0
- package/dist/commands/list-functions.d.ts.map +1 -0
- package/dist/commands/list-functions.js +140 -0
- package/dist/commands/list-functions.js.map +1 -0
- package/dist/commands/package-functions.d.ts +9 -0
- package/dist/commands/package-functions.d.ts.map +1 -0
- package/dist/commands/package-functions.js +292 -0
- package/dist/commands/package-functions.js.map +1 -0
- package/dist/commands/upload-manifest.d.ts +7 -0
- package/dist/commands/upload-manifest.d.ts.map +1 -0
- package/dist/commands/upload-manifest.js +53 -0
- package/dist/commands/upload-manifest.js.map +1 -0
- package/dist/commands/upload-static.d.ts +7 -0
- package/dist/commands/upload-static.d.ts.map +1 -0
- package/dist/commands/upload-static.js +142 -0
- package/dist/commands/upload-static.js.map +1 -0
- package/dist/utils/types.d.ts +38 -0
- package/dist/utils/types.d.ts.map +1 -0
- package/dist/utils/types.js +2 -0
- package/dist/utils/types.js.map +1 -0
- package/dist/utils/vercel-config.d.ts +60 -0
- package/dist/utils/vercel-config.d.ts.map +1 -0
- package/dist/utils/vercel-config.js +121 -0
- package/dist/utils/vercel-config.js.map +1 -0
- package/dist/utils.d.ts +31 -0
- package/dist/utils.d.ts.map +1 -0
- package/dist/utils.js +263 -0
- package/dist/utils.js.map +1 -0
- package/package.json +26 -0
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { parseVercelConfig, buildFileManifest, parseOverrides, } from "../utils/vercel-config.js";
|
|
4
|
+
import { scanFunctions, resolveVercelOutputDir } from "../utils.js";
|
|
5
|
+
export function generateManifest(options) {
|
|
6
|
+
const { vercelOutputDir, output, hostname } = options;
|
|
7
|
+
// Resolve base Vercel output directory
|
|
8
|
+
const baseDir = resolveVercelOutputDir(vercelOutputDir);
|
|
9
|
+
const configPath = path.join(baseDir, "config.json");
|
|
10
|
+
const staticDir = path.join(baseDir, "static");
|
|
11
|
+
const functionsDir = path.join(baseDir, "functions");
|
|
12
|
+
// Parse routes from config.json
|
|
13
|
+
let routes = [];
|
|
14
|
+
try {
|
|
15
|
+
routes = parseVercelConfig(configPath);
|
|
16
|
+
}
|
|
17
|
+
catch (error) {
|
|
18
|
+
console.error(`Warning: Failed to parse routes from ${configPath}:`, error.message);
|
|
19
|
+
console.error("Continuing without routes...");
|
|
20
|
+
}
|
|
21
|
+
// Parse overrides from config.json
|
|
22
|
+
let overrides = {};
|
|
23
|
+
try {
|
|
24
|
+
if (fs.existsSync(configPath)) {
|
|
25
|
+
overrides = parseOverrides(configPath);
|
|
26
|
+
}
|
|
27
|
+
}
|
|
28
|
+
catch (error) {
|
|
29
|
+
console.warn(`Warning: Failed to parse overrides from ${configPath}:`, error.message);
|
|
30
|
+
}
|
|
31
|
+
// Build file manifest from static directory
|
|
32
|
+
let fileManifest = [];
|
|
33
|
+
try {
|
|
34
|
+
if (fs.existsSync(staticDir)) {
|
|
35
|
+
fileManifest = buildFileManifest(staticDir);
|
|
36
|
+
}
|
|
37
|
+
else {
|
|
38
|
+
console.warn(`Warning: Static directory not found: ${staticDir}`);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
catch (error) {
|
|
42
|
+
console.error(`Warning: Failed to build file manifest:`, error.message);
|
|
43
|
+
}
|
|
44
|
+
// Transform file manifest using overrides
|
|
45
|
+
const transformedFileManifest = [];
|
|
46
|
+
const filesWithOverrides = new Set();
|
|
47
|
+
// First pass: process all overrides
|
|
48
|
+
for (const [filePath, override] of Object.entries(overrides)) {
|
|
49
|
+
// Normalize file path (ensure it has leading slash for comparison)
|
|
50
|
+
const normalizedFilePath = filePath.startsWith("/")
|
|
51
|
+
? filePath
|
|
52
|
+
: "/" + filePath;
|
|
53
|
+
// Check if the file exists in the file manifest
|
|
54
|
+
if (fileManifest.includes(normalizedFilePath)) {
|
|
55
|
+
filesWithOverrides.add(normalizedFilePath);
|
|
56
|
+
if (override.path) {
|
|
57
|
+
// Path override: create override entry, file will be removed from manifest
|
|
58
|
+
const overridePath = override.path.startsWith("/")
|
|
59
|
+
? override.path
|
|
60
|
+
: "/" + override.path;
|
|
61
|
+
const overrideEntry = {
|
|
62
|
+
match: overridePath,
|
|
63
|
+
path: normalizedFilePath,
|
|
64
|
+
};
|
|
65
|
+
if (override.contentType) {
|
|
66
|
+
overrideEntry.contentType = override.contentType;
|
|
67
|
+
}
|
|
68
|
+
transformedFileManifest.push(overrideEntry);
|
|
69
|
+
}
|
|
70
|
+
else if (override.contentType) {
|
|
71
|
+
// ContentType-only override: create entry where match equals original path
|
|
72
|
+
const contentTypeEntry = {
|
|
73
|
+
match: normalizedFilePath,
|
|
74
|
+
path: normalizedFilePath,
|
|
75
|
+
contentType: override.contentType,
|
|
76
|
+
};
|
|
77
|
+
transformedFileManifest.push(contentTypeEntry);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
// Second pass: add normal files (excluding those with overrides)
|
|
82
|
+
for (const file of fileManifest) {
|
|
83
|
+
if (!filesWithOverrides.has(file)) {
|
|
84
|
+
transformedFileManifest.push(file);
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
// Build resource manifest and hashes from functions
|
|
88
|
+
let resourceManifest = [];
|
|
89
|
+
const resourceHashes = {};
|
|
90
|
+
try {
|
|
91
|
+
if (fs.existsSync(functionsDir)) {
|
|
92
|
+
const functions = scanFunctions(functionsDir, functionsDir);
|
|
93
|
+
for (const func of functions) {
|
|
94
|
+
// Extract resource name (remove leading slash and .func extension)
|
|
95
|
+
let resourceName = func.resourceName;
|
|
96
|
+
if (resourceName.startsWith("/")) {
|
|
97
|
+
resourceName = resourceName.slice(1);
|
|
98
|
+
}
|
|
99
|
+
if (resourceName.endsWith(".func")) {
|
|
100
|
+
resourceName = resourceName.slice(0, -5);
|
|
101
|
+
}
|
|
102
|
+
// Add to resource manifest if not already present
|
|
103
|
+
if (resourceName && !resourceManifest.includes(resourceName)) {
|
|
104
|
+
resourceManifest.push(resourceName);
|
|
105
|
+
}
|
|
106
|
+
// Add hash if available
|
|
107
|
+
if (func.hash && resourceName) {
|
|
108
|
+
resourceHashes[resourceName] = func.hash;
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
// Sort resource manifest
|
|
112
|
+
resourceManifest.sort();
|
|
113
|
+
}
|
|
114
|
+
else {
|
|
115
|
+
console.warn(`Warning: Functions directory not found: ${functionsDir}`);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
catch (error) {
|
|
119
|
+
console.error(`Warning: Failed to build resource manifest:`, error.message);
|
|
120
|
+
}
|
|
121
|
+
// Build deployment manifest
|
|
122
|
+
const manifest = {
|
|
123
|
+
routes,
|
|
124
|
+
fileManifest: transformedFileManifest,
|
|
125
|
+
resourceManifest,
|
|
126
|
+
resourceHashes: Object.keys(resourceHashes).length > 0 ? resourceHashes : undefined,
|
|
127
|
+
version: "1.0.0",
|
|
128
|
+
createdAt: new Date().toISOString(),
|
|
129
|
+
};
|
|
130
|
+
// Add hostname if provided
|
|
131
|
+
if (hostname) {
|
|
132
|
+
manifest.hostname = hostname;
|
|
133
|
+
}
|
|
134
|
+
// Output manifest
|
|
135
|
+
const manifestJson = JSON.stringify(manifest, null, 2);
|
|
136
|
+
if (output) {
|
|
137
|
+
const outputPath = path.resolve(output);
|
|
138
|
+
fs.writeFileSync(outputPath, manifestJson, "utf8");
|
|
139
|
+
console.log(`Manifest written to: ${outputPath}`);
|
|
140
|
+
}
|
|
141
|
+
else {
|
|
142
|
+
console.log(manifestJson);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
//# sourceMappingURL=generate-manifest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"generate-manifest.js","sourceRoot":"","sources":["../../src/commands/generate-manifest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-functions.d.ts","sourceRoot":"","sources":["../../src/commands/list-functions.ts"],"names":[],"mappings":"AAIA,MAAM,WAAW,oBAAoB;IACnC,GAAG,EAAE,MAAM,CAAC;IACZ,MAAM,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,wBAAgB,aAAa,CAAC,OAAO,EAAE,oBAAoB,GAAG,IAAI,CAuJjE"}
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
import * as path from 'path';
|
|
2
|
+
import { findWorkspaceRoot, scanFunctions } from '../utils.js';
|
|
3
|
+
export function listFunctions(options) {
|
|
4
|
+
const workspaceRoot = findWorkspaceRoot();
|
|
5
|
+
const projectRoot = path.join(workspaceRoot, 'apps', 'web');
|
|
6
|
+
const functionsDir = options.functionsDir
|
|
7
|
+
? path.resolve(projectRoot, options.functionsDir)
|
|
8
|
+
: path.resolve(options.dir);
|
|
9
|
+
const functions = scanFunctions(functionsDir, functionsDir);
|
|
10
|
+
// Sort by resource name for consistent output
|
|
11
|
+
functions.sort((a, b) => a.resourceName.localeCompare(b.resourceName));
|
|
12
|
+
// Calculate unique functions based on hash
|
|
13
|
+
const uniqueHashes = new Set();
|
|
14
|
+
const functionsWithHash = functions.filter(f => f.hash);
|
|
15
|
+
for (const func of functionsWithHash) {
|
|
16
|
+
if (func.hash) {
|
|
17
|
+
uniqueHashes.add(func.hash);
|
|
18
|
+
}
|
|
19
|
+
}
|
|
20
|
+
const uniqueFunctionCount = uniqueHashes.size;
|
|
21
|
+
// Filter functions to match Vercel's count (main page functions only, excluding .rsc and segments)
|
|
22
|
+
// Note: Vercel appears to filter based on resource name patterns rather than .vc-config.json fields
|
|
23
|
+
// All functions have similar configs (same operationType, etc.), so we use naming conventions:
|
|
24
|
+
// - Exclude functions with ".rsc.func" in the name (RSC variants)
|
|
25
|
+
// - Exclude functions with "segments" in the name (internal segment functions)
|
|
26
|
+
const mainPageFunctions = functions.filter(f => !f.resourceName.includes('.rsc.func') &&
|
|
27
|
+
!f.resourceName.includes('segments'));
|
|
28
|
+
const mainPageFunctionCount = mainPageFunctions.length;
|
|
29
|
+
// Group functions by hash
|
|
30
|
+
const hashGroups = new Map();
|
|
31
|
+
for (const func of functionsWithHash) {
|
|
32
|
+
if (func.hash) {
|
|
33
|
+
if (!hashGroups.has(func.hash)) {
|
|
34
|
+
hashGroups.set(func.hash, []);
|
|
35
|
+
}
|
|
36
|
+
hashGroups.get(func.hash).push(func);
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
// Sort groups by number of functions (largest first)
|
|
40
|
+
const sortedGroups = Array.from(hashGroups.entries()).sort((a, b) => b[1].length - a[1].length);
|
|
41
|
+
// Create groups array for JSON output
|
|
42
|
+
const groups = sortedGroups.map(([hash, groupFuncs], index) => {
|
|
43
|
+
// Sort functions in group by resource name
|
|
44
|
+
const sortedFuncs = [...groupFuncs].sort((a, b) => a.resourceName.localeCompare(b.resourceName));
|
|
45
|
+
return {
|
|
46
|
+
groupIndex: index + 1,
|
|
47
|
+
hash,
|
|
48
|
+
functionCount: sortedFuncs.length,
|
|
49
|
+
functions: sortedFuncs.map(f => ({
|
|
50
|
+
resourceName: f.resourceName,
|
|
51
|
+
configPath: f.configPath,
|
|
52
|
+
funcDir: f.funcDir,
|
|
53
|
+
prerenderConfigPath: f.prerenderConfigPath,
|
|
54
|
+
prerenderFallbackPath: f.prerenderFallbackPath,
|
|
55
|
+
})),
|
|
56
|
+
};
|
|
57
|
+
});
|
|
58
|
+
if (options.output === 'json') {
|
|
59
|
+
const output = {
|
|
60
|
+
summary: {
|
|
61
|
+
functionsDirectory: functionsDir,
|
|
62
|
+
totalFunctions: functions.length,
|
|
63
|
+
mainPageFunctions: mainPageFunctionCount,
|
|
64
|
+
rscVariants: functions.filter(f => f.resourceName.includes('.rsc.func') && !f.resourceName.includes('segments')).length,
|
|
65
|
+
segmentFunctions: functions.filter(f => f.resourceName.includes('segments')).length,
|
|
66
|
+
uniqueFunctions: uniqueFunctionCount,
|
|
67
|
+
},
|
|
68
|
+
functions: functions,
|
|
69
|
+
groups: groups,
|
|
70
|
+
};
|
|
71
|
+
console.log(JSON.stringify(output, null, 2));
|
|
72
|
+
}
|
|
73
|
+
else {
|
|
74
|
+
// Text output
|
|
75
|
+
console.log('='.repeat(80));
|
|
76
|
+
console.log('Next.js Functions List');
|
|
77
|
+
console.log('='.repeat(80));
|
|
78
|
+
console.log(`Functions directory: ${functionsDir}`);
|
|
79
|
+
console.log(`Total functions found: ${functions.length}`);
|
|
80
|
+
console.log(` - Main page functions: ${mainPageFunctionCount} (matches Vercel count)`);
|
|
81
|
+
console.log(` - .rsc variants: ${functions.filter(f => f.resourceName.includes('.rsc.func') && !f.resourceName.includes('segments')).length}`);
|
|
82
|
+
console.log(` - Segment functions: ${functions.filter(f => f.resourceName.includes('segments')).length}`);
|
|
83
|
+
console.log(`Unique functions (by hash): ${uniqueFunctionCount}`);
|
|
84
|
+
console.log('='.repeat(80));
|
|
85
|
+
console.log('');
|
|
86
|
+
if (functions.length === 0) {
|
|
87
|
+
console.log('No functions found.');
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
console.log('Functions:');
|
|
91
|
+
console.log('');
|
|
92
|
+
for (const func of functions) {
|
|
93
|
+
console.log(`Resource Name: ${func.resourceName}`);
|
|
94
|
+
console.log(`Config Path: ${func.configPath}`);
|
|
95
|
+
if (func.hash) {
|
|
96
|
+
console.log(`Hash: ${func.hash}`);
|
|
97
|
+
}
|
|
98
|
+
if (func.prerenderConfigPath) {
|
|
99
|
+
console.log(`Prerender: ${func.prerenderConfigPath}`);
|
|
100
|
+
if (func.prerenderFallbackPath) {
|
|
101
|
+
console.log(`Fallback: ${func.prerenderFallbackPath}`);
|
|
102
|
+
}
|
|
103
|
+
}
|
|
104
|
+
console.log('');
|
|
105
|
+
}
|
|
106
|
+
// Group functions by hash
|
|
107
|
+
if (functionsWithHash.length > 0) {
|
|
108
|
+
console.log('='.repeat(80));
|
|
109
|
+
console.log('Functions Grouped by Hash');
|
|
110
|
+
console.log('='.repeat(80));
|
|
111
|
+
console.log('');
|
|
112
|
+
// Create a map of hash -> functions
|
|
113
|
+
const hashGroups = new Map();
|
|
114
|
+
for (const func of functionsWithHash) {
|
|
115
|
+
if (func.hash) {
|
|
116
|
+
if (!hashGroups.has(func.hash)) {
|
|
117
|
+
hashGroups.set(func.hash, []);
|
|
118
|
+
}
|
|
119
|
+
hashGroups.get(func.hash).push(func);
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
// Sort groups by number of functions (largest first)
|
|
123
|
+
const sortedGroups = Array.from(hashGroups.entries()).sort((a, b) => b[1].length - a[1].length);
|
|
124
|
+
for (let i = 0; i < sortedGroups.length; i++) {
|
|
125
|
+
const [hash, groupFuncs] = sortedGroups[i];
|
|
126
|
+
console.log(`Group ${i + 1} (${groupFuncs.length} function(s)):`);
|
|
127
|
+
console.log(`Hash: ${hash}`);
|
|
128
|
+
console.log('');
|
|
129
|
+
// Sort functions in group by resource name
|
|
130
|
+
groupFuncs.sort((a, b) => a.resourceName.localeCompare(b.resourceName));
|
|
131
|
+
for (const func of groupFuncs) {
|
|
132
|
+
console.log(` - ${func.resourceName}`);
|
|
133
|
+
}
|
|
134
|
+
console.log('');
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
//# sourceMappingURL=list-functions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"list-functions.js","sourceRoot":"","sources":["../../src/commands/list-functions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
export interface PackageFunctionsOptions {
|
|
2
|
+
vercelOutputDir: string;
|
|
3
|
+
manifestFile?: string;
|
|
4
|
+
}
|
|
5
|
+
/**
|
|
6
|
+
* Package each function directory into a zip file named by its hash from the manifest
|
|
7
|
+
*/
|
|
8
|
+
export declare function packageFunctions(options: PackageFunctionsOptions): void;
|
|
9
|
+
//# sourceMappingURL=package-functions.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-functions.d.ts","sourceRoot":"","sources":["../../src/commands/package-functions.ts"],"names":[],"mappings":"AAMA,MAAM,WAAW,uBAAuB;IACtC,eAAe,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AA4LD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,uBAAuB,GAAG,IAAI,CAwHvE"}
|
|
@@ -0,0 +1,292 @@
|
|
|
1
|
+
import * as fs from 'fs';
|
|
2
|
+
import * as path from 'path';
|
|
3
|
+
import { execSync } from 'child_process';
|
|
4
|
+
import { resolveVercelOutputDir } from "../utils.js";
|
|
5
|
+
/**
|
|
6
|
+
* Handler wrapper code that converts API Gateway events to Node.js req/res objects
|
|
7
|
+
*/
|
|
8
|
+
function generateHandlerWrapper(handlerFile) {
|
|
9
|
+
return `/* eslint-disable @typescript-eslint/no-require-imports */
|
|
10
|
+
|
|
11
|
+
const handler = require("./${handlerFile.replace(/\.js$/, "")}");
|
|
12
|
+
|
|
13
|
+
const { Readable } = require("stream");
|
|
14
|
+
|
|
15
|
+
const { EventEmitter } = require("events");
|
|
16
|
+
|
|
17
|
+
module.exports.handler = async (event, _context) => {
|
|
18
|
+
return new Promise((resolve, reject) => {
|
|
19
|
+
// Convert AWS Lambda API Gateway event to Node.js request/response objects
|
|
20
|
+
// Support both API Gateway V1 (REST) and V2 (HTTP) formats
|
|
21
|
+
const isV2 = event.requestContext && event.requestContext.http;
|
|
22
|
+
const method = isV2
|
|
23
|
+
? event.requestContext.http.method
|
|
24
|
+
: event.httpMethod || "GET";
|
|
25
|
+
|
|
26
|
+
// Normalize headers (API Gateway V2 uses lowercase, V1 can be mixed)
|
|
27
|
+
const normalizedHeaders = {};
|
|
28
|
+
if (event.headers) {
|
|
29
|
+
Object.entries(event.headers).forEach(([key, value]) => {
|
|
30
|
+
normalizedHeaders[key.toLowerCase()] = value;
|
|
31
|
+
});
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
// Build URL with query parameters
|
|
35
|
+
const queryParams = { ...(event.queryStringParameters || {}) };
|
|
36
|
+
|
|
37
|
+
// Extract the URL from the 'x-matched-path' header
|
|
38
|
+
// This header contains the original path that was matched
|
|
39
|
+
let path = "/";
|
|
40
|
+
const matchedPath = normalizedHeaders["x-matched-path"];
|
|
41
|
+
if (matchedPath) {
|
|
42
|
+
path = matchedPath;
|
|
43
|
+
// Ensure path starts with /
|
|
44
|
+
if (!path.startsWith("/")) {
|
|
45
|
+
path = "/" + path;
|
|
46
|
+
}
|
|
47
|
+
} else {
|
|
48
|
+
// Fallback to original path if no 'x-matched-path' header
|
|
49
|
+
path = isV2
|
|
50
|
+
? event.rawPath || event.path || "/"
|
|
51
|
+
: event.path || "/";
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
const url = new URL(path, \`http://\${event.headers?.host || event.headers?.["host"] || "localhost"}\`);
|
|
55
|
+
|
|
56
|
+
// Add remaining query parameters
|
|
57
|
+
Object.entries(queryParams).forEach(([key, value]) => {
|
|
58
|
+
url.searchParams.set(key, value);
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
// Handle body - decode if base64 encoded
|
|
62
|
+
let bodyBuffer = null;
|
|
63
|
+
if (event.body) {
|
|
64
|
+
if (event.isBase64Encoded) {
|
|
65
|
+
bodyBuffer = Buffer.from(event.body, "base64");
|
|
66
|
+
} else {
|
|
67
|
+
bodyBuffer = Buffer.from(event.body, "utf8");
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
// Create a mock request object
|
|
72
|
+
const req = Object.assign(
|
|
73
|
+
new Readable({
|
|
74
|
+
read() {
|
|
75
|
+
if (bodyBuffer) {
|
|
76
|
+
this.push(bodyBuffer);
|
|
77
|
+
}
|
|
78
|
+
this.push(null);
|
|
79
|
+
},
|
|
80
|
+
}),
|
|
81
|
+
{
|
|
82
|
+
method: method,
|
|
83
|
+
url: url.pathname + url.search,
|
|
84
|
+
headers: normalizedHeaders,
|
|
85
|
+
query: queryParams,
|
|
86
|
+
body: bodyBuffer,
|
|
87
|
+
}
|
|
88
|
+
);
|
|
89
|
+
|
|
90
|
+
// Create a mock response object
|
|
91
|
+
let statusCode = 200;
|
|
92
|
+
const headers = {};
|
|
93
|
+
let body = "";
|
|
94
|
+
let headersSent = false;
|
|
95
|
+
const res = Object.assign(new EventEmitter(), {
|
|
96
|
+
setHeader: (key, value) => {
|
|
97
|
+
if (!headersSent) {
|
|
98
|
+
headers[key.toLowerCase()] = value;
|
|
99
|
+
}
|
|
100
|
+
},
|
|
101
|
+
getHeader: (key) => headers[key.toLowerCase()],
|
|
102
|
+
removeHeader: (key) => {
|
|
103
|
+
delete headers[key.toLowerCase()];
|
|
104
|
+
},
|
|
105
|
+
appendHeader: (key, value) => {
|
|
106
|
+
if (!headersSent) {
|
|
107
|
+
const lowerKey = key.toLowerCase();
|
|
108
|
+
const existing = headers[lowerKey];
|
|
109
|
+
if (existing) {
|
|
110
|
+
// Append to existing header (comma-separated)
|
|
111
|
+
headers[lowerKey] = Array.isArray(existing)
|
|
112
|
+
? existing.concat(value)
|
|
113
|
+
: [existing, value];
|
|
114
|
+
} else {
|
|
115
|
+
headers[lowerKey] = value;
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
},
|
|
119
|
+
hasHeader: (key) => {
|
|
120
|
+
return key.toLowerCase() in headers;
|
|
121
|
+
},
|
|
122
|
+
getHeaderNames: () => Object.keys(headers),
|
|
123
|
+
writeHead: (code, responseHeaders) => {
|
|
124
|
+
if (!headersSent) {
|
|
125
|
+
statusCode = code;
|
|
126
|
+
if (responseHeaders) {
|
|
127
|
+
Object.entries(responseHeaders).forEach(([key, value]) => {
|
|
128
|
+
headers[key.toLowerCase()] = value;
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
headersSent = true;
|
|
132
|
+
}
|
|
133
|
+
return res;
|
|
134
|
+
},
|
|
135
|
+
write: (chunk) => {
|
|
136
|
+
if (!headersSent) {
|
|
137
|
+
headersSent = true;
|
|
138
|
+
}
|
|
139
|
+
body += chunk.toString();
|
|
140
|
+
return true;
|
|
141
|
+
},
|
|
142
|
+
end: (chunk) => {
|
|
143
|
+
if (chunk) {
|
|
144
|
+
body += chunk.toString();
|
|
145
|
+
}
|
|
146
|
+
if (!headersSent) {
|
|
147
|
+
headersSent = true;
|
|
148
|
+
}
|
|
149
|
+
// Normalize headers - convert arrays to comma-separated strings
|
|
150
|
+
const normalizedHeaders = {};
|
|
151
|
+
Object.entries(headers).forEach(([key, value]) => {
|
|
152
|
+
normalizedHeaders[key] = Array.isArray(value) ? value.join(", ") : value;
|
|
153
|
+
});
|
|
154
|
+
// Return AWS Lambda API Gateway response format
|
|
155
|
+
// Use statusCode (which can be set via res.statusCode = value or writeHead)
|
|
156
|
+
resolve({
|
|
157
|
+
statusCode: statusCode || 200,
|
|
158
|
+
headers: normalizedHeaders,
|
|
159
|
+
body: body,
|
|
160
|
+
});
|
|
161
|
+
},
|
|
162
|
+
headersSent: false,
|
|
163
|
+
});
|
|
164
|
+
|
|
165
|
+
// Define statusCode as a getter/setter to sync with the local variable
|
|
166
|
+
// This allows handlers to set res.statusCode = 404 and have it work correctly
|
|
167
|
+
Object.defineProperty(res, "statusCode", {
|
|
168
|
+
get: () => statusCode,
|
|
169
|
+
set: (value) => {
|
|
170
|
+
statusCode = value;
|
|
171
|
+
},
|
|
172
|
+
enumerable: true,
|
|
173
|
+
configurable: true,
|
|
174
|
+
});
|
|
175
|
+
|
|
176
|
+
// Handle errors
|
|
177
|
+
req.on("error", reject);
|
|
178
|
+
res.on("error", reject);
|
|
179
|
+
|
|
180
|
+
// Call the Next.js handler
|
|
181
|
+
try {
|
|
182
|
+
handler(req, res);
|
|
183
|
+
} catch (error) {
|
|
184
|
+
reject(error);
|
|
185
|
+
}
|
|
186
|
+
});
|
|
187
|
+
};
|
|
188
|
+
`;
|
|
189
|
+
}
|
|
190
|
+
/**
|
|
191
|
+
* Package each function directory into a zip file named by its hash from the manifest
|
|
192
|
+
*/
|
|
193
|
+
export function packageFunctions(options) {
|
|
194
|
+
const { vercelOutputDir, manifestFile } = options;
|
|
195
|
+
// Resolve base Vercel output directory
|
|
196
|
+
const baseDir = resolveVercelOutputDir(vercelOutputDir);
|
|
197
|
+
const functionsDir = path.join(baseDir, "functions");
|
|
198
|
+
// Resolve manifest file path
|
|
199
|
+
let resolvedManifestFile;
|
|
200
|
+
if (manifestFile) {
|
|
201
|
+
resolvedManifestFile = path.resolve(manifestFile);
|
|
202
|
+
}
|
|
203
|
+
else {
|
|
204
|
+
resolvedManifestFile = path.join(baseDir, "manifest.json");
|
|
205
|
+
}
|
|
206
|
+
if (!fs.existsSync(resolvedManifestFile)) {
|
|
207
|
+
throw new Error(`Manifest file not found: ${resolvedManifestFile}`);
|
|
208
|
+
}
|
|
209
|
+
// Read and parse manifest
|
|
210
|
+
const manifestContent = fs.readFileSync(resolvedManifestFile, "utf8");
|
|
211
|
+
const manifest = JSON.parse(manifestContent);
|
|
212
|
+
const resourceHashes = manifest.resourceHashes || {};
|
|
213
|
+
if (Object.keys(resourceHashes).length === 0) {
|
|
214
|
+
console.warn("No resource hashes found in manifest. Nothing to package.");
|
|
215
|
+
return;
|
|
216
|
+
}
|
|
217
|
+
console.log(`Found ${Object.keys(resourceHashes).length} function(s) to package`);
|
|
218
|
+
// Package each function
|
|
219
|
+
for (const [resourceName, hash] of Object.entries(resourceHashes)) {
|
|
220
|
+
try {
|
|
221
|
+
// Construct function directory path
|
|
222
|
+
// Resource names might have leading slashes, remove them
|
|
223
|
+
const cleanResourceName = resourceName.startsWith("/")
|
|
224
|
+
? resourceName.slice(1)
|
|
225
|
+
: resourceName;
|
|
226
|
+
const funcPath = path.join(functionsDir, `${cleanResourceName}.func`);
|
|
227
|
+
if (!fs.existsSync(funcPath)) {
|
|
228
|
+
console.warn(`Function directory not found: ${funcPath}`);
|
|
229
|
+
continue;
|
|
230
|
+
}
|
|
231
|
+
// Read .vc-config.json to get handler file name
|
|
232
|
+
const vcConfigPath = path.join(funcPath, ".vc-config.json");
|
|
233
|
+
let handlerFile = "handler.js"; // default
|
|
234
|
+
if (fs.existsSync(vcConfigPath)) {
|
|
235
|
+
try {
|
|
236
|
+
const vcConfig = JSON.parse(fs.readFileSync(vcConfigPath, "utf8"));
|
|
237
|
+
if (vcConfig.handler) {
|
|
238
|
+
handlerFile = vcConfig.handler;
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
catch (error) {
|
|
242
|
+
console.warn(`Warning: Could not read .vc-config.json from ${funcPath}: ${error.message}`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
// Create handler wrapper
|
|
246
|
+
const handlerWrapperCode = generateHandlerWrapper(handlerFile);
|
|
247
|
+
// Create a temporary directory for packaging
|
|
248
|
+
const tempZipDir = path.join(baseDir, `temp-zip-${hash}`);
|
|
249
|
+
fs.mkdirSync(tempZipDir, { recursive: true });
|
|
250
|
+
// Copy all function files to temp directory
|
|
251
|
+
const copyRecursive = (src, dest) => {
|
|
252
|
+
const entries = fs.readdirSync(src, { withFileTypes: true });
|
|
253
|
+
for (const entry of entries) {
|
|
254
|
+
const srcPath = path.join(src, entry.name);
|
|
255
|
+
const destPath = path.join(dest, entry.name);
|
|
256
|
+
if (entry.isDirectory()) {
|
|
257
|
+
fs.mkdirSync(destPath, { recursive: true });
|
|
258
|
+
copyRecursive(srcPath, destPath);
|
|
259
|
+
}
|
|
260
|
+
else {
|
|
261
|
+
fs.copyFileSync(srcPath, destPath);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
264
|
+
};
|
|
265
|
+
copyRecursive(funcPath, tempZipDir);
|
|
266
|
+
// Write handler wrapper as handler.js in temp directory
|
|
267
|
+
const handlerWrapperPath = path.join(tempZipDir, "handler.js");
|
|
268
|
+
fs.writeFileSync(handlerWrapperPath, handlerWrapperCode);
|
|
269
|
+
// Create zip file
|
|
270
|
+
const zipPath = path.join(baseDir, `${hash}.zip`);
|
|
271
|
+
// Use a simple zip command via child_process
|
|
272
|
+
try {
|
|
273
|
+
execSync(`cd "${tempZipDir}" && zip -r "${zipPath}" . > /dev/null 2>&1`, { stdio: "inherit" });
|
|
274
|
+
console.log(`✓ Packaged ${resourceName} -> ${hash}.zip`);
|
|
275
|
+
}
|
|
276
|
+
catch (zipError) {
|
|
277
|
+
console.error(`Failed to create zip for ${resourceName}: ${zipError.message}`);
|
|
278
|
+
// Clean up temp directory
|
|
279
|
+
fs.rmSync(tempZipDir, { recursive: true, force: true });
|
|
280
|
+
continue;
|
|
281
|
+
}
|
|
282
|
+
// Clean up temp directory
|
|
283
|
+
fs.rmSync(tempZipDir, { recursive: true, force: true });
|
|
284
|
+
}
|
|
285
|
+
catch (error) {
|
|
286
|
+
console.error(`Error packaging ${resourceName}: ${error.message}`);
|
|
287
|
+
// Continue with next function
|
|
288
|
+
}
|
|
289
|
+
}
|
|
290
|
+
console.log(`✓ Function packaging completed`);
|
|
291
|
+
}
|
|
292
|
+
//# sourceMappingURL=package-functions.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"package-functions.js","sourceRoot":"","sources":["../../src/commands/package-functions.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"upload-manifest.d.ts","sourceRoot":"","sources":["../../src/commands/upload-manifest.ts"],"names":[],"mappings":"AAGA,MAAM,WAAW,qBAAqB;IACpC,YAAY,EAAE,MAAM,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED,wBAAsB,cAAc,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDlF"}
|