@certik/serverless-api 1.0.12 → 2.0.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/CHANGELOG.md +4 -0
- package/README.md +0 -1
- package/dist/deploy.d.ts +20 -0
- package/dist/deploy.d.ts.map +1 -0
- package/dist/deploy.js +17 -0
- package/dist/dev.d.ts +8 -0
- package/dist/dev.d.ts.map +1 -0
- package/dist/dev.js +8 -0
- package/dist/entrypoint.d.ts +26 -0
- package/dist/entrypoint.d.ts.map +1 -0
- package/dist/entrypoint.js +78 -0
- package/dist/handler.d.ts +2 -0
- package/dist/handler.d.ts.map +1 -0
- package/{index.js → dist/handler.js} +1 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/lib/app.d.ts +39 -0
- package/dist/lib/app.d.ts.map +1 -0
- package/dist/lib/app.js +139 -0
- package/dist/lib/const.d.ts +12 -0
- package/dist/lib/const.d.ts.map +1 -0
- package/dist/lib/const.js +12 -0
- package/dist/lib/cors.d.ts +19 -0
- package/dist/lib/cors.d.ts.map +1 -0
- package/dist/lib/cors.js +38 -0
- package/dist/lib/dev.d.ts +38 -0
- package/dist/lib/dev.d.ts.map +1 -0
- package/dist/lib/dev.js +78 -0
- package/dist/lib/domain.d.ts +16 -0
- package/dist/lib/domain.d.ts.map +1 -0
- package/dist/lib/domain.js +19 -0
- package/dist/lib/env.d.ts +14 -0
- package/dist/lib/env.d.ts.map +1 -0
- package/dist/lib/env.js +37 -0
- package/dist/lib/pack.d.ts +29 -0
- package/dist/lib/pack.d.ts.map +1 -0
- package/dist/lib/pack.js +93 -0
- package/dist/lib/path.d.ts +22 -0
- package/dist/lib/path.d.ts.map +1 -0
- package/dist/lib/path.js +26 -0
- package/dist/lib/routes.d.ts +32 -0
- package/dist/lib/routes.d.ts.map +1 -0
- package/dist/lib/routes.js +76 -0
- package/dist/lib/types.d.ts +125 -0
- package/dist/lib/types.d.ts.map +1 -0
- package/dist/lib/types.js +7 -0
- package/package.json +36 -44
- package/dev.js +0 -4
- package/entrypoint.js +0 -68
- package/lib/app.js +0 -162
- package/lib/const.js +0 -4
- package/lib/cors.js +0 -21
- package/lib/dev.js +0 -54
- package/lib/env.js +0 -24
- package/lib/pack.js +0 -83
- package/lib/path.js +0 -6
- package/lib/routes.js +0 -39
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Domain name utilities.
|
|
3
|
+
*
|
|
4
|
+
* @module domain
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Derive a wildcard certificate name from a fully-qualified domain.
|
|
8
|
+
*
|
|
9
|
+
* Replaces the leftmost label with `*` so the result matches an
|
|
10
|
+
* ACM wildcard certificate (e.g. `data.example.com` → `*.example.com`).
|
|
11
|
+
*
|
|
12
|
+
* @param domainName - The fully-qualified domain name.
|
|
13
|
+
* @returns The wildcard domain (e.g. `*.example.com`).
|
|
14
|
+
*/
|
|
15
|
+
export function getWildcardCertificateName(domainName) {
|
|
16
|
+
const parts = domainName.split(".");
|
|
17
|
+
return ["*", ...parts.slice(1)].join(".");
|
|
18
|
+
}
|
|
19
|
+
//# sourceMappingURL=domain.js.map
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for filtering AWS Lambda reserved environment variable names.
|
|
3
|
+
*
|
|
4
|
+
* @module env
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Check whether an environment variable name is reserved by the
|
|
8
|
+
* AWS Lambda runtime and should not be set manually.
|
|
9
|
+
*
|
|
10
|
+
* @param name - The environment variable name to check.
|
|
11
|
+
* @returns `true` if the name is reserved by Lambda.
|
|
12
|
+
*/
|
|
13
|
+
export declare function isReservedEnvName(name: string): boolean;
|
|
14
|
+
//# sourceMappingURL=env.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"env.d.ts","sourceRoot":"","sources":["../../src/lib/env.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAwBH;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAEvD"}
|
package/dist/lib/env.js
ADDED
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utilities for filtering AWS Lambda reserved environment variable names.
|
|
3
|
+
*
|
|
4
|
+
* @module env
|
|
5
|
+
*/
|
|
6
|
+
/** Environment variable names reserved by the AWS Lambda runtime. */
|
|
7
|
+
const RESERVED_ENV_NAMES = new Set([
|
|
8
|
+
"_HANDLER",
|
|
9
|
+
"_X_AMZN_TRACE_ID",
|
|
10
|
+
"AWS_DEFAULT_REGION",
|
|
11
|
+
"AWS_REGION",
|
|
12
|
+
"AWS_EXECUTION_ENV",
|
|
13
|
+
"AWS_LAMBDA_FUNCTION_NAME",
|
|
14
|
+
"AWS_LAMBDA_FUNCTION_MEMORY_SIZE",
|
|
15
|
+
"AWS_LAMBDA_FUNCTION_VERSION",
|
|
16
|
+
"AWS_LAMBDA_INITIALIZATION_TYPE",
|
|
17
|
+
"AWS_LAMBDA_LOG_GROUP_NAME",
|
|
18
|
+
"AWS_LAMBDA_LOG_STREAM_NAME",
|
|
19
|
+
"AWS_ACCESS_KEY",
|
|
20
|
+
"AWS_ACCESS_KEY_ID",
|
|
21
|
+
"AWS_SECRET_ACCESS_KEY",
|
|
22
|
+
"AWS_SESSION_TOKEN",
|
|
23
|
+
"AWS_LAMBDA_RUNTIME_API",
|
|
24
|
+
"LAMBDA_TASK_ROOT",
|
|
25
|
+
"LAMBDA_RUNTIME_DIR",
|
|
26
|
+
]);
|
|
27
|
+
/**
|
|
28
|
+
* Check whether an environment variable name is reserved by the
|
|
29
|
+
* AWS Lambda runtime and should not be set manually.
|
|
30
|
+
*
|
|
31
|
+
* @param name - The environment variable name to check.
|
|
32
|
+
* @returns `true` if the name is reserved by Lambda.
|
|
33
|
+
*/
|
|
34
|
+
export function isReservedEnvName(name) {
|
|
35
|
+
return RESERVED_ENV_NAMES.has(name);
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=env.js.map
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lambda deployment packaging.
|
|
3
|
+
*
|
|
4
|
+
* Copies the project source (excluding tests, node_modules, etc.)
|
|
5
|
+
* into a temporary directory, installs production dependencies,
|
|
6
|
+
* and produces a zip archive suitable for uploading to AWS Lambda
|
|
7
|
+
* via S3.
|
|
8
|
+
*
|
|
9
|
+
* @module pack
|
|
10
|
+
*/
|
|
11
|
+
import type { PackOptions, PackResult } from "./types.js";
|
|
12
|
+
/**
|
|
13
|
+
* Package the project source code into a zip archive ready for
|
|
14
|
+
* Lambda deployment.
|
|
15
|
+
*
|
|
16
|
+
* The function:
|
|
17
|
+
* 1. Cleans and recreates the `.serverless-pack/` staging directory.
|
|
18
|
+
* 2. Copies all root-level files (except excluded ones) in parallel.
|
|
19
|
+
* 3. Runs `bun install` to populate `node_modules`.
|
|
20
|
+
* 4. Compresses the staging directory into `all-code.zip`.
|
|
21
|
+
* 5. Computes a SHA-256 hash for Pulumi change detection.
|
|
22
|
+
*
|
|
23
|
+
* @param options - Packaging options.
|
|
24
|
+
* @param options.bundleDevDependencies - When `true`, installs all
|
|
25
|
+
* dependencies (including devDependencies).
|
|
26
|
+
* @returns The zip filename and its SHA-256 hash.
|
|
27
|
+
*/
|
|
28
|
+
export declare function packAndZip({ bundleDevDependencies, }?: PackOptions): Promise<PackResult>;
|
|
29
|
+
//# sourceMappingURL=pack.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"pack.d.ts","sourceRoot":"","sources":["../../src/lib/pack.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AASH,OAAO,KAAK,EAAE,WAAW,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAiD1D;;;;;;;;;;;;;;;GAeG;AACH,wBAAsB,UAAU,CAAC,EAC/B,qBAAqB,GACtB,GAAE,WAAgB,GAAG,OAAO,CAAC,UAAU,CAAC,CA2BxC"}
|
package/dist/lib/pack.js
ADDED
|
@@ -0,0 +1,93 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Lambda deployment packaging.
|
|
3
|
+
*
|
|
4
|
+
* Copies the project source (excluding tests, node_modules, etc.)
|
|
5
|
+
* into a temporary directory, installs production dependencies,
|
|
6
|
+
* and produces a zip archive suitable for uploading to AWS Lambda
|
|
7
|
+
* via S3.
|
|
8
|
+
*
|
|
9
|
+
* @module pack
|
|
10
|
+
*/
|
|
11
|
+
import { exec } from "node:child_process";
|
|
12
|
+
import cryptoModule from "node:crypto";
|
|
13
|
+
import { createReadStream } from "node:fs";
|
|
14
|
+
import { rm, mkdir, readdir, cp } from "node:fs/promises";
|
|
15
|
+
import pathModule from "node:path";
|
|
16
|
+
import { promisify } from "node:util";
|
|
17
|
+
const execPromise = promisify(exec);
|
|
18
|
+
const PACK_DIR = ".serverless-pack";
|
|
19
|
+
const ZIP_FILE = "all-code.zip";
|
|
20
|
+
/** Files and directories excluded from the Lambda deployment bundle. */
|
|
21
|
+
const EXCLUDED_FILES = new Set([
|
|
22
|
+
"node_modules",
|
|
23
|
+
"test",
|
|
24
|
+
"dist",
|
|
25
|
+
"coverage",
|
|
26
|
+
"bun.lockb",
|
|
27
|
+
ZIP_FILE,
|
|
28
|
+
PACK_DIR,
|
|
29
|
+
"tsconfig.json",
|
|
30
|
+
"tsconfig.test.json",
|
|
31
|
+
]);
|
|
32
|
+
/**
|
|
33
|
+
* Create a zip archive from the contents of a directory.
|
|
34
|
+
*
|
|
35
|
+
* Uses the system `zip` command for reliable, fast compression.
|
|
36
|
+
*
|
|
37
|
+
* @param sourceDir - The directory to compress.
|
|
38
|
+
* @param outPath - The output zip file path.
|
|
39
|
+
*/
|
|
40
|
+
async function zipDirectory(sourceDir, outPath) {
|
|
41
|
+
const absoluteOut = pathModule.resolve(outPath);
|
|
42
|
+
await execPromise(`zip -r -q -y "${absoluteOut}" .`, { cwd: sourceDir });
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Compute the SHA-256 hash of a file.
|
|
46
|
+
*
|
|
47
|
+
* @param filePath - Absolute path to the file to hash.
|
|
48
|
+
* @returns The hex-encoded SHA-256 digest.
|
|
49
|
+
*/
|
|
50
|
+
async function getHash(filePath) {
|
|
51
|
+
return new Promise((resolve, reject) => {
|
|
52
|
+
const hash = cryptoModule.createHash("sha256");
|
|
53
|
+
const rs = createReadStream(filePath);
|
|
54
|
+
rs.on("error", reject);
|
|
55
|
+
rs.on("data", (chunk) => hash.update(chunk));
|
|
56
|
+
rs.on("end", () => resolve(hash.digest("hex")));
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Package the project source code into a zip archive ready for
|
|
61
|
+
* Lambda deployment.
|
|
62
|
+
*
|
|
63
|
+
* The function:
|
|
64
|
+
* 1. Cleans and recreates the `.serverless-pack/` staging directory.
|
|
65
|
+
* 2. Copies all root-level files (except excluded ones) in parallel.
|
|
66
|
+
* 3. Runs `bun install` to populate `node_modules`.
|
|
67
|
+
* 4. Compresses the staging directory into `all-code.zip`.
|
|
68
|
+
* 5. Computes a SHA-256 hash for Pulumi change detection.
|
|
69
|
+
*
|
|
70
|
+
* @param options - Packaging options.
|
|
71
|
+
* @param options.bundleDevDependencies - When `true`, installs all
|
|
72
|
+
* dependencies (including devDependencies).
|
|
73
|
+
* @returns The zip filename and its SHA-256 hash.
|
|
74
|
+
*/
|
|
75
|
+
export async function packAndZip({ bundleDevDependencies, } = {}) {
|
|
76
|
+
const packDirAbsolute = pathModule.resolve(PACK_DIR);
|
|
77
|
+
await rm(packDirAbsolute, { recursive: true, force: true });
|
|
78
|
+
await mkdir(packDirAbsolute);
|
|
79
|
+
const rootLevelFiles = await readdir(".");
|
|
80
|
+
await Promise.all(rootLevelFiles
|
|
81
|
+
.filter((file) => !EXCLUDED_FILES.has(file))
|
|
82
|
+
.map((file) => cp(file, pathModule.join(packDirAbsolute, file), { recursive: true })));
|
|
83
|
+
if (bundleDevDependencies) {
|
|
84
|
+
await execPromise("bun install", { cwd: packDirAbsolute });
|
|
85
|
+
}
|
|
86
|
+
else {
|
|
87
|
+
await execPromise("bun install --production", { cwd: packDirAbsolute });
|
|
88
|
+
}
|
|
89
|
+
await zipDirectory(packDirAbsolute, pathModule.resolve(ZIP_FILE));
|
|
90
|
+
const zipFileHash = await getHash(pathModule.resolve(ZIP_FILE));
|
|
91
|
+
return { zipFileName: ZIP_FILE, zipFileHash };
|
|
92
|
+
}
|
|
93
|
+
//# sourceMappingURL=pack.js.map
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path utilities for ESM modules.
|
|
3
|
+
*
|
|
4
|
+
* @module path
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Derive the directory path from an `import.meta.url` value.
|
|
8
|
+
*
|
|
9
|
+
* This is the ESM equivalent of the CommonJS `__dirname` global,
|
|
10
|
+
* useful for resolving paths relative to the current module.
|
|
11
|
+
*
|
|
12
|
+
* @param importMetaUrl - The `import.meta.url` of the calling module.
|
|
13
|
+
* @returns The absolute directory path of the calling module.
|
|
14
|
+
*
|
|
15
|
+
* @example
|
|
16
|
+
* ```ts
|
|
17
|
+
* import { dirname } from "./lib/path.js";
|
|
18
|
+
* const dir = dirname(import.meta.url);
|
|
19
|
+
* ```
|
|
20
|
+
*/
|
|
21
|
+
export declare function dirname(importMetaUrl: string): string;
|
|
22
|
+
//# sourceMappingURL=path.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"path.d.ts","sourceRoot":"","sources":["../../src/lib/path.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAKH;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,OAAO,CAAC,aAAa,EAAE,MAAM,GAAG,MAAM,CAErD"}
|
package/dist/lib/path.js
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Path utilities for ESM modules.
|
|
3
|
+
*
|
|
4
|
+
* @module path
|
|
5
|
+
*/
|
|
6
|
+
import pathModule from "node:path";
|
|
7
|
+
import { fileURLToPath } from "node:url";
|
|
8
|
+
/**
|
|
9
|
+
* Derive the directory path from an `import.meta.url` value.
|
|
10
|
+
*
|
|
11
|
+
* This is the ESM equivalent of the CommonJS `__dirname` global,
|
|
12
|
+
* useful for resolving paths relative to the current module.
|
|
13
|
+
*
|
|
14
|
+
* @param importMetaUrl - The `import.meta.url` of the calling module.
|
|
15
|
+
* @returns The absolute directory path of the calling module.
|
|
16
|
+
*
|
|
17
|
+
* @example
|
|
18
|
+
* ```ts
|
|
19
|
+
* import { dirname } from "./lib/path.js";
|
|
20
|
+
* const dir = dirname(import.meta.url);
|
|
21
|
+
* ```
|
|
22
|
+
*/
|
|
23
|
+
export function dirname(importMetaUrl) {
|
|
24
|
+
return fileURLToPath(new URL(pathModule.join("."), importMetaUrl));
|
|
25
|
+
}
|
|
26
|
+
//# sourceMappingURL=path.js.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-system-based route loader.
|
|
3
|
+
*
|
|
4
|
+
* Discovers route handler modules by scanning a directory for `.js`
|
|
5
|
+
* or `.ts` files and resolving each into one or more {@link Route}
|
|
6
|
+
* definitions. In production (compiled output) it loads `.js` files;
|
|
7
|
+
* in development (with `tsx`) it can also load `.ts` source directly.
|
|
8
|
+
*
|
|
9
|
+
* @module routes
|
|
10
|
+
*/
|
|
11
|
+
import type { Route } from "./types.js";
|
|
12
|
+
/**
|
|
13
|
+
* Load all route definitions from a directory.
|
|
14
|
+
*
|
|
15
|
+
* Each `.js` or `.ts` file in {@link routeDirectory} is dynamically
|
|
16
|
+
* imported and expected to conform to the {@link RouteModule}
|
|
17
|
+
* interface. A single file may produce multiple routes when it
|
|
18
|
+
* exports a `methods` array (e.g. `["GET", "POST"]`). If a route
|
|
19
|
+
* sets `corsOrigin`, an additional `OPTIONS` preflight route is
|
|
20
|
+
* generated automatically.
|
|
21
|
+
*
|
|
22
|
+
* When both a `.js` and `.ts` version of a route exist (e.g. during
|
|
23
|
+
* development with a `dist/` build), the `.js` version takes
|
|
24
|
+
* precedence to avoid duplicate routes.
|
|
25
|
+
*
|
|
26
|
+
* @param routeDirectory - Absolute path to the directory containing
|
|
27
|
+
* route modules (compiled `.js` or source `.ts`).
|
|
28
|
+
* @returns A flat array of resolved routes ready for deployment or
|
|
29
|
+
* local serving.
|
|
30
|
+
*/
|
|
31
|
+
export declare function getRoutes(routeDirectory: string): Promise<Route[]>;
|
|
32
|
+
//# sourceMappingURL=routes.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"routes.d.ts","sourceRoot":"","sources":["../../src/lib/routes.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,OAAO,KAAK,EAAE,KAAK,EAAe,MAAM,YAAY,CAAC;AAQrD;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAsB,SAAS,CAAC,cAAc,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,EAAE,CAAC,CAiDxE"}
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* File-system-based route loader.
|
|
3
|
+
*
|
|
4
|
+
* Discovers route handler modules by scanning a directory for `.js`
|
|
5
|
+
* or `.ts` files and resolving each into one or more {@link Route}
|
|
6
|
+
* definitions. In production (compiled output) it loads `.js` files;
|
|
7
|
+
* in development (with `tsx`) it can also load `.ts` source directly.
|
|
8
|
+
*
|
|
9
|
+
* @module routes
|
|
10
|
+
*/
|
|
11
|
+
import { readdir } from "node:fs/promises";
|
|
12
|
+
import pathModule from "node:path";
|
|
13
|
+
import { DEFAULT_TIMEOUT, MAX_TIMEOUT, DEFAULT_MEMORY_SIZE } from "./const.js";
|
|
14
|
+
import { corsPreflight } from "./cors.js";
|
|
15
|
+
/** File extensions recognised as route modules, in priority order. */
|
|
16
|
+
const ROUTE_EXTENSIONS = [".js", ".ts"];
|
|
17
|
+
/**
|
|
18
|
+
* Load all route definitions from a directory.
|
|
19
|
+
*
|
|
20
|
+
* Each `.js` or `.ts` file in {@link routeDirectory} is dynamically
|
|
21
|
+
* imported and expected to conform to the {@link RouteModule}
|
|
22
|
+
* interface. A single file may produce multiple routes when it
|
|
23
|
+
* exports a `methods` array (e.g. `["GET", "POST"]`). If a route
|
|
24
|
+
* sets `corsOrigin`, an additional `OPTIONS` preflight route is
|
|
25
|
+
* generated automatically.
|
|
26
|
+
*
|
|
27
|
+
* When both a `.js` and `.ts` version of a route exist (e.g. during
|
|
28
|
+
* development with a `dist/` build), the `.js` version takes
|
|
29
|
+
* precedence to avoid duplicate routes.
|
|
30
|
+
*
|
|
31
|
+
* @param routeDirectory - Absolute path to the directory containing
|
|
32
|
+
* route modules (compiled `.js` or source `.ts`).
|
|
33
|
+
* @returns A flat array of resolved routes ready for deployment or
|
|
34
|
+
* local serving.
|
|
35
|
+
*/
|
|
36
|
+
export async function getRoutes(routeDirectory) {
|
|
37
|
+
const routeFiles = await readdir(routeDirectory);
|
|
38
|
+
// Collect unique route basenames, preferring .js over .ts
|
|
39
|
+
const seen = new Set();
|
|
40
|
+
const filteredFiles = [];
|
|
41
|
+
for (const ext of ROUTE_EXTENSIONS) {
|
|
42
|
+
for (const file of routeFiles) {
|
|
43
|
+
if (file.endsWith(ext)) {
|
|
44
|
+
const base = pathModule.basename(file, ext);
|
|
45
|
+
if (!seen.has(base)) {
|
|
46
|
+
seen.add(base);
|
|
47
|
+
filteredFiles.push(file);
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
const routesFromFiles = await Promise.all(filteredFiles.map(async (routeFile) => {
|
|
53
|
+
const routeFilePath = pathModule.join(routeDirectory, routeFile);
|
|
54
|
+
const route = (await import(`file://${routeFilePath}`));
|
|
55
|
+
const ext = ROUTE_EXTENSIONS.find((e) => routeFile.endsWith(e)) ?? ".js";
|
|
56
|
+
const routeName = pathModule.basename(routeFile, ext);
|
|
57
|
+
const methods = route.methods ?? ["GET"];
|
|
58
|
+
const environmentVariables = route.environmentVariables ?? [];
|
|
59
|
+
const methodRoutes = methods.map((method) => ({
|
|
60
|
+
name: `${routeName}-${method}`,
|
|
61
|
+
path: `/${routeName}`,
|
|
62
|
+
method,
|
|
63
|
+
corsOrigin: route.corsOrigin,
|
|
64
|
+
timeout: Math.min(route.timeout ?? DEFAULT_TIMEOUT, MAX_TIMEOUT),
|
|
65
|
+
handler: route.default,
|
|
66
|
+
memorySize: route.memorySize ?? DEFAULT_MEMORY_SIZE,
|
|
67
|
+
environmentVariables,
|
|
68
|
+
}));
|
|
69
|
+
if (route.corsOrigin) {
|
|
70
|
+
methodRoutes.push(corsPreflight(`${routeName}-OPTIONS`, `/${routeName}`));
|
|
71
|
+
}
|
|
72
|
+
return methodRoutes;
|
|
73
|
+
}));
|
|
74
|
+
return routesFromFiles.flat();
|
|
75
|
+
}
|
|
76
|
+
//# sourceMappingURL=routes.js.map
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Shared type definitions for the serverless API library.
|
|
3
|
+
*
|
|
4
|
+
* @module types
|
|
5
|
+
*/
|
|
6
|
+
/** Incoming API Gateway proxy event passed to Lambda handlers. */
|
|
7
|
+
export interface LambdaEvent {
|
|
8
|
+
/** The API resource path template (e.g. `/{proxy+}`). */
|
|
9
|
+
resource: string;
|
|
10
|
+
/** The actual request path (e.g. `/dynamodb-example`). */
|
|
11
|
+
path: string;
|
|
12
|
+
/** The HTTP method (`GET`, `POST`, etc.). */
|
|
13
|
+
httpMethod: string;
|
|
14
|
+
/** Nested context supplied by API Gateway. */
|
|
15
|
+
requestContext: {
|
|
16
|
+
resourcePath: string;
|
|
17
|
+
httpMethod: string;
|
|
18
|
+
path: string;
|
|
19
|
+
};
|
|
20
|
+
/** Single-value request headers. */
|
|
21
|
+
headers: Record<string, string>;
|
|
22
|
+
/** Multi-value request headers. */
|
|
23
|
+
multiValueHeaders: Record<string, string[]>;
|
|
24
|
+
/** Single-value query string parameters. */
|
|
25
|
+
queryStringParameters: Record<string, string> | null;
|
|
26
|
+
/** The raw request body (may be base64-encoded). */
|
|
27
|
+
body: string | null;
|
|
28
|
+
/** Whether {@link body} is base64-encoded. */
|
|
29
|
+
isBase64Encoded: boolean;
|
|
30
|
+
}
|
|
31
|
+
/** Lambda execution context. */
|
|
32
|
+
export interface LambdaContext {
|
|
33
|
+
/** The name of the Lambda function. */
|
|
34
|
+
functionName?: string;
|
|
35
|
+
/** The version of the Lambda function. */
|
|
36
|
+
functionVersion?: string;
|
|
37
|
+
/** The ARN of the invocation. */
|
|
38
|
+
invokedFunctionArn?: string;
|
|
39
|
+
/** Memory limit in MB. */
|
|
40
|
+
memoryLimitInMB?: string;
|
|
41
|
+
/** The AWS request ID. */
|
|
42
|
+
awsRequestId?: string;
|
|
43
|
+
/** The CloudWatch log group. */
|
|
44
|
+
logGroupName?: string;
|
|
45
|
+
/** The CloudWatch log stream. */
|
|
46
|
+
logStreamName?: string;
|
|
47
|
+
}
|
|
48
|
+
/** Response shape returned by Lambda handlers to API Gateway. */
|
|
49
|
+
export interface LambdaResponse {
|
|
50
|
+
/** HTTP status code. */
|
|
51
|
+
statusCode: number;
|
|
52
|
+
/** The response body string. */
|
|
53
|
+
body: string;
|
|
54
|
+
/** Optional response headers. */
|
|
55
|
+
headers?: Record<string, string>;
|
|
56
|
+
}
|
|
57
|
+
/** A Lambda route handler function. */
|
|
58
|
+
export type RouteHandler = (event: LambdaEvent, context: LambdaContext) => Promise<LambdaResponse>;
|
|
59
|
+
/**
|
|
60
|
+
* A resolved route definition used internally by the entrypoint
|
|
61
|
+
* and deployment logic.
|
|
62
|
+
*/
|
|
63
|
+
export interface Route {
|
|
64
|
+
/** Unique name for the route (e.g. `dynamodb-example-GET`). */
|
|
65
|
+
name: string;
|
|
66
|
+
/** The URL path (e.g. `/dynamodb-example`). */
|
|
67
|
+
path: string;
|
|
68
|
+
/** The HTTP method. */
|
|
69
|
+
method: string;
|
|
70
|
+
/** The allowed CORS origin, if any. */
|
|
71
|
+
corsOrigin?: string;
|
|
72
|
+
/** Request timeout in seconds. */
|
|
73
|
+
timeout: number;
|
|
74
|
+
/** The handler function for this route. */
|
|
75
|
+
handler: RouteHandler;
|
|
76
|
+
/** Lambda memory allocation in MB. */
|
|
77
|
+
memorySize: number;
|
|
78
|
+
/** Environment variable names the Lambda needs. */
|
|
79
|
+
environmentVariables: string[];
|
|
80
|
+
}
|
|
81
|
+
/**
|
|
82
|
+
* The shape of a dynamically imported route module.
|
|
83
|
+
* Each route file can export these named exports.
|
|
84
|
+
*/
|
|
85
|
+
export interface RouteModule {
|
|
86
|
+
/** The route handler (default export). */
|
|
87
|
+
default: RouteHandler;
|
|
88
|
+
/** HTTP methods this route responds to (defaults to `["GET"]`). */
|
|
89
|
+
methods?: string[];
|
|
90
|
+
/** Allowed CORS origin header value. */
|
|
91
|
+
corsOrigin?: string;
|
|
92
|
+
/** Request timeout in seconds. */
|
|
93
|
+
timeout?: number;
|
|
94
|
+
/** Lambda memory size in MB. */
|
|
95
|
+
memorySize?: number;
|
|
96
|
+
/** Environment variable names required by this route. */
|
|
97
|
+
environmentVariables?: string[];
|
|
98
|
+
}
|
|
99
|
+
/** Options for {@link createPulumiAPIApp}. */
|
|
100
|
+
export interface PulumiAPIAppOptions {
|
|
101
|
+
/** The resolved routes to deploy. */
|
|
102
|
+
routes: Route[];
|
|
103
|
+
/** Whether to include devDependencies in the Lambda bundle. */
|
|
104
|
+
bundleDevDependencies?: boolean;
|
|
105
|
+
}
|
|
106
|
+
/** Options for {@link startLocalApp}. */
|
|
107
|
+
export interface LocalAppOptions {
|
|
108
|
+
/** The resolved routes to serve locally. */
|
|
109
|
+
routes: Route[];
|
|
110
|
+
/** The shared Lambda handler function. */
|
|
111
|
+
handler: RouteHandler;
|
|
112
|
+
}
|
|
113
|
+
/** Options for {@link packAndZip}. */
|
|
114
|
+
export interface PackOptions {
|
|
115
|
+
/** Whether to include devDependencies in the bundle. */
|
|
116
|
+
bundleDevDependencies?: boolean;
|
|
117
|
+
}
|
|
118
|
+
/** Result returned by {@link packAndZip}. */
|
|
119
|
+
export interface PackResult {
|
|
120
|
+
/** The filename of the generated zip archive. */
|
|
121
|
+
zipFileName: string;
|
|
122
|
+
/** SHA-256 hash of the zip file for change detection. */
|
|
123
|
+
zipFileHash: string;
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=types.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/lib/types.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,63 +1,55 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@certik/serverless-api",
|
|
3
|
+
"version": "2.0.0",
|
|
3
4
|
"description": "A library that supports quick development and deployment for AWS lambda based serverless APIs",
|
|
5
|
+
"license": "MIT",
|
|
4
6
|
"author": "CertiK Engineering",
|
|
7
|
+
"files": [
|
|
8
|
+
"dist/**/*.js",
|
|
9
|
+
"dist/**/*.d.ts",
|
|
10
|
+
"dist/**/*.d.ts.map",
|
|
11
|
+
"README.md",
|
|
12
|
+
"CHANGELOG.md"
|
|
13
|
+
],
|
|
5
14
|
"type": "module",
|
|
6
|
-
"main": "index.js",
|
|
7
|
-
"
|
|
15
|
+
"main": "dist/index.js",
|
|
16
|
+
"types": "dist/index.d.ts",
|
|
8
17
|
"scripts": {
|
|
9
|
-
"
|
|
10
|
-
"
|
|
11
|
-
"lint
|
|
12
|
-
"format": "
|
|
13
|
-
"
|
|
14
|
-
"test
|
|
18
|
+
"build": "tsc",
|
|
19
|
+
"start": "doppler run -- bun --watch start-dev.ts",
|
|
20
|
+
"lint": "oxlint src test routes *.ts",
|
|
21
|
+
"format": "oxfmt src test routes *.ts",
|
|
22
|
+
"format:check": "oxfmt --check src test routes *.ts",
|
|
23
|
+
"test": "bun test",
|
|
15
24
|
"up": "doppler run -- pulumi up --stack dev",
|
|
16
25
|
"up:production": "doppler run --config prd -- pulumi up --stack production",
|
|
17
26
|
"down": "doppler run -- pulumi down --stack dev",
|
|
18
27
|
"down:production": "doppler run --config prd -- pulumi down --stack production",
|
|
28
|
+
"prepare": "husky",
|
|
29
|
+
"prepublishOnly": "tsc",
|
|
19
30
|
"pub": "npm publish --access public"
|
|
20
31
|
},
|
|
21
32
|
"dependencies": {
|
|
22
|
-
"@pulumi/aws": "^
|
|
23
|
-
"@pulumi/aws-apigateway": "^
|
|
24
|
-
"@pulumi/pulumi": "^3.
|
|
25
|
-
"
|
|
26
|
-
"express": "^4.19.2"
|
|
33
|
+
"@pulumi/aws": "^7.20.0",
|
|
34
|
+
"@pulumi/aws-apigateway": "^3.0.0",
|
|
35
|
+
"@pulumi/pulumi": "^3.224.0",
|
|
36
|
+
"express": "^5.1.0"
|
|
27
37
|
},
|
|
28
38
|
"devDependencies": {
|
|
29
|
-
"@aws-sdk/client-dynamodb": "^3.
|
|
30
|
-
"
|
|
31
|
-
"
|
|
32
|
-
"
|
|
33
|
-
"
|
|
34
|
-
"
|
|
35
|
-
"
|
|
36
|
-
"
|
|
37
|
-
"eslint-plugin-import": "^2.27.5",
|
|
38
|
-
"eslint-plugin-prettier": "^5.0.0",
|
|
39
|
-
"eslint-plugin-promise": "^6.1.1",
|
|
40
|
-
"nodemon": "^3.0.1",
|
|
41
|
-
"prettier": "^3.0.0"
|
|
39
|
+
"@aws-sdk/client-dynamodb": "^3.1000.0",
|
|
40
|
+
"@types/express": "^5.0.0",
|
|
41
|
+
"@types/node": "^25.3.3",
|
|
42
|
+
"husky": "^9.1.7",
|
|
43
|
+
"lint-staged": "^16.3.1",
|
|
44
|
+
"oxfmt": "^0.35.0",
|
|
45
|
+
"oxlint": "^1.50.0",
|
|
46
|
+
"typescript": "^5.7.0"
|
|
42
47
|
},
|
|
43
|
-
"
|
|
44
|
-
"
|
|
45
|
-
"
|
|
46
|
-
"entrypoint.js",
|
|
47
|
-
"README.md",
|
|
48
|
-
"CHANGELOG.md",
|
|
49
|
-
"lib/**/*"
|
|
50
|
-
],
|
|
51
|
-
"engines": {
|
|
52
|
-
"node": ">= 18"
|
|
48
|
+
"lint-staged": {
|
|
49
|
+
"*.{ts,js}": "oxlint",
|
|
50
|
+
"*": "oxfmt --no-error-on-unmatched-pattern"
|
|
53
51
|
},
|
|
54
|
-
"
|
|
55
|
-
|
|
56
|
-
"verbose": true,
|
|
57
|
-
"ignore": [
|
|
58
|
-
"coverage/*",
|
|
59
|
-
"test/*"
|
|
60
|
-
],
|
|
61
|
-
"ext": "js json"
|
|
52
|
+
"engines": {
|
|
53
|
+
"node": ">= 20"
|
|
62
54
|
}
|
|
63
55
|
}
|
package/dev.js
DELETED