@skuba-lib/api 2.2.0 → 3.0.0-add-cdk-NodejsFunction-20260618233139
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/buildkite/package.json +1 -2
- package/cdk/nodejsFunction/package.json +5 -0
- package/cdk/package.json +1 -2
- package/git/package.json +1 -2
- package/github/package.json +1 -2
- package/lib/buildkite/index.mjs +1 -1
- package/lib/{buildkite-DdGh6ljO.mjs → buildkite-DCSmKf_B.mjs} +1 -1
- package/lib/cdk/bridges/rolldown.mjs +50 -0
- package/lib/cdk/index.d.mts +13 -5
- package/lib/cdk/index.mjs +18 -4
- package/lib/cdk/nodejsFunction/index.d.mts +2 -0
- package/lib/cdk/nodejsFunction/index.mjs +334 -0
- package/lib/git/index.mjs +1 -1
- package/lib/{git-CmP3a9Z9.mjs → git-BHbneN9r.mjs} +1 -1
- package/lib/github/index.mjs +2 -2
- package/lib/{github-BUEZ_y2Y.mjs → github-Buehx6Xt.mjs} +2 -2
- package/lib/index-DnMMX6Ji.d.mts +32 -0
- package/lib/index.d.mts +4 -5
- package/lib/index.mjs +5 -6
- package/lib/net/index.mjs +1 -1
- package/lib/{net-Bi0PXcTy.mjs → net-CbEVAvJj.mjs} +1 -1
- package/lib/{rolldown-runtime-D7D4PA-g.mjs → rolldown-runtime-8H4AJuhK.mjs} +1 -0
- package/net/package.json +1 -2
- package/package.json +28 -29
- package/lib/buildkite/index.cjs +0 -4
- package/lib/buildkite/index.d.cts +0 -2
- package/lib/buildkite-_FU8d_a-.cjs +0 -62
- package/lib/cdk/index.cjs +0 -13
- package/lib/cdk/index.d.cts +0 -6
- package/lib/error-BnrwrJEG.cjs +0 -62
- package/lib/exec-Da3EoDZ1.cjs +0 -82
- package/lib/git/index.cjs +0 -14
- package/lib/git/index.d.cts +0 -2
- package/lib/git-D98vomnD.cjs +0 -460
- package/lib/github/index.cjs +0 -12
- package/lib/github/index.d.cts +0 -2
- package/lib/github-D12IboDc.cjs +0 -296
- package/lib/index-C9WMO_Y9.d.cts +0 -278
- package/lib/index-CNxgBJm_.d.cts +0 -39
- package/lib/index-D4JUiy2k.d.cts +0 -259
- package/lib/index-Kyp8ZCwF.d.cts +0 -38
- package/lib/index.cjs +0 -36
- package/lib/index.d.cts +0 -6
- package/lib/net/index.cjs +0 -3
- package/lib/net/index.d.cts +0 -2
- package/lib/net-4Ly1AB2r.cjs +0 -79
- package/lib/rolldown-runtime-DakpK96I.cjs +0 -43
package/buildkite/package.json
CHANGED
package/cdk/package.json
CHANGED
package/git/package.json
CHANGED
package/github/package.json
CHANGED
package/lib/buildkite/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as md, r as annotate } from "../buildkite-
|
|
1
|
+
import { n as md, r as annotate } from "../buildkite-DCSmKf_B.mjs";
|
|
2
2
|
export { annotate, md };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
|
|
2
2
|
import { n as log } from "./error-BYLsj5YU.mjs";
|
|
3
3
|
import { n as exec, r as hasCommand } from "./exec-CbhqWxN4.mjs";
|
|
4
4
|
//#region src/buildkite/annotate.ts
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { pathToFileURL } from "node:url";
|
|
2
|
+
import { rolldown } from "rolldown";
|
|
3
|
+
//#region src/cdk/nodejsFunction/util.ts
|
|
4
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
5
|
+
//#endregion
|
|
6
|
+
//#region src/cdk/nodejsFunction/bridges/rolldown.mts
|
|
7
|
+
const [configPath, entry, outputDir] = process.argv.slice(2, 5);
|
|
8
|
+
if (!configPath || !entry || !outputDir) throw new Error("Expected arguments: <configPath> <entry> <outputDir>");
|
|
9
|
+
const mod = await import(pathToFileURL(configPath).href);
|
|
10
|
+
const root = isRecord(mod) ? mod.default : void 0;
|
|
11
|
+
const userConfig = isRecord(root) ? root : void 0;
|
|
12
|
+
if (!userConfig) throw new Error(`Config file must export a default config object: ${configPath}`);
|
|
13
|
+
const rawOutput = userConfig.output;
|
|
14
|
+
if (Array.isArray(rawOutput) && rawOutput.length !== 1) {
|
|
15
|
+
const detail = rawOutput.length === 0 ? "the `output` array is empty" : `the \`output\` array contains ${rawOutput.length} entries`;
|
|
16
|
+
throw new Error(`\`output\` must contain exactly one entry but ${detail}: NodejsFunction emits a single index.mjs handler.`);
|
|
17
|
+
}
|
|
18
|
+
const rawBase = Array.isArray(rawOutput) ? rawOutput[0] : rawOutput;
|
|
19
|
+
if (rawBase !== void 0 && !isRecord(rawBase)) throw new Error("`output` must be a configuration object: NodejsFunction emits a single index.mjs handler.");
|
|
20
|
+
const baseRaw = isRecord(rawBase) ? rawBase : {};
|
|
21
|
+
if (baseRaw.preserveModules) throw new Error("`output.preserveModules` is not supported: NodejsFunction emits a single index.mjs handler.");
|
|
22
|
+
if (baseRaw.entryFileNames !== void 0) throw new Error("`output.entryFileNames` is not supported: NodejsFunction names the handler index.mjs itself.");
|
|
23
|
+
if (baseRaw.chunkFileNames !== void 0) throw new Error("`output.chunkFileNames` is not supported: NodejsFunction names the handler index.mjs and lets rolldown name split chunks to avoid collisions.");
|
|
24
|
+
if (baseRaw.file !== void 0) throw new Error("`output.file` is not supported: NodejsFunction writes index.mjs into the output directory itself.");
|
|
25
|
+
if (userConfig.input !== void 0) throw new Error("`input` is not supported: NodejsFunction sets the bundle entry itself.");
|
|
26
|
+
const format = typeof baseRaw.format === "string" ? baseRaw.format : void 0;
|
|
27
|
+
if (format !== void 0 && ![
|
|
28
|
+
"es",
|
|
29
|
+
"esm",
|
|
30
|
+
"module"
|
|
31
|
+
].includes(format)) throw new Error("`output.format` must be ESM (es/esm/module): NodejsFunction emits an ESM index.mjs handler.");
|
|
32
|
+
const { output: _output, ...userConfigRest } = userConfig;
|
|
33
|
+
const inputOptions = {
|
|
34
|
+
...userConfigRest,
|
|
35
|
+
input: entry
|
|
36
|
+
};
|
|
37
|
+
const outputOptions = {
|
|
38
|
+
...baseRaw,
|
|
39
|
+
format: "es",
|
|
40
|
+
dir: outputDir,
|
|
41
|
+
entryFileNames: "index.mjs"
|
|
42
|
+
};
|
|
43
|
+
const bundle = await rolldown(inputOptions);
|
|
44
|
+
try {
|
|
45
|
+
await bundle.write(outputOptions);
|
|
46
|
+
} finally {
|
|
47
|
+
await bundle.close();
|
|
48
|
+
}
|
|
49
|
+
//#endregion
|
|
50
|
+
export {};
|
package/lib/cdk/index.d.mts
CHANGED
|
@@ -1,6 +1,14 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
4
|
-
declare const
|
|
1
|
+
import { i as ICommandHooks, n as NodejsFunctionProps, r as BundlingOptions, t as NodejsFunction } from "../index-DnMMX6Ji.mjs";
|
|
2
|
+
|
|
3
|
+
//#region src/cdk/index.d.ts
|
|
4
|
+
declare const Cdk: {
|
|
5
|
+
normaliseTemplate: (template: object) => unknown;
|
|
6
|
+
/**
|
|
7
|
+
* Lazily loads {@link NodejsFunction} on first access so that the optional
|
|
8
|
+
* `aws-cdk-lib` and `constructs` peer dependencies are only required by
|
|
9
|
+
* consumers that actually use the construct.
|
|
10
|
+
*/
|
|
11
|
+
readonly NodejsFunction: typeof NodejsFunction;
|
|
12
|
+
};
|
|
5
13
|
//#endregion
|
|
6
|
-
export {
|
|
14
|
+
export { type BundlingOptions, Cdk, type ICommandHooks, type NodejsFunctionProps };
|
package/lib/cdk/index.mjs
CHANGED
|
@@ -1,7 +1,21 @@
|
|
|
1
|
-
import {
|
|
2
|
-
//#region src/cdk/index.ts
|
|
3
|
-
var cdk_exports = /* @__PURE__ */ __exportAll({ normaliseTemplate: () => normaliseTemplate });
|
|
1
|
+
import { createRequire } from "node:module";
|
|
2
|
+
//#region src/cdk/normaliseTemplate/index.ts
|
|
4
3
|
const normaliseTemplateJsonString = (json) => json.replace(/"S3Key":"([0-9a-f]+)\.zip"/g, (_, hash) => `"S3Key":"${"x".repeat(hash.length)}.zip"`).replace(/workerCurrentVersion([0-9a-zA-Z]+)"/g, (_, hash) => `workerCurrentVersion${"x".repeat(hash.length)}"`).replaceAll(/"Value":"\d+\.\d+\.\d+-([^"]+)"/g, (_, hash) => `"Value": "x.x.x-${"x".repeat(hash.length)}"`).replaceAll(/"Value":"v\d+\.\d+\.\d+"/g, (_) => "\"Value\": \"vx.x.x\"").replace(/"DD_TAGS":"git.commit.sha:([0-9a-f]+),git.repository_url:([^\"]+)",/g, "").replaceAll(/(layer:Datadog-[^-]+-.+?:)\d+/g, (_, layer) => `${layer}x`);
|
|
5
4
|
const normaliseTemplate = (template) => JSON.parse(normaliseTemplateJsonString(JSON.stringify(template)));
|
|
6
5
|
//#endregion
|
|
7
|
-
|
|
6
|
+
//#region src/cdk/index.ts
|
|
7
|
+
const require = createRequire(import.meta.url);
|
|
8
|
+
let cached;
|
|
9
|
+
const Cdk = {
|
|
10
|
+
normaliseTemplate,
|
|
11
|
+
/**
|
|
12
|
+
* Lazily loads {@link NodejsFunction} on first access so that the optional
|
|
13
|
+
* `aws-cdk-lib` and `constructs` peer dependencies are only required by
|
|
14
|
+
* consumers that actually use the construct.
|
|
15
|
+
*/
|
|
16
|
+
get NodejsFunction() {
|
|
17
|
+
return cached ??= require("@skuba-lib/api/cdk/nodejsFunction").NodejsFunction;
|
|
18
|
+
}
|
|
19
|
+
};
|
|
20
|
+
//#endregion
|
|
21
|
+
export { Cdk };
|
|
@@ -0,0 +1,334 @@
|
|
|
1
|
+
import { findPackageJSON } from "node:module";
|
|
2
|
+
import * as fs from "node:fs";
|
|
3
|
+
import * as path from "node:path";
|
|
4
|
+
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
5
|
+
import { spawnSync } from "node:child_process";
|
|
6
|
+
import * as cdk from "aws-cdk-lib";
|
|
7
|
+
import { fileURLToPath, pathToFileURL } from "node:url";
|
|
8
|
+
import { parse, stringify } from "yaml";
|
|
9
|
+
//#region src/cdk/nodejsFunction/errors.ts
|
|
10
|
+
var ValidationError = class extends Error {
|
|
11
|
+
constructor(message) {
|
|
12
|
+
super(message);
|
|
13
|
+
this.name = "ValidationError";
|
|
14
|
+
}
|
|
15
|
+
};
|
|
16
|
+
//#endregion
|
|
17
|
+
//#region src/cdk/nodejsFunction/util.ts
|
|
18
|
+
const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
|
|
19
|
+
const isInside = (parent, child) => {
|
|
20
|
+
const rel = path.relative(path.resolve(parent), path.resolve(child));
|
|
21
|
+
return rel === "" || !rel.startsWith("..") && !path.isAbsolute(rel);
|
|
22
|
+
};
|
|
23
|
+
const parseJsonFile = (filePath) => {
|
|
24
|
+
try {
|
|
25
|
+
return JSON.parse(fs.readFileSync(filePath, "utf-8"));
|
|
26
|
+
} catch (err) {
|
|
27
|
+
throw new ValidationError(`Failed to parse ${filePath} as JSON: ${err.message}`);
|
|
28
|
+
}
|
|
29
|
+
};
|
|
30
|
+
const findUp = (name, directory = process.cwd()) => {
|
|
31
|
+
const absoluteDirectory = path.resolve(directory);
|
|
32
|
+
const file = path.join(absoluteDirectory, name);
|
|
33
|
+
if (fs.existsSync(file)) return file;
|
|
34
|
+
const { root } = path.parse(absoluteDirectory);
|
|
35
|
+
if (absoluteDirectory === root) return;
|
|
36
|
+
return findUp(name, path.dirname(absoluteDirectory));
|
|
37
|
+
};
|
|
38
|
+
const extractDependencies = (pkgPath, modules) => {
|
|
39
|
+
const result = {};
|
|
40
|
+
const base = pathToFileURL(pkgPath);
|
|
41
|
+
for (const mod of modules) {
|
|
42
|
+
let modPkgPath;
|
|
43
|
+
try {
|
|
44
|
+
modPkgPath = findPackageJSON(mod, base);
|
|
45
|
+
} catch {
|
|
46
|
+
modPkgPath = void 0;
|
|
47
|
+
}
|
|
48
|
+
const parsed = modPkgPath ? parseJsonFile(modPkgPath) : void 0;
|
|
49
|
+
const version = isRecord(parsed) && typeof parsed.version === "string" ? parsed.version.trim() : void 0;
|
|
50
|
+
if (!version) throw new ValidationError(`Cannot extract version for module '${mod}'. Check that it's referenced in your package.json or installed.`);
|
|
51
|
+
result[mod] = version;
|
|
52
|
+
}
|
|
53
|
+
return result;
|
|
54
|
+
};
|
|
55
|
+
//#endregion
|
|
56
|
+
//#region src/cdk/nodejsFunction/bridge-path.ts
|
|
57
|
+
const findPackageRoot = (moduleUrl) => {
|
|
58
|
+
const pkg = findUp("package.json", path.dirname(fileURLToPath(moduleUrl)));
|
|
59
|
+
if (!pkg) throw new ValidationError("Unable to locate the package root to resolve the bundler bridge script.");
|
|
60
|
+
return path.dirname(pkg);
|
|
61
|
+
};
|
|
62
|
+
const BRIDGE_RELATIVE_PATH = path.join("lib", "cdk", "bridges", "rolldown.mjs");
|
|
63
|
+
const resolveRolldownBridge = () => path.join(findPackageRoot(import.meta.url), BRIDGE_RELATIVE_PATH);
|
|
64
|
+
//#endregion
|
|
65
|
+
//#region src/cdk/nodejsFunction/package-manager.ts
|
|
66
|
+
const PNPM_LOCK = "pnpm-lock.yaml";
|
|
67
|
+
const PNPM_WORKSPACE_FILES = [
|
|
68
|
+
"pnpm-workspace.yaml",
|
|
69
|
+
".npmrc",
|
|
70
|
+
".pnpmfile.cjs",
|
|
71
|
+
".pnpmfile.mjs"
|
|
72
|
+
];
|
|
73
|
+
const PNPM_INSTALL_COMMAND = [
|
|
74
|
+
"pnpm",
|
|
75
|
+
"install",
|
|
76
|
+
"--config.node-linker=hoisted",
|
|
77
|
+
"--config.package-import-method=clone-or-copy",
|
|
78
|
+
"--no-frozen-lockfile"
|
|
79
|
+
];
|
|
80
|
+
const assertPnpm = (name, source, pkgPath) => {
|
|
81
|
+
if (name !== "pnpm") throw new ValidationError(`Unsupported package manager '${name}' declared in ${source} of ${pkgPath}. NodejsFunction only supports pnpm.`);
|
|
82
|
+
};
|
|
83
|
+
const readPackageManagerMeta = (projectRoot) => {
|
|
84
|
+
const pkgPath = path.join(projectRoot, "package.json");
|
|
85
|
+
const nearestPackageJson = fs.existsSync(pkgPath) ? pkgPath : void 0;
|
|
86
|
+
if (!nearestPackageJson) return {
|
|
87
|
+
nearestPackageJson,
|
|
88
|
+
packageManagerField: void 0
|
|
89
|
+
};
|
|
90
|
+
const parsed = parseJsonFile(pkgPath);
|
|
91
|
+
if (!isRecord(parsed)) return {
|
|
92
|
+
nearestPackageJson,
|
|
93
|
+
packageManagerField: void 0
|
|
94
|
+
};
|
|
95
|
+
if (isRecord(parsed.devEngines)) {
|
|
96
|
+
const devEnginesPm = parsed.devEngines.packageManager;
|
|
97
|
+
if (isRecord(devEnginesPm) && typeof devEnginesPm.name === "string") assertPnpm(devEnginesPm.name, "the `devEngines.packageManager` field", pkgPath);
|
|
98
|
+
}
|
|
99
|
+
if (typeof parsed.packageManager === "string" && parsed.packageManager.includes("@")) {
|
|
100
|
+
assertPnpm(parsePackageName(parsed.packageManager), "the `packageManager` field", pkgPath);
|
|
101
|
+
return {
|
|
102
|
+
nearestPackageJson,
|
|
103
|
+
packageManagerField: parsed.packageManager
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
return {
|
|
107
|
+
nearestPackageJson,
|
|
108
|
+
packageManagerField: void 0
|
|
109
|
+
};
|
|
110
|
+
};
|
|
111
|
+
const parsePackageName = (spec) => {
|
|
112
|
+
const at = spec.indexOf("@", spec.startsWith("@") ? 1 : 0);
|
|
113
|
+
return at === -1 ? spec : spec.slice(0, at);
|
|
114
|
+
};
|
|
115
|
+
const injectIgnoreScripts = (outputDir, stagedFiles) => {
|
|
116
|
+
const target = path.join(outputDir, ".npmrc");
|
|
117
|
+
const filtered = (fs.existsSync(target) ? fs.readFileSync(target, "utf8") : "").split("\n").filter((line) => !/^ignore-scripts\s*=/.test(line)).join("\n");
|
|
118
|
+
const sep = filtered.length > 0 && !filtered.endsWith("\n") ? "\n" : "";
|
|
119
|
+
fs.writeFileSync(target, `${filtered}${sep}ignore-scripts=true\n`);
|
|
120
|
+
if (!stagedFiles.includes(target)) stagedFiles.push(target);
|
|
121
|
+
};
|
|
122
|
+
const copyPatchFile = (relativePath, projectRoot, outputDir, copiedFiles) => {
|
|
123
|
+
const src = path.join(projectRoot, relativePath);
|
|
124
|
+
const dest = path.join(outputDir, relativePath);
|
|
125
|
+
if (!isInside(projectRoot, src) || !isInside(outputDir, dest)) throw new ValidationError(`Refusing to copy pnpm patch '${relativePath}': it resolves outside the project root or output directory.`);
|
|
126
|
+
if (!fs.existsSync(src)) return;
|
|
127
|
+
const realSrc = fs.realpathSync(src);
|
|
128
|
+
if (!isInside(fs.realpathSync(projectRoot), realSrc)) throw new ValidationError(`Refusing to copy pnpm patch '${relativePath}': it resolves (via symlink) outside the project root.`);
|
|
129
|
+
fs.mkdirSync(path.dirname(dest), { recursive: true });
|
|
130
|
+
fs.copyFileSync(realSrc, dest);
|
|
131
|
+
copiedFiles.push(dest);
|
|
132
|
+
};
|
|
133
|
+
const filterPnpmWorkspaceYaml = (content, nodeModules, projectRoot, outputDir, copiedFiles) => {
|
|
134
|
+
let doc;
|
|
135
|
+
try {
|
|
136
|
+
doc = parse(content);
|
|
137
|
+
} catch (err) {
|
|
138
|
+
throw new ValidationError(`Failed to parse pnpm-workspace.yaml: ${err.message}`);
|
|
139
|
+
}
|
|
140
|
+
if (!isRecord(doc) || !("patchedDependencies" in doc)) return content;
|
|
141
|
+
const patched = doc.patchedDependencies;
|
|
142
|
+
if (!isRecord(patched)) {
|
|
143
|
+
delete doc.patchedDependencies;
|
|
144
|
+
return stringify(doc);
|
|
145
|
+
}
|
|
146
|
+
const nodeModuleSet = new Set(nodeModules);
|
|
147
|
+
for (const [key, value] of Object.entries(patched)) {
|
|
148
|
+
const pkgName = parsePackageName(key);
|
|
149
|
+
if (!nodeModuleSet.has(pkgName)) delete patched[key];
|
|
150
|
+
else if (typeof value === "string" && value) copyPatchFile(value, projectRoot, outputDir, copiedFiles);
|
|
151
|
+
}
|
|
152
|
+
if (Object.keys(patched).length === 0) delete doc.patchedDependencies;
|
|
153
|
+
return stringify(doc);
|
|
154
|
+
};
|
|
155
|
+
const copyWorkspaceFiles = (projectRoot, outputDir, nodeModules = [], ignoreScripts = false, stagedFiles = []) => {
|
|
156
|
+
for (const file of PNPM_WORKSPACE_FILES) {
|
|
157
|
+
const src = path.join(projectRoot, file);
|
|
158
|
+
if (!fs.existsSync(src)) continue;
|
|
159
|
+
const dest = path.join(outputDir, file);
|
|
160
|
+
if (file === "pnpm-workspace.yaml") {
|
|
161
|
+
const filtered = filterPnpmWorkspaceYaml(fs.readFileSync(src, "utf8"), nodeModules, projectRoot, outputDir, stagedFiles);
|
|
162
|
+
fs.writeFileSync(dest, filtered);
|
|
163
|
+
} else fs.copyFileSync(src, dest);
|
|
164
|
+
stagedFiles.push(dest);
|
|
165
|
+
}
|
|
166
|
+
if (ignoreScripts) injectIgnoreScripts(outputDir, stagedFiles);
|
|
167
|
+
};
|
|
168
|
+
//#endregion
|
|
169
|
+
//#region src/cdk/nodejsFunction/bundling.ts
|
|
170
|
+
const SPAWN_MAX_BUFFER = 16 * 1024 * 1024;
|
|
171
|
+
const stderrTail = (stderr) => {
|
|
172
|
+
if (!stderr) return "";
|
|
173
|
+
const tail = stderr.trimEnd().split("\n").slice(-20).join("\n");
|
|
174
|
+
return tail ? `\n\n${tail}` : "";
|
|
175
|
+
};
|
|
176
|
+
const checkSpawnResult = (result, prefix) => {
|
|
177
|
+
if (result.error) {
|
|
178
|
+
const code = result.error.code;
|
|
179
|
+
if (code === "ETIMEDOUT") throw new ValidationError(`${prefix} timed out.${stderrTail(result.stderr)}`);
|
|
180
|
+
if (code === "ENOBUFS") throw new ValidationError(`${prefix} produced more than ${SPAWN_MAX_BUFFER / (1024 * 1024)}MB of output.${stderrTail(result.stderr)}`);
|
|
181
|
+
throw result.error;
|
|
182
|
+
}
|
|
183
|
+
if (result.status !== 0) throw new ValidationError(`${prefix} ${result.signal != null ? `killed by signal ${result.signal}` : `exited with status ${result.status}`}.${stderrTail(result.stderr)}`);
|
|
184
|
+
if (result.stderr) process.stderr.write(result.stderr);
|
|
185
|
+
};
|
|
186
|
+
const writeOutputPackageJson = (outputDir, fields) => {
|
|
187
|
+
const pkg = {
|
|
188
|
+
type: "module",
|
|
189
|
+
dependencies: fields.dependencies,
|
|
190
|
+
packageManager: fields.packageManager
|
|
191
|
+
};
|
|
192
|
+
fs.writeFileSync(path.join(outputDir, "package.json"), JSON.stringify(pkg, null, 2));
|
|
193
|
+
};
|
|
194
|
+
const removeEmptyParentDirs = (startDir, outputDir) => {
|
|
195
|
+
let dir = startDir;
|
|
196
|
+
while (dir !== outputDir && isInside(outputDir, dir)) {
|
|
197
|
+
try {
|
|
198
|
+
fs.rmdirSync(dir);
|
|
199
|
+
} catch {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
dir = path.dirname(dir);
|
|
203
|
+
}
|
|
204
|
+
};
|
|
205
|
+
var Bundling = class Bundling {
|
|
206
|
+
props;
|
|
207
|
+
static bundle(props) {
|
|
208
|
+
return lambda.Code.fromAsset(props.projectRoot, {
|
|
209
|
+
assetHash: props.assetHash,
|
|
210
|
+
assetHashType: props.assetHash ? cdk.AssetHashType.CUSTOM : cdk.AssetHashType.OUTPUT,
|
|
211
|
+
bundling: new Bundling(props)
|
|
212
|
+
});
|
|
213
|
+
}
|
|
214
|
+
image;
|
|
215
|
+
local;
|
|
216
|
+
constructor(props) {
|
|
217
|
+
this.props = props;
|
|
218
|
+
this.image = cdk.DockerImage.fromRegistry("dummy");
|
|
219
|
+
this.local = this.buildLocalBundling();
|
|
220
|
+
}
|
|
221
|
+
buildLocalBundling() {
|
|
222
|
+
return { tryBundle: (outputDir) => {
|
|
223
|
+
this.runHooks(this.props.commandHooks?.beforeBundling(this.props.projectRoot, outputDir) ?? [], this.props.projectRoot);
|
|
224
|
+
this.runBundler(outputDir);
|
|
225
|
+
const { nodeModules } = this.props;
|
|
226
|
+
if (nodeModules?.length) this.installNodeModules(outputDir, nodeModules);
|
|
227
|
+
else writeOutputPackageJson(outputDir, {});
|
|
228
|
+
this.runHooks(this.props.commandHooks?.afterBundling(this.props.projectRoot, outputDir) ?? [], this.props.projectRoot);
|
|
229
|
+
return true;
|
|
230
|
+
} };
|
|
231
|
+
}
|
|
232
|
+
runHooks(commands, cwd) {
|
|
233
|
+
for (const cmd of commands) this.spawn(cmd, [], cwd, `Command hook '${cmd}'`, { shell: true });
|
|
234
|
+
}
|
|
235
|
+
runBundler(outputDir) {
|
|
236
|
+
this.spawn("node", [
|
|
237
|
+
resolveRolldownBridge(),
|
|
238
|
+
this.props.bundlerConfig,
|
|
239
|
+
this.props.entry,
|
|
240
|
+
outputDir
|
|
241
|
+
], this.props.projectRoot, "Bundler 'rolldown'");
|
|
242
|
+
}
|
|
243
|
+
installNodeModules(outputDir, nodeModules) {
|
|
244
|
+
const { nearestPackageJson, packageManagerField } = readPackageManagerMeta(this.props.projectRoot);
|
|
245
|
+
if (!nearestPackageJson) throw new ValidationError("Cannot find a package.json. Using nodeModules requires a package.json.");
|
|
246
|
+
this.runHooks(this.props.commandHooks?.beforeInstall(this.props.projectRoot, outputDir) ?? [], this.props.projectRoot);
|
|
247
|
+
writeOutputPackageJson(outputDir, {
|
|
248
|
+
dependencies: extractDependencies(nearestPackageJson, nodeModules),
|
|
249
|
+
packageManager: packageManagerField
|
|
250
|
+
});
|
|
251
|
+
const stagedFiles = [];
|
|
252
|
+
try {
|
|
253
|
+
copyWorkspaceFiles(this.props.projectRoot, outputDir, nodeModules, this.props.ignoreScripts, stagedFiles);
|
|
254
|
+
if (fs.existsSync(this.props.depsLockFilePath)) {
|
|
255
|
+
const lockDest = path.join(outputDir, PNPM_LOCK);
|
|
256
|
+
fs.copyFileSync(this.props.depsLockFilePath, lockDest);
|
|
257
|
+
stagedFiles.push(lockDest);
|
|
258
|
+
}
|
|
259
|
+
const [installBin, ...installArgs] = PNPM_INSTALL_COMMAND;
|
|
260
|
+
this.spawn(installBin, installArgs, outputDir, "Package manager 'pnpm' install");
|
|
261
|
+
} finally {
|
|
262
|
+
for (const file of stagedFiles) {
|
|
263
|
+
fs.rmSync(file, { force: true });
|
|
264
|
+
removeEmptyParentDirs(path.dirname(file), outputDir);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
}
|
|
268
|
+
spawn(bin, args, cwd, prefix, opts) {
|
|
269
|
+
checkSpawnResult(spawnSync(bin, args, {
|
|
270
|
+
env: process.env,
|
|
271
|
+
stdio: [
|
|
272
|
+
"ignore",
|
|
273
|
+
"inherit",
|
|
274
|
+
"pipe"
|
|
275
|
+
],
|
|
276
|
+
cwd,
|
|
277
|
+
timeout: this.props.timeout,
|
|
278
|
+
encoding: "utf-8",
|
|
279
|
+
maxBuffer: SPAWN_MAX_BUFFER,
|
|
280
|
+
shell: opts?.shell
|
|
281
|
+
}), prefix);
|
|
282
|
+
}
|
|
283
|
+
};
|
|
284
|
+
//#endregion
|
|
285
|
+
//#region src/cdk/nodejsFunction/function.ts
|
|
286
|
+
var NodejsFunction = class extends lambda.Function {
|
|
287
|
+
constructor(scope, id, props) {
|
|
288
|
+
if (props.runtime && props.runtime.family !== lambda.RuntimeFamily.NODEJS) throw new ValidationError("Only NODEJS runtimes are supported.");
|
|
289
|
+
const runtime = props.runtime ?? lambda.Runtime.NODEJS_LATEST;
|
|
290
|
+
const entry = validateEntry(props.entry);
|
|
291
|
+
const depsLockFilePath = findLockFile(props.depsLockFilePath);
|
|
292
|
+
const projectRoot = path.resolve(props.projectRoot ?? path.dirname(depsLockFilePath));
|
|
293
|
+
const bundlerConfig = path.resolve(projectRoot, props.bundling.bundlerConfig);
|
|
294
|
+
const handlerFn = resolveHandlerFn(props.handler);
|
|
295
|
+
const { entry: _entry, bundling, depsLockFilePath: _depsLockFilePath, projectRoot: _projectRoot, handler: _handler, runtime: _runtime, ...functionOptions } = props;
|
|
296
|
+
super(scope, id, {
|
|
297
|
+
...functionOptions,
|
|
298
|
+
runtime,
|
|
299
|
+
code: Bundling.bundle({
|
|
300
|
+
...bundling,
|
|
301
|
+
bundlerConfig,
|
|
302
|
+
entry,
|
|
303
|
+
depsLockFilePath,
|
|
304
|
+
projectRoot
|
|
305
|
+
}),
|
|
306
|
+
handler: `index.${handlerFn}`
|
|
307
|
+
});
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
const resolveHandlerFn = (handler) => {
|
|
311
|
+
const handlerName = (handler ?? "handler").trim();
|
|
312
|
+
const handlerFn = handlerName.slice(handlerName.lastIndexOf(".") + 1);
|
|
313
|
+
if (!/^[A-Za-z_$][\w$]*$/.test(handlerFn)) throw new ValidationError(`Invalid handler '${handler}'. Expected an exported function name, optionally prefixed with a file part (e.g. 'handler' or 'index.handler').`);
|
|
314
|
+
return handlerFn;
|
|
315
|
+
};
|
|
316
|
+
const validateEntry = (entry) => {
|
|
317
|
+
const base = path.basename(entry);
|
|
318
|
+
if (/\.d\.(c|m)?ts$/i.test(base) || !/\.(js|ts|mjs|mts|cts|cjs)$/i.test(base)) throw new ValidationError("Only JavaScript or TypeScript entry files are supported.");
|
|
319
|
+
const resolved = path.resolve(entry);
|
|
320
|
+
if (!fs.existsSync(resolved)) throw new ValidationError(`Cannot find the entry file at '${entry}'.`);
|
|
321
|
+
return resolved;
|
|
322
|
+
};
|
|
323
|
+
const findLockFile = (depsLockFilePath) => {
|
|
324
|
+
if (depsLockFilePath) {
|
|
325
|
+
const resolved = path.resolve(depsLockFilePath);
|
|
326
|
+
if (!fs.existsSync(resolved)) throw new ValidationError(`Cannot find a pnpm-lock.yaml file at '${depsLockFilePath}'.`);
|
|
327
|
+
return resolved;
|
|
328
|
+
}
|
|
329
|
+
const lockFile = findUp(PNPM_LOCK);
|
|
330
|
+
if (!lockFile) throw new ValidationError("Cannot find a pnpm-lock.yaml file. Please specify it with `depsLockFilePath`.");
|
|
331
|
+
return lockFile;
|
|
332
|
+
};
|
|
333
|
+
//#endregion
|
|
334
|
+
export { NodejsFunction };
|
package/lib/git/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { a as push, d as getHeadCommitMessage, f as currentBranch, g as commit, h as findRoot, i as fastForwardBranch, l as getOwnerAndRepo, m as getChangedFiles, n as isFileGitIgnored, p as commitAllChanges, r as reset, u as getHeadCommitId } from "../git-
|
|
1
|
+
import { a as push, d as getHeadCommitMessage, f as currentBranch, g as commit, h as findRoot, i as fastForwardBranch, l as getOwnerAndRepo, m as getChangedFiles, n as isFileGitIgnored, p as commitAllChanges, r as reset, u as getHeadCommitId } from "../git-BHbneN9r.mjs";
|
|
2
2
|
export { commit, commitAllChanges, currentBranch, fastForwardBranch, findRoot, getChangedFiles, getHeadCommitId, getHeadCommitMessage, getOwnerAndRepo, isFileGitIgnored, push, reset };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
|
|
2
2
|
import { t as isErrorWithCode } from "./error-BYLsj5YU.mjs";
|
|
3
3
|
import fs from "fs-extra";
|
|
4
4
|
import git, { findRoot } from "isomorphic-git";
|
package/lib/github/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import { c as enabledFromEnvironment, o as apiTokenFromEnvironment, s as buildNameFromEnvironment } from "../git-
|
|
2
|
-
import { a as putIssueComment, i as uploadFileChanges, n as readFileChanges, o as getPullRequestNumber, r as uploadAllFileChanges, s as createCheckRun } from "../github-
|
|
1
|
+
import { c as enabledFromEnvironment, o as apiTokenFromEnvironment, s as buildNameFromEnvironment } from "../git-BHbneN9r.mjs";
|
|
2
|
+
import { a as putIssueComment, i as uploadFileChanges, n as readFileChanges, o as getPullRequestNumber, r as uploadAllFileChanges, s as createCheckRun } from "../github-Buehx6Xt.mjs";
|
|
3
3
|
export { apiTokenFromEnvironment, buildNameFromEnvironment, createCheckRun, enabledFromEnvironment, getPullRequestNumber, putIssueComment, readFileChanges, uploadAllFileChanges, uploadFileChanges };
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { t as __exportAll } from "./rolldown-runtime-
|
|
1
|
+
import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.mjs";
|
|
2
2
|
import { r as pluralise } from "./error-BYLsj5YU.mjs";
|
|
3
|
-
import { c as enabledFromEnvironment, h as findRoot, i as fastForwardBranch, l as getOwnerAndRepo, m as getChangedFiles, o as apiTokenFromEnvironment, s as buildNameFromEnvironment, u as getHeadCommitId } from "./git-
|
|
3
|
+
import { c as enabledFromEnvironment, h as findRoot, i as fastForwardBranch, l as getOwnerAndRepo, m as getChangedFiles, o as apiTokenFromEnvironment, s as buildNameFromEnvironment, u as getHeadCommitId } from "./git-BHbneN9r.mjs";
|
|
4
4
|
import fs from "fs-extra";
|
|
5
5
|
import path from "path";
|
|
6
6
|
//#region src/github/octokit.ts
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import * as lambda from "aws-cdk-lib/aws-lambda";
|
|
2
|
+
import { Construct } from "constructs";
|
|
3
|
+
|
|
4
|
+
//#region src/cdk/nodejsFunction/types.d.ts
|
|
5
|
+
interface ICommandHooks {
|
|
6
|
+
beforeBundling(inputDir: string, outputDir: string): string[];
|
|
7
|
+
afterBundling(inputDir: string, outputDir: string): string[];
|
|
8
|
+
beforeInstall(inputDir: string, outputDir: string): string[];
|
|
9
|
+
}
|
|
10
|
+
interface BundlingOptions {
|
|
11
|
+
bundlerConfig: string;
|
|
12
|
+
nodeModules?: string[];
|
|
13
|
+
commandHooks?: ICommandHooks;
|
|
14
|
+
assetHash?: string;
|
|
15
|
+
timeout?: number;
|
|
16
|
+
ignoreScripts?: boolean;
|
|
17
|
+
}
|
|
18
|
+
//#endregion
|
|
19
|
+
//#region src/cdk/nodejsFunction/function.d.ts
|
|
20
|
+
interface NodejsFunctionProps extends lambda.FunctionOptions {
|
|
21
|
+
readonly entry: string;
|
|
22
|
+
readonly handler?: string;
|
|
23
|
+
readonly runtime?: lambda.Runtime;
|
|
24
|
+
readonly depsLockFilePath?: string;
|
|
25
|
+
readonly projectRoot?: string;
|
|
26
|
+
readonly bundling: BundlingOptions;
|
|
27
|
+
}
|
|
28
|
+
declare class NodejsFunction extends lambda.Function {
|
|
29
|
+
constructor(scope: Construct, id: string, props: NodejsFunctionProps);
|
|
30
|
+
}
|
|
31
|
+
//#endregion
|
|
32
|
+
export { ICommandHooks as i, NodejsFunctionProps as n, BundlingOptions as r, NodejsFunction as t };
|
package/lib/index.d.mts
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { t as index_d_exports } from "./index-CNxgBJm_.mjs";
|
|
2
|
-
import { t as index_d_exports$1 } from "./
|
|
3
|
-
import { t as index_d_exports$2 } from "./index-
|
|
4
|
-
import { t as index_d_exports$3 } from "./index-
|
|
5
|
-
|
|
6
|
-
export { index_d_exports as Buildkite, index_d_exports$1 as Cdk, index_d_exports$2 as Git, index_d_exports$3 as GitHub, index_d_exports$4 as Net };
|
|
2
|
+
import { t as index_d_exports$1 } from "./index-C9WMO_Y9.mjs";
|
|
3
|
+
import { t as index_d_exports$2 } from "./index-DbjgHTTm.mjs";
|
|
4
|
+
import { t as index_d_exports$3 } from "./index-Kyp8ZCwF.mjs";
|
|
5
|
+
export { index_d_exports as Buildkite, index_d_exports$1 as Git, index_d_exports$2 as GitHub, index_d_exports$3 as Net };
|
package/lib/index.mjs
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import { t as buildkite_exports } from "./buildkite-
|
|
2
|
-
import { t as
|
|
3
|
-
import { t as
|
|
4
|
-
import { t as
|
|
5
|
-
|
|
6
|
-
export { buildkite_exports as Buildkite, cdk_exports as Cdk, git_exports as Git, github_exports as GitHub, net_exports as Net };
|
|
1
|
+
import { t as buildkite_exports } from "./buildkite-DCSmKf_B.mjs";
|
|
2
|
+
import { t as git_exports } from "./git-BHbneN9r.mjs";
|
|
3
|
+
import { t as github_exports } from "./github-Buehx6Xt.mjs";
|
|
4
|
+
import { t as net_exports } from "./net-CbEVAvJj.mjs";
|
|
5
|
+
export { buildkite_exports as Buildkite, git_exports as Git, github_exports as GitHub, net_exports as Net };
|
package/lib/net/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as waitFor } from "../net-
|
|
1
|
+
import { n as waitFor } from "../net-CbEVAvJj.mjs";
|
|
2
2
|
export { waitFor };
|