@skuba-lib/api 2.3.0-rolldown-cdk-bundle-plugin-20260804001207 → 2.3.0-rolldown-cdk-bundle-plugin-20260804234000

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.
@@ -0,0 +1,21 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-DakpK96I.cjs");
2
+ const require_error = require("./error-BSBcaHO0.cjs");
3
+ let fs_extra = require("fs-extra");
4
+ fs_extra = require_rolldown_runtime.__toESM(fs_extra, 1);
5
+ //#region ../../src/utils/fs.ts
6
+ const pathExists = async (filePath) => {
7
+ try {
8
+ await fs_extra.default.promises.access(filePath);
9
+ return true;
10
+ } catch (error) {
11
+ if (require_error.isErrorWithCode(error, "ENOENT")) return false;
12
+ throw error;
13
+ }
14
+ };
15
+ //#endregion
16
+ Object.defineProperty(exports, "pathExists", {
17
+ enumerable: true,
18
+ get: function() {
19
+ return pathExists;
20
+ }
21
+ });
@@ -0,0 +1,14 @@
1
+ import { t as isErrorWithCode } from "./error-CxiNRw9A.mjs";
2
+ import fs from "fs-extra";
3
+ //#region ../../src/utils/fs.ts
4
+ const pathExists = async (filePath) => {
5
+ try {
6
+ await fs.promises.access(filePath);
7
+ return true;
8
+ } catch (error) {
9
+ if (isErrorWithCode(error, "ENOENT")) return false;
10
+ throw error;
11
+ }
12
+ };
13
+ //#endregion
14
+ export { pathExists as t };
package/lib/git/index.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_git = require("../git-BeGqD0KV.cjs");
2
+ const require_git = require("../git-BGcWTYZJ.cjs");
3
3
  exports.commit = require_git.commit;
4
4
  exports.commitAllChanges = require_git.commitAllChanges;
5
5
  exports.currentBranch = require_git.currentBranch;
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-DyhV01cl.mjs";
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-DKqd7R1V.mjs";
2
2
  export { commit, commitAllChanges, currentBranch, fastForwardBranch, findRoot, getChangedFiles, getHeadCommitId, getHeadCommitMessage, getOwnerAndRepo, isFileGitIgnored, push, reset };
@@ -1,5 +1,5 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-DakpK96I.cjs");
2
- const require_error = require("./error-BSBcaHO0.cjs");
2
+ const require_fs = require("./fs-BBMaW7WT.cjs");
3
3
  let fs_extra = require("fs-extra");
4
4
  fs_extra = require_rolldown_runtime.__toESM(fs_extra, 1);
5
5
  let isomorphic_git = require("isomorphic-git");
@@ -39,17 +39,6 @@ const findRoot$1 = async ({ dir }) => {
39
39
  }
40
40
  };
41
41
  //#endregion
42
- //#region ../../src/utils/fs.ts
43
- const pathExists = async (filePath) => {
44
- try {
45
- await fs_extra.default.promises.access(filePath);
46
- return true;
47
- } catch (error) {
48
- if (require_error.isErrorWithCode(error, "ENOENT")) return false;
49
- throw error;
50
- }
51
- };
52
- //#endregion
53
42
  //#region src/git/getChangedFiles.ts
54
43
  const mapState = (row) => {
55
44
  if (row[1] === 0) return "added";
@@ -140,7 +129,7 @@ const getChangedFilesFromRefs = async ({ dir, src, dst }) => {
140
129
  const createIsLfsFilter = async (gitRoot) => {
141
130
  if (!gitRoot) return () => false;
142
131
  const lfsFile = `${gitRoot}/.gitattributes`;
143
- if (!await pathExists(lfsFile)) return () => false;
132
+ if (!await require_fs.pathExists(lfsFile)) return () => false;
144
133
  const filter = (0, ignore.default)().add((await fs_extra.default.promises.readFile(lfsFile, "utf8")).split("\n").map((l) => l.trim()).filter((l) => !l.startsWith("#") && l.includes("filter=lfs")).map((l) => l.split(/\s+/)[0]).flatMap((l) => l ? [l] : []));
145
134
  return (pathname) => filter.ignores(pathname);
146
135
  };
@@ -1,5 +1,5 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
- import { t as isErrorWithCode } from "./error-CxiNRw9A.mjs";
2
+ import { t as pathExists } from "./fs-BrQNZY8y.mjs";
3
3
  import fs from "fs-extra";
4
4
  import git, { findRoot } from "isomorphic-git";
5
5
  import path from "path";
@@ -34,17 +34,6 @@ const findRoot$1 = async ({ dir }) => {
34
34
  }
35
35
  };
36
36
  //#endregion
37
- //#region ../../src/utils/fs.ts
38
- const pathExists = async (filePath) => {
39
- try {
40
- await fs.promises.access(filePath);
41
- return true;
42
- } catch (error) {
43
- if (isErrorWithCode(error, "ENOENT")) return false;
44
- throw error;
45
- }
46
- };
47
- //#endregion
48
37
  //#region src/git/getChangedFiles.ts
49
38
  const mapState = (row) => {
50
39
  if (row[1] === 0) return "added";
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
- const require_git = require("../git-BeGqD0KV.cjs");
3
- const require_github = require("../github-C91l-j0Z.cjs");
2
+ const require_git = require("../git-BGcWTYZJ.cjs");
3
+ const require_github = require("../github-B2fQutQz.cjs");
4
4
  exports.apiTokenFromEnvironment = require_git.apiTokenFromEnvironment;
5
5
  exports.buildNameFromEnvironment = require_git.buildNameFromEnvironment;
6
6
  exports.createCheckRun = require_github.createCheckRun;
@@ -1,3 +1,3 @@
1
- import { c as enabledFromEnvironment, o as apiTokenFromEnvironment, s as buildNameFromEnvironment } from "../git-DyhV01cl.mjs";
2
- import { a as putIssueComment, i as uploadFileChanges, n as readFileChanges, o as getPullRequestNumber, r as uploadAllFileChanges, s as createCheckRun } from "../github-CmHDTIHw.mjs";
1
+ import { c as enabledFromEnvironment, o as apiTokenFromEnvironment, s as buildNameFromEnvironment } from "../git-DKqd7R1V.mjs";
2
+ import { a as putIssueComment, i as uploadFileChanges, n as readFileChanges, o as getPullRequestNumber, r as uploadAllFileChanges, s as createCheckRun } from "../github-EDhl9ON9.mjs";
3
3
  export { apiTokenFromEnvironment, buildNameFromEnvironment, createCheckRun, enabledFromEnvironment, getPullRequestNumber, putIssueComment, readFileChanges, uploadAllFileChanges, uploadFileChanges };
@@ -1,6 +1,6 @@
1
1
  const require_rolldown_runtime = require("./rolldown-runtime-DakpK96I.cjs");
2
2
  const require_logging = require("./logging-BqpzZfsF.cjs");
3
- const require_git = require("./git-BeGqD0KV.cjs");
3
+ const require_git = require("./git-BGcWTYZJ.cjs");
4
4
  let fs_extra = require("fs-extra");
5
5
  fs_extra = require_rolldown_runtime.__toESM(fs_extra, 1);
6
6
  let path = require("path");
@@ -1,6 +1,6 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
2
  import { n as pluralise } from "./logging-BQNEupxh.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-DyhV01cl.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-DKqd7R1V.mjs";
4
4
  import fs from "fs-extra";
5
5
  import path from "path";
6
6
  //#region src/github/octokit.ts
@@ -0,0 +1,97 @@
1
+ import { Plugin } from "rolldown";
2
+ //#region src/rolldown/lambdaAsset.d.ts
3
+ interface LambdaAssetFile {
4
+ /**
5
+ * Path to the file or directory to copy, resolved relative to `projectRoot`.
6
+ */
7
+ from: string;
8
+ /**
9
+ * Destination path relative to the output directory.
10
+ *
11
+ * Defaults to the basename of `from`, placing it at the top of the output
12
+ * directory.
13
+ */
14
+ to?: string;
15
+ }
16
+ interface LambdaAssetOptions {
17
+ /**
18
+ * npm packages to install into the output directory rather than embed in the
19
+ * bundle.
20
+ *
21
+ * Versions are resolved from the copy installed under `projectRoot`. Mark
22
+ * these packages `external` in your rolldown config too, otherwise they will
23
+ * be bundled _and_ installed.
24
+ *
25
+ * Packages with native binaries (e.g. `sharp`) are the usual candidates.
26
+ */
27
+ nodeModules?: string[];
28
+ /**
29
+ * Extra files or directories to copy into the output directory alongside the
30
+ * bundle, e.g. static assets or configuration the handler reads at runtime.
31
+ *
32
+ * Each `from` is resolved relative to `projectRoot`; each `to` defaults to
33
+ * the basename of `from` and is resolved relative to the output directory.
34
+ */
35
+ assets?: LambdaAssetFile[];
36
+ /**
37
+ * Directory that `nodeModules` versions are resolved from, and that `assets`
38
+ * are copied from.
39
+ *
40
+ * This is the directory holding the `package.json` that depends on them; in a
41
+ * workspace, that is the individual package rather than the workspace root.
42
+ *
43
+ * Relative paths resolve against rolldown's `cwd`, which defaults to
44
+ * `process.cwd()`.
45
+ */
46
+ projectRoot?: string;
47
+ /**
48
+ * Path to the `pnpm-lock.yaml` to install against.
49
+ *
50
+ * pnpm keeps this at the workspace root, so its directory is also where the
51
+ * workspace config and patches are staged from.
52
+ *
53
+ * Defaults to the nearest lock file, walking up from rolldown's `cwd`, which
54
+ * defaults to `process.cwd()`. A relative path resolves against that `cwd`.
55
+ */
56
+ depsLockFilePath?: string;
57
+ }
58
+ /**
59
+ * Prepares a rolldown output directory for deployment as a Lambda asset.
60
+ *
61
+ * The plugin supports ESM output and pnpm only. It makes no assumptions about
62
+ * how you bundle; it only augments what rolldown has already written:
63
+ *
64
+ * 1. Emits any extra `assets` into the build output alongside the bundle, via
65
+ * rolldown's `emitFile`.
66
+ * 2. Writes a `package.json` of `type: 'module'`.
67
+ * 3. Installs `nodeModules` into the output directory with pnpm, staging the
68
+ * workspace config, `.npmrc`, lock file and patches to do so.
69
+ * 4. Strips those install-only files back out, leaving the bundle, the
70
+ * generated `package.json` and `node_modules`.
71
+ *
72
+ * The result can be handed to CDK as `aws_lambda.Code.fromAsset(outputDir)`.
73
+ *
74
+ * @example
75
+ * ```js
76
+ * // rolldown.config.mjs
77
+ * import { Rolldown } from 'skuba';
78
+ *
79
+ * export default {
80
+ * input: 'src/lambda.ts',
81
+ * output: { dir: 'lib' },
82
+ * external: ['sharp'],
83
+ * plugins: [
84
+ * Rolldown.lambdaAsset({
85
+ * nodeModules: ['sharp'],
86
+ * assets: [{ from: 'src/config.json' }],
87
+ * }),
88
+ * ],
89
+ * };
90
+ * ```
91
+ */
92
+ declare const lambdaAsset: ({ nodeModules, assets, projectRoot: projectRootOption, depsLockFilePath: depsLockFilePathOption }?: LambdaAssetOptions) => Plugin;
93
+ declare namespace index_d_exports {
94
+ export { LambdaAssetFile, LambdaAssetOptions, lambdaAsset };
95
+ }
96
+ //#endregion
97
+ export { lambdaAsset as i, LambdaAssetFile as n, LambdaAssetOptions as r, index_d_exports as t };
@@ -0,0 +1,97 @@
1
+ import { Plugin } from "rolldown";
2
+ //#region src/rolldown/lambdaAsset.d.ts
3
+ interface LambdaAssetFile {
4
+ /**
5
+ * Path to the file or directory to copy, resolved relative to `projectRoot`.
6
+ */
7
+ from: string;
8
+ /**
9
+ * Destination path relative to the output directory.
10
+ *
11
+ * Defaults to the basename of `from`, placing it at the top of the output
12
+ * directory.
13
+ */
14
+ to?: string;
15
+ }
16
+ interface LambdaAssetOptions {
17
+ /**
18
+ * npm packages to install into the output directory rather than embed in the
19
+ * bundle.
20
+ *
21
+ * Versions are resolved from the copy installed under `projectRoot`. Mark
22
+ * these packages `external` in your rolldown config too, otherwise they will
23
+ * be bundled _and_ installed.
24
+ *
25
+ * Packages with native binaries (e.g. `sharp`) are the usual candidates.
26
+ */
27
+ nodeModules?: string[];
28
+ /**
29
+ * Extra files or directories to copy into the output directory alongside the
30
+ * bundle, e.g. static assets or configuration the handler reads at runtime.
31
+ *
32
+ * Each `from` is resolved relative to `projectRoot`; each `to` defaults to
33
+ * the basename of `from` and is resolved relative to the output directory.
34
+ */
35
+ assets?: LambdaAssetFile[];
36
+ /**
37
+ * Directory that `nodeModules` versions are resolved from, and that `assets`
38
+ * are copied from.
39
+ *
40
+ * This is the directory holding the `package.json` that depends on them; in a
41
+ * workspace, that is the individual package rather than the workspace root.
42
+ *
43
+ * Relative paths resolve against rolldown's `cwd`, which defaults to
44
+ * `process.cwd()`.
45
+ */
46
+ projectRoot?: string;
47
+ /**
48
+ * Path to the `pnpm-lock.yaml` to install against.
49
+ *
50
+ * pnpm keeps this at the workspace root, so its directory is also where the
51
+ * workspace config and patches are staged from.
52
+ *
53
+ * Defaults to the nearest lock file, walking up from rolldown's `cwd`, which
54
+ * defaults to `process.cwd()`. A relative path resolves against that `cwd`.
55
+ */
56
+ depsLockFilePath?: string;
57
+ }
58
+ /**
59
+ * Prepares a rolldown output directory for deployment as a Lambda asset.
60
+ *
61
+ * The plugin supports ESM output and pnpm only. It makes no assumptions about
62
+ * how you bundle; it only augments what rolldown has already written:
63
+ *
64
+ * 1. Emits any extra `assets` into the build output alongside the bundle, via
65
+ * rolldown's `emitFile`.
66
+ * 2. Writes a `package.json` of `type: 'module'`.
67
+ * 3. Installs `nodeModules` into the output directory with pnpm, staging the
68
+ * workspace config, `.npmrc`, lock file and patches to do so.
69
+ * 4. Strips those install-only files back out, leaving the bundle, the
70
+ * generated `package.json` and `node_modules`.
71
+ *
72
+ * The result can be handed to CDK as `aws_lambda.Code.fromAsset(outputDir)`.
73
+ *
74
+ * @example
75
+ * ```js
76
+ * // rolldown.config.mjs
77
+ * import { Rolldown } from 'skuba';
78
+ *
79
+ * export default {
80
+ * input: 'src/lambda.ts',
81
+ * output: { dir: 'lib' },
82
+ * external: ['sharp'],
83
+ * plugins: [
84
+ * Rolldown.lambdaAsset({
85
+ * nodeModules: ['sharp'],
86
+ * assets: [{ from: 'src/config.json' }],
87
+ * }),
88
+ * ],
89
+ * };
90
+ * ```
91
+ */
92
+ declare const lambdaAsset: ({ nodeModules, assets, projectRoot: projectRootOption, depsLockFilePath: depsLockFilePathOption }?: LambdaAssetOptions) => Plugin;
93
+ declare namespace index_d_exports {
94
+ export { LambdaAssetFile, LambdaAssetOptions, lambdaAsset };
95
+ }
96
+ //#endregion
97
+ export { lambdaAsset as i, LambdaAssetFile as n, LambdaAssetOptions as r, index_d_exports as t };
package/lib/index.cjs CHANGED
@@ -1,9 +1,10 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
2
  const require_buildkite = require("./buildkite-CM-xlOq5.cjs");
3
3
  const require_cdk_index = require("./cdk/index.cjs");
4
- const require_git = require("./git-BeGqD0KV.cjs");
5
- const require_github = require("./github-C91l-j0Z.cjs");
4
+ const require_git = require("./git-BGcWTYZJ.cjs");
5
+ const require_github = require("./github-B2fQutQz.cjs");
6
6
  const require_net = require("./net-zrteIHld.cjs");
7
+ const require_rolldown = require("./rolldown-CN3DH_Tw.cjs");
7
8
  Object.defineProperty(exports, "Buildkite", {
8
9
  enumerable: true,
9
10
  get: function() {
@@ -34,3 +35,9 @@ Object.defineProperty(exports, "Net", {
34
35
  return require_net.net_exports;
35
36
  }
36
37
  });
38
+ Object.defineProperty(exports, "Rolldown", {
39
+ enumerable: true,
40
+ get: function() {
41
+ return require_rolldown.rolldown_exports;
42
+ }
43
+ });
package/lib/index.d.cts CHANGED
@@ -3,4 +3,5 @@ import { t as index_d_exports$1 } from "./cdk/index.cjs";
3
3
  import { t as index_d_exports$2 } from "./index-CLEYcnJY.cjs";
4
4
  import { t as index_d_exports$3 } from "./index-CPm5rAMy.cjs";
5
5
  import { t as index_d_exports$4 } from "./index-C9lVo3vU.cjs";
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 };
6
+ import { t as index_d_exports$5 } from "./index-BEmN8nSJ.cjs";
7
+ 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, index_d_exports$5 as Rolldown };
package/lib/index.d.mts CHANGED
@@ -3,4 +3,5 @@ import { t as index_d_exports$1 } from "./cdk/index.mjs";
3
3
  import { t as index_d_exports$2 } from "./index-CLEYcnJY.mjs";
4
4
  import { t as index_d_exports$3 } from "./index-CwdiFn_m.mjs";
5
5
  import { t as index_d_exports$4 } from "./index-C9lVo3vU.mjs";
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 };
6
+ import { t as index_d_exports$5 } from "./index-BEmN8nSJ.mjs";
7
+ 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, index_d_exports$5 as Rolldown };
package/lib/index.mjs CHANGED
@@ -1,6 +1,7 @@
1
1
  import { t as buildkite_exports } from "./buildkite-B0gyBRNS.mjs";
2
2
  import { t as cdk_exports } from "./cdk/index.mjs";
3
- import { t as git_exports } from "./git-DyhV01cl.mjs";
4
- import { t as github_exports } from "./github-CmHDTIHw.mjs";
3
+ import { t as git_exports } from "./git-DKqd7R1V.mjs";
4
+ import { t as github_exports } from "./github-EDhl9ON9.mjs";
5
5
  import { t as net_exports } from "./net-97EvMPiP.mjs";
6
- export { buildkite_exports as Buildkite, cdk_exports as Cdk, git_exports as Git, github_exports as GitHub, net_exports as Net };
6
+ import { t as rolldown_exports } from "./rolldown--bMMtGC0.mjs";
7
+ export { buildkite_exports as Buildkite, cdk_exports as Cdk, git_exports as Git, github_exports as GitHub, net_exports as Net, rolldown_exports as Rolldown };
@@ -0,0 +1,3 @@
1
+ Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
2
+ const require_rolldown = require("../rolldown-CN3DH_Tw.cjs");
3
+ exports.lambdaAsset = require_rolldown.lambdaAsset;
@@ -0,0 +1,2 @@
1
+ import { i as lambdaAsset, n as LambdaAssetFile, r as LambdaAssetOptions } from "../index-BEmN8nSJ.cjs";
2
+ export { type LambdaAssetFile, type LambdaAssetOptions, lambdaAsset };
@@ -0,0 +1,2 @@
1
+ import { i as lambdaAsset, n as LambdaAssetFile, r as LambdaAssetOptions } from "../index-BEmN8nSJ.mjs";
2
+ export { type LambdaAssetFile, type LambdaAssetOptions, lambdaAsset };
@@ -0,0 +1,2 @@
1
+ import { n as lambdaAsset } from "../rolldown--bMMtGC0.mjs";
2
+ export { lambdaAsset };
@@ -0,0 +1,279 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-D7D4PA-g.mjs";
2
+ import { t as log } from "./logging-BQNEupxh.mjs";
3
+ import { t as createExec } from "./exec-Dp89sakg.mjs";
4
+ import { t as pathExists } from "./fs-BrQNZY8y.mjs";
5
+ import { findPackageJSON } from "node:module";
6
+ import fs from "fs-extra";
7
+ import * as path from "node:path";
8
+ import { findUp } from "find-up";
9
+ import { pathToFileURL } from "node:url";
10
+ import { isMap, parseDocument } from "yaml";
11
+ //#region src/rolldown/pnpm.ts
12
+ const PNPM_LOCK = "pnpm-lock.yaml";
13
+ const PNPM_WORKSPACE_YAML = "pnpm-workspace.yaml";
14
+ const PNPM_PATCHES_DIR = "patches";
15
+ const PNPM_WORKSPACE_FILES = [
16
+ PNPM_WORKSPACE_YAML,
17
+ ".npmrc",
18
+ ".pnpmfile.cjs",
19
+ ".pnpmfile.mjs"
20
+ ];
21
+ /**
22
+ * Files that `pnpm install` leaves behind which record machine-local paths and
23
+ * timestamps, and so would churn the CDK asset hash on every build.
24
+ */
25
+ const PNPM_METADATA_FILES = [path.join("node_modules", ".modules.yaml"), path.join("node_modules", ".pnpm-workspace-state-v1.json")];
26
+ const PNPM_INSTALL_COMMAND = [
27
+ "pnpm",
28
+ "install",
29
+ "--config.node-linker=hoisted",
30
+ "--config.package-import-method=clone-or-copy",
31
+ "--no-frozen-lockfile"
32
+ ];
33
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
34
+ const readJsonFile = async (filePath) => {
35
+ try {
36
+ return await fs.readJson(filePath);
37
+ } catch (err) {
38
+ throw new Error(`Failed to parse ${filePath} as JSON: ${err.message}`);
39
+ }
40
+ };
41
+ /**
42
+ * Reads a `name@version` package manager pin from a manifest, preferring the
43
+ * `packageManager` field and falling back to `devEngines.packageManager`.
44
+ *
45
+ * `devEngines.packageManager` is either an object `{ name, version }` or an
46
+ * array of them; a pin is only returned when both `name` and `version` are
47
+ * present, since corepack needs the version to activate.
48
+ */
49
+ const readPin = (parsed) => {
50
+ if (typeof parsed.packageManager === "string") return parsed.packageManager;
51
+ const raw = (isRecord(parsed.devEngines) ? parsed.devEngines : void 0)?.packageManager;
52
+ const packageManager = Array.isArray(raw) ? raw[0] : raw;
53
+ if (isRecord(packageManager) && typeof packageManager.name === "string" && typeof packageManager.version === "string") return `${packageManager.name}@${packageManager.version}`;
54
+ };
55
+ /**
56
+ * Reads the package manager pin from the workspace root manifest.
57
+ *
58
+ * Forwarding it to the output directory keeps the staged install on the same
59
+ * pnpm version as the project.
60
+ */
61
+ const readPackageManagerPin = async (workspaceRoot) => {
62
+ const pkgPath = path.join(workspaceRoot, "package.json");
63
+ if (!await pathExists(pkgPath)) return;
64
+ const parsed = await readJsonFile(pkgPath);
65
+ return isRecord(parsed) ? readPin(parsed) : void 0;
66
+ };
67
+ /**
68
+ * The output directory installs a subset of the workspace's dependencies, so
69
+ * most `patchedDependencies` entries have nothing to apply to. pnpm fails the
70
+ * install on an unused patch unless this is set.
71
+ */
72
+ const allowUnusedPatches = (content) => {
73
+ const doc = parseDocument(content);
74
+ const [error] = doc.errors;
75
+ if (error) throw new Error(`Failed to parse ${PNPM_WORKSPACE_YAML}: ${error.message}`);
76
+ if (!isMap(doc.contents)) return content;
77
+ doc.set("allowUnusedPatches", true);
78
+ return doc.toString();
79
+ };
80
+ /**
81
+ * Stages the pnpm config that an install in `outputDir` needs.
82
+ *
83
+ * Patch files are staged from `patches`, where `pnpm patch-commit` writes them.
84
+ *
85
+ * Every path written is appended to `stagedFiles` so the caller can strip it
86
+ * back out once the install is done; `.npmrc` in particular may hold registry
87
+ * credentials that must not ship in the asset.
88
+ */
89
+ const stageWorkspaceFiles = async (workspaceRoot, outputDir, stagedFiles = []) => {
90
+ const present = (await Promise.all(PNPM_WORKSPACE_FILES.map(async (file) => {
91
+ const src = path.join(workspaceRoot, file);
92
+ return await pathExists(src) ? {
93
+ file,
94
+ src
95
+ } : void 0;
96
+ }))).filter((entry) => entry !== void 0);
97
+ for (const { file } of present) stagedFiles.push(path.join(outputDir, file));
98
+ await Promise.all(present.map(async ({ file, src }) => {
99
+ const dest = path.join(outputDir, file);
100
+ if (file === PNPM_WORKSPACE_YAML) await fs.promises.writeFile(dest, allowUnusedPatches(await fs.promises.readFile(src, "utf8")));
101
+ else await fs.promises.copyFile(src, dest);
102
+ }));
103
+ const patchesSrc = path.join(workspaceRoot, PNPM_PATCHES_DIR);
104
+ if (await pathExists(patchesSrc)) {
105
+ const patchesDest = path.join(outputDir, PNPM_PATCHES_DIR);
106
+ stagedFiles.push(patchesDest);
107
+ await fs.copy(patchesSrc, patchesDest);
108
+ }
109
+ return stagedFiles;
110
+ };
111
+ /**
112
+ * Resolves the installed version of each module, as seen from `resolveFrom`.
113
+ */
114
+ const extractDependencies = async (resolveFrom, modules) => {
115
+ const result = {};
116
+ const base = pathToFileURL(resolveFrom);
117
+ for (const mod of modules) {
118
+ let modPkgPath;
119
+ try {
120
+ modPkgPath = findPackageJSON(mod, base);
121
+ } catch {
122
+ modPkgPath = void 0;
123
+ }
124
+ const parsed = modPkgPath ? await readJsonFile(modPkgPath) : void 0;
125
+ const version = isRecord(parsed) && typeof parsed.version === "string" ? parsed.version.trim() : void 0;
126
+ if (!version) throw new Error(`Cannot extract version for module '${mod}'. Check that it's referenced in your package.json or installed.`);
127
+ result[mod] = version;
128
+ }
129
+ return result;
130
+ };
131
+ //#endregion
132
+ //#region src/rolldown/lambdaAsset.ts
133
+ const PLUGIN_NAME = "skuba:lambda-asset";
134
+ const resolveOutputDir = ({ dir, file }, cwd) => {
135
+ if (!dir) throw new Error(`${PLUGIN_NAME} requires \`output.dir\`; it prepares a deployable directory, so a single \`output.file\`${file ? ` (${file})` : ""} has nowhere to install into.`);
136
+ return path.resolve(cwd, dir);
137
+ };
138
+ const resolveLockFile = async (depsLockFilePath, cwd) => {
139
+ if (!depsLockFilePath) return findUp(PNPM_LOCK, { cwd });
140
+ const resolved = path.resolve(cwd, depsLockFilePath);
141
+ if (!await pathExists(resolved)) throw new Error(`${PLUGIN_NAME} cannot find a ${PNPM_LOCK} at '${depsLockFilePath}'.`);
142
+ return resolved;
143
+ };
144
+ const toPosix = (p) => p.split(path.sep).join("/");
145
+ /**
146
+ * Emits extra `assets` into the build output alongside the bundle.
147
+ *
148
+ * `from` is resolved relative to `projectRoot`; `to` becomes the emitted
149
+ * `fileName`, which rolldown writes relative to the output directory, creating
150
+ * parent directories as needed. Directories are emitted recursively, one asset
151
+ * per file. `originalFileName` points rolldown at each source file so watch mode
152
+ * rebuilds when it changes.
153
+ */
154
+ const emitAssets = async (emit, projectRoot, assets) => {
155
+ await Promise.all(assets.map(async (asset) => {
156
+ const from = path.resolve(projectRoot, asset.from);
157
+ const to = asset.to ?? path.basename(asset.from);
158
+ const normalized = path.normalize(to);
159
+ if (path.isAbsolute(normalized) || normalized === "." || normalized === ".." || normalized.startsWith(`..${path.sep}`)) throw new Error(`${PLUGIN_NAME} refuses to copy asset '${asset.from}' to '${asset.to}': it escapes the output directory.`);
160
+ const files = (await fs.promises.stat(from)).isDirectory() ? (await fs.promises.readdir(from, {
161
+ recursive: true,
162
+ withFileTypes: true
163
+ })).filter((entry) => entry.isFile()).map((entry) => path.join(entry.parentPath, entry.name)) : [from];
164
+ await Promise.all(files.map(async (absFile) => {
165
+ const rel = path.relative(from, absFile);
166
+ emit({
167
+ type: "asset",
168
+ fileName: toPosix(rel ? path.join(to, rel) : to),
169
+ originalFileName: absFile,
170
+ source: await fs.promises.readFile(absFile)
171
+ });
172
+ }));
173
+ }));
174
+ };
175
+ const writeOutputPackageJson = (outputDir, fields = {}) => fs.promises.writeFile(path.join(outputDir, "package.json"), JSON.stringify({
176
+ type: "module",
177
+ ...fields
178
+ }, null, 2));
179
+ /**
180
+ * Strips the install-only files back out of the output directory.
181
+ *
182
+ * `.npmrc` may hold registry credentials, so one path failing to remove must
183
+ * not skip the rest, and the caller must hear about it.
184
+ */
185
+ const stripInstallFiles = async (outputDir, stagedFiles, cause) => {
186
+ const reasons = (await Promise.allSettled([...stagedFiles, ...PNPM_METADATA_FILES.map((file) => path.join(outputDir, file))].map((file) => fs.remove(file)))).flatMap((result) => result.status === "rejected" ? [String(result.reason)] : []);
187
+ if (reasons.length) throw new Error(`${PLUGIN_NAME} could not strip install-only files from '${outputDir}'; these may include registry credentials and must not be deployed. ${reasons.join("; ")}`, { cause });
188
+ };
189
+ /**
190
+ * Prepares a rolldown output directory for deployment as a Lambda asset.
191
+ *
192
+ * The plugin supports ESM output and pnpm only. It makes no assumptions about
193
+ * how you bundle; it only augments what rolldown has already written:
194
+ *
195
+ * 1. Emits any extra `assets` into the build output alongside the bundle, via
196
+ * rolldown's `emitFile`.
197
+ * 2. Writes a `package.json` of `type: 'module'`.
198
+ * 3. Installs `nodeModules` into the output directory with pnpm, staging the
199
+ * workspace config, `.npmrc`, lock file and patches to do so.
200
+ * 4. Strips those install-only files back out, leaving the bundle, the
201
+ * generated `package.json` and `node_modules`.
202
+ *
203
+ * The result can be handed to CDK as `aws_lambda.Code.fromAsset(outputDir)`.
204
+ *
205
+ * @example
206
+ * ```js
207
+ * // rolldown.config.mjs
208
+ * import { Rolldown } from 'skuba';
209
+ *
210
+ * export default {
211
+ * input: 'src/lambda.ts',
212
+ * output: { dir: 'lib' },
213
+ * external: ['sharp'],
214
+ * plugins: [
215
+ * Rolldown.lambdaAsset({
216
+ * nodeModules: ['sharp'],
217
+ * assets: [{ from: 'src/config.json' }],
218
+ * }),
219
+ * ],
220
+ * };
221
+ * ```
222
+ */
223
+ const lambdaAsset = ({ nodeModules = [], assets = [], projectRoot: projectRootOption, depsLockFilePath: depsLockFilePathOption } = {}) => {
224
+ const prepared = /* @__PURE__ */ new Set();
225
+ let cwd = process.cwd();
226
+ return {
227
+ name: PLUGIN_NAME,
228
+ async buildStart(options) {
229
+ cwd = options.cwd;
230
+ prepared.clear();
231
+ if (assets.length) {
232
+ const projectRoot = path.resolve(cwd, projectRootOption ?? ".");
233
+ await emitAssets((file) => this.emitFile(file), projectRoot, assets);
234
+ }
235
+ },
236
+ async writeBundle(outputOptions) {
237
+ const outputDir = resolveOutputDir(outputOptions, cwd);
238
+ if (prepared.has(outputDir)) return;
239
+ prepared.add(outputDir);
240
+ const projectRoot = path.resolve(cwd, projectRootOption ?? ".");
241
+ if (!nodeModules.length) {
242
+ await writeOutputPackageJson(outputDir);
243
+ return;
244
+ }
245
+ const depsLockFilePath = await resolveLockFile(depsLockFilePathOption, cwd);
246
+ if (!depsLockFilePath) throw new Error(`${PLUGIN_NAME} cannot find a ${PNPM_LOCK}, which \`nodeModules\` requires. Specify one with \`depsLockFilePath\`.`);
247
+ const workspaceRoot = path.dirname(depsLockFilePath);
248
+ const projectPackageJson = path.join(projectRoot, "package.json");
249
+ if (!await pathExists(projectPackageJson)) throw new Error(`${PLUGIN_NAME} cannot find a package.json in '${projectRoot}', which \`nodeModules\` requires. Specify the directory with \`projectRoot\`.`);
250
+ await writeOutputPackageJson(outputDir, {
251
+ dependencies: await extractDependencies(projectPackageJson, nodeModules),
252
+ packageManager: await readPackageManagerPin(workspaceRoot)
253
+ });
254
+ const stagedFiles = [];
255
+ try {
256
+ await stageWorkspaceFiles(workspaceRoot, outputDir, stagedFiles);
257
+ const lockDest = path.join(outputDir, PNPM_LOCK);
258
+ stagedFiles.push(lockDest);
259
+ await fs.promises.copyFile(depsLockFilePath, lockDest);
260
+ log.plain(log.bold(PLUGIN_NAME), "installing", log.bold(nodeModules.join(", ")));
261
+ const [bin, ...args] = PNPM_INSTALL_COMMAND;
262
+ await createExec({ cwd: outputDir })(bin, ...args);
263
+ } catch (err) {
264
+ await stripInstallFiles(outputDir, [
265
+ ...stagedFiles,
266
+ path.join(outputDir, "package.json"),
267
+ path.join(outputDir, "node_modules")
268
+ ], err);
269
+ throw err;
270
+ }
271
+ await stripInstallFiles(outputDir, stagedFiles);
272
+ }
273
+ };
274
+ };
275
+ //#endregion
276
+ //#region src/rolldown/index.ts
277
+ var rolldown_exports = /* @__PURE__ */ __exportAll({ lambdaAsset: () => lambdaAsset });
278
+ //#endregion
279
+ export { lambdaAsset as n, rolldown_exports as t };
@@ -0,0 +1,292 @@
1
+ const require_rolldown_runtime = require("./rolldown-runtime-DakpK96I.cjs");
2
+ const require_logging = require("./logging-BqpzZfsF.cjs");
3
+ const require_exec = require("./exec-BGMWpmZ7.cjs");
4
+ const require_fs = require("./fs-BBMaW7WT.cjs");
5
+ let fs_extra = require("fs-extra");
6
+ fs_extra = require_rolldown_runtime.__toESM(fs_extra, 1);
7
+ let node_path = require("node:path");
8
+ node_path = require_rolldown_runtime.__toESM(node_path, 1);
9
+ let find_up = require("find-up");
10
+ let node_module = require("node:module");
11
+ let node_url = require("node:url");
12
+ let yaml = require("yaml");
13
+ //#region src/rolldown/pnpm.ts
14
+ const PNPM_LOCK = "pnpm-lock.yaml";
15
+ const PNPM_WORKSPACE_YAML = "pnpm-workspace.yaml";
16
+ const PNPM_PATCHES_DIR = "patches";
17
+ const PNPM_WORKSPACE_FILES = [
18
+ PNPM_WORKSPACE_YAML,
19
+ ".npmrc",
20
+ ".pnpmfile.cjs",
21
+ ".pnpmfile.mjs"
22
+ ];
23
+ /**
24
+ * Files that `pnpm install` leaves behind which record machine-local paths and
25
+ * timestamps, and so would churn the CDK asset hash on every build.
26
+ */
27
+ const PNPM_METADATA_FILES = [node_path.join("node_modules", ".modules.yaml"), node_path.join("node_modules", ".pnpm-workspace-state-v1.json")];
28
+ const PNPM_INSTALL_COMMAND = [
29
+ "pnpm",
30
+ "install",
31
+ "--config.node-linker=hoisted",
32
+ "--config.package-import-method=clone-or-copy",
33
+ "--no-frozen-lockfile"
34
+ ];
35
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
36
+ const readJsonFile = async (filePath) => {
37
+ try {
38
+ return await fs_extra.default.readJson(filePath);
39
+ } catch (err) {
40
+ throw new Error(`Failed to parse ${filePath} as JSON: ${err.message}`);
41
+ }
42
+ };
43
+ /**
44
+ * Reads a `name@version` package manager pin from a manifest, preferring the
45
+ * `packageManager` field and falling back to `devEngines.packageManager`.
46
+ *
47
+ * `devEngines.packageManager` is either an object `{ name, version }` or an
48
+ * array of them; a pin is only returned when both `name` and `version` are
49
+ * present, since corepack needs the version to activate.
50
+ */
51
+ const readPin = (parsed) => {
52
+ if (typeof parsed.packageManager === "string") return parsed.packageManager;
53
+ const raw = (isRecord(parsed.devEngines) ? parsed.devEngines : void 0)?.packageManager;
54
+ const packageManager = Array.isArray(raw) ? raw[0] : raw;
55
+ if (isRecord(packageManager) && typeof packageManager.name === "string" && typeof packageManager.version === "string") return `${packageManager.name}@${packageManager.version}`;
56
+ };
57
+ /**
58
+ * Reads the package manager pin from the workspace root manifest.
59
+ *
60
+ * Forwarding it to the output directory keeps the staged install on the same
61
+ * pnpm version as the project.
62
+ */
63
+ const readPackageManagerPin = async (workspaceRoot) => {
64
+ const pkgPath = node_path.join(workspaceRoot, "package.json");
65
+ if (!await require_fs.pathExists(pkgPath)) return;
66
+ const parsed = await readJsonFile(pkgPath);
67
+ return isRecord(parsed) ? readPin(parsed) : void 0;
68
+ };
69
+ /**
70
+ * The output directory installs a subset of the workspace's dependencies, so
71
+ * most `patchedDependencies` entries have nothing to apply to. pnpm fails the
72
+ * install on an unused patch unless this is set.
73
+ */
74
+ const allowUnusedPatches = (content) => {
75
+ const doc = (0, yaml.parseDocument)(content);
76
+ const [error] = doc.errors;
77
+ if (error) throw new Error(`Failed to parse ${PNPM_WORKSPACE_YAML}: ${error.message}`);
78
+ if (!(0, yaml.isMap)(doc.contents)) return content;
79
+ doc.set("allowUnusedPatches", true);
80
+ return doc.toString();
81
+ };
82
+ /**
83
+ * Stages the pnpm config that an install in `outputDir` needs.
84
+ *
85
+ * Patch files are staged from `patches`, where `pnpm patch-commit` writes them.
86
+ *
87
+ * Every path written is appended to `stagedFiles` so the caller can strip it
88
+ * back out once the install is done; `.npmrc` in particular may hold registry
89
+ * credentials that must not ship in the asset.
90
+ */
91
+ const stageWorkspaceFiles = async (workspaceRoot, outputDir, stagedFiles = []) => {
92
+ const present = (await Promise.all(PNPM_WORKSPACE_FILES.map(async (file) => {
93
+ const src = node_path.join(workspaceRoot, file);
94
+ return await require_fs.pathExists(src) ? {
95
+ file,
96
+ src
97
+ } : void 0;
98
+ }))).filter((entry) => entry !== void 0);
99
+ for (const { file } of present) stagedFiles.push(node_path.join(outputDir, file));
100
+ await Promise.all(present.map(async ({ file, src }) => {
101
+ const dest = node_path.join(outputDir, file);
102
+ if (file === PNPM_WORKSPACE_YAML) await fs_extra.default.promises.writeFile(dest, allowUnusedPatches(await fs_extra.default.promises.readFile(src, "utf8")));
103
+ else await fs_extra.default.promises.copyFile(src, dest);
104
+ }));
105
+ const patchesSrc = node_path.join(workspaceRoot, PNPM_PATCHES_DIR);
106
+ if (await require_fs.pathExists(patchesSrc)) {
107
+ const patchesDest = node_path.join(outputDir, PNPM_PATCHES_DIR);
108
+ stagedFiles.push(patchesDest);
109
+ await fs_extra.default.copy(patchesSrc, patchesDest);
110
+ }
111
+ return stagedFiles;
112
+ };
113
+ /**
114
+ * Resolves the installed version of each module, as seen from `resolveFrom`.
115
+ */
116
+ const extractDependencies = async (resolveFrom, modules) => {
117
+ const result = {};
118
+ const base = (0, node_url.pathToFileURL)(resolveFrom);
119
+ for (const mod of modules) {
120
+ let modPkgPath;
121
+ try {
122
+ modPkgPath = (0, node_module.findPackageJSON)(mod, base);
123
+ } catch {
124
+ modPkgPath = void 0;
125
+ }
126
+ const parsed = modPkgPath ? await readJsonFile(modPkgPath) : void 0;
127
+ const version = isRecord(parsed) && typeof parsed.version === "string" ? parsed.version.trim() : void 0;
128
+ if (!version) throw new Error(`Cannot extract version for module '${mod}'. Check that it's referenced in your package.json or installed.`);
129
+ result[mod] = version;
130
+ }
131
+ return result;
132
+ };
133
+ //#endregion
134
+ //#region src/rolldown/lambdaAsset.ts
135
+ const PLUGIN_NAME = "skuba:lambda-asset";
136
+ const resolveOutputDir = ({ dir, file }, cwd) => {
137
+ if (!dir) throw new Error(`${PLUGIN_NAME} requires \`output.dir\`; it prepares a deployable directory, so a single \`output.file\`${file ? ` (${file})` : ""} has nowhere to install into.`);
138
+ return node_path.resolve(cwd, dir);
139
+ };
140
+ const resolveLockFile = async (depsLockFilePath, cwd) => {
141
+ if (!depsLockFilePath) return (0, find_up.findUp)(PNPM_LOCK, { cwd });
142
+ const resolved = node_path.resolve(cwd, depsLockFilePath);
143
+ if (!await require_fs.pathExists(resolved)) throw new Error(`${PLUGIN_NAME} cannot find a ${PNPM_LOCK} at '${depsLockFilePath}'.`);
144
+ return resolved;
145
+ };
146
+ const toPosix = (p) => p.split(node_path.sep).join("/");
147
+ /**
148
+ * Emits extra `assets` into the build output alongside the bundle.
149
+ *
150
+ * `from` is resolved relative to `projectRoot`; `to` becomes the emitted
151
+ * `fileName`, which rolldown writes relative to the output directory, creating
152
+ * parent directories as needed. Directories are emitted recursively, one asset
153
+ * per file. `originalFileName` points rolldown at each source file so watch mode
154
+ * rebuilds when it changes.
155
+ */
156
+ const emitAssets = async (emit, projectRoot, assets) => {
157
+ await Promise.all(assets.map(async (asset) => {
158
+ const from = node_path.resolve(projectRoot, asset.from);
159
+ const to = asset.to ?? node_path.basename(asset.from);
160
+ const normalized = node_path.normalize(to);
161
+ if (node_path.isAbsolute(normalized) || normalized === "." || normalized === ".." || normalized.startsWith(`..${node_path.sep}`)) throw new Error(`${PLUGIN_NAME} refuses to copy asset '${asset.from}' to '${asset.to}': it escapes the output directory.`);
162
+ const files = (await fs_extra.default.promises.stat(from)).isDirectory() ? (await fs_extra.default.promises.readdir(from, {
163
+ recursive: true,
164
+ withFileTypes: true
165
+ })).filter((entry) => entry.isFile()).map((entry) => node_path.join(entry.parentPath, entry.name)) : [from];
166
+ await Promise.all(files.map(async (absFile) => {
167
+ const rel = node_path.relative(from, absFile);
168
+ emit({
169
+ type: "asset",
170
+ fileName: toPosix(rel ? node_path.join(to, rel) : to),
171
+ originalFileName: absFile,
172
+ source: await fs_extra.default.promises.readFile(absFile)
173
+ });
174
+ }));
175
+ }));
176
+ };
177
+ const writeOutputPackageJson = (outputDir, fields = {}) => fs_extra.default.promises.writeFile(node_path.join(outputDir, "package.json"), JSON.stringify({
178
+ type: "module",
179
+ ...fields
180
+ }, null, 2));
181
+ /**
182
+ * Strips the install-only files back out of the output directory.
183
+ *
184
+ * `.npmrc` may hold registry credentials, so one path failing to remove must
185
+ * not skip the rest, and the caller must hear about it.
186
+ */
187
+ const stripInstallFiles = async (outputDir, stagedFiles, cause) => {
188
+ const reasons = (await Promise.allSettled([...stagedFiles, ...PNPM_METADATA_FILES.map((file) => node_path.join(outputDir, file))].map((file) => fs_extra.default.remove(file)))).flatMap((result) => result.status === "rejected" ? [String(result.reason)] : []);
189
+ if (reasons.length) throw new Error(`${PLUGIN_NAME} could not strip install-only files from '${outputDir}'; these may include registry credentials and must not be deployed. ${reasons.join("; ")}`, { cause });
190
+ };
191
+ /**
192
+ * Prepares a rolldown output directory for deployment as a Lambda asset.
193
+ *
194
+ * The plugin supports ESM output and pnpm only. It makes no assumptions about
195
+ * how you bundle; it only augments what rolldown has already written:
196
+ *
197
+ * 1. Emits any extra `assets` into the build output alongside the bundle, via
198
+ * rolldown's `emitFile`.
199
+ * 2. Writes a `package.json` of `type: 'module'`.
200
+ * 3. Installs `nodeModules` into the output directory with pnpm, staging the
201
+ * workspace config, `.npmrc`, lock file and patches to do so.
202
+ * 4. Strips those install-only files back out, leaving the bundle, the
203
+ * generated `package.json` and `node_modules`.
204
+ *
205
+ * The result can be handed to CDK as `aws_lambda.Code.fromAsset(outputDir)`.
206
+ *
207
+ * @example
208
+ * ```js
209
+ * // rolldown.config.mjs
210
+ * import { Rolldown } from 'skuba';
211
+ *
212
+ * export default {
213
+ * input: 'src/lambda.ts',
214
+ * output: { dir: 'lib' },
215
+ * external: ['sharp'],
216
+ * plugins: [
217
+ * Rolldown.lambdaAsset({
218
+ * nodeModules: ['sharp'],
219
+ * assets: [{ from: 'src/config.json' }],
220
+ * }),
221
+ * ],
222
+ * };
223
+ * ```
224
+ */
225
+ const lambdaAsset = ({ nodeModules = [], assets = [], projectRoot: projectRootOption, depsLockFilePath: depsLockFilePathOption } = {}) => {
226
+ const prepared = /* @__PURE__ */ new Set();
227
+ let cwd = process.cwd();
228
+ return {
229
+ name: PLUGIN_NAME,
230
+ async buildStart(options) {
231
+ cwd = options.cwd;
232
+ prepared.clear();
233
+ if (assets.length) {
234
+ const projectRoot = node_path.resolve(cwd, projectRootOption ?? ".");
235
+ await emitAssets((file) => this.emitFile(file), projectRoot, assets);
236
+ }
237
+ },
238
+ async writeBundle(outputOptions) {
239
+ const outputDir = resolveOutputDir(outputOptions, cwd);
240
+ if (prepared.has(outputDir)) return;
241
+ prepared.add(outputDir);
242
+ const projectRoot = node_path.resolve(cwd, projectRootOption ?? ".");
243
+ if (!nodeModules.length) {
244
+ await writeOutputPackageJson(outputDir);
245
+ return;
246
+ }
247
+ const depsLockFilePath = await resolveLockFile(depsLockFilePathOption, cwd);
248
+ if (!depsLockFilePath) throw new Error(`${PLUGIN_NAME} cannot find a ${PNPM_LOCK}, which \`nodeModules\` requires. Specify one with \`depsLockFilePath\`.`);
249
+ const workspaceRoot = node_path.dirname(depsLockFilePath);
250
+ const projectPackageJson = node_path.join(projectRoot, "package.json");
251
+ if (!await require_fs.pathExists(projectPackageJson)) throw new Error(`${PLUGIN_NAME} cannot find a package.json in '${projectRoot}', which \`nodeModules\` requires. Specify the directory with \`projectRoot\`.`);
252
+ await writeOutputPackageJson(outputDir, {
253
+ dependencies: await extractDependencies(projectPackageJson, nodeModules),
254
+ packageManager: await readPackageManagerPin(workspaceRoot)
255
+ });
256
+ const stagedFiles = [];
257
+ try {
258
+ await stageWorkspaceFiles(workspaceRoot, outputDir, stagedFiles);
259
+ const lockDest = node_path.join(outputDir, PNPM_LOCK);
260
+ stagedFiles.push(lockDest);
261
+ await fs_extra.default.promises.copyFile(depsLockFilePath, lockDest);
262
+ require_logging.log.plain(require_logging.log.bold(PLUGIN_NAME), "installing", require_logging.log.bold(nodeModules.join(", ")));
263
+ const [bin, ...args] = PNPM_INSTALL_COMMAND;
264
+ await require_exec.createExec({ cwd: outputDir })(bin, ...args);
265
+ } catch (err) {
266
+ await stripInstallFiles(outputDir, [
267
+ ...stagedFiles,
268
+ node_path.join(outputDir, "package.json"),
269
+ node_path.join(outputDir, "node_modules")
270
+ ], err);
271
+ throw err;
272
+ }
273
+ await stripInstallFiles(outputDir, stagedFiles);
274
+ }
275
+ };
276
+ };
277
+ //#endregion
278
+ //#region src/rolldown/index.ts
279
+ var rolldown_exports = /* @__PURE__ */ require_rolldown_runtime.__exportAll({ lambdaAsset: () => lambdaAsset });
280
+ //#endregion
281
+ Object.defineProperty(exports, "lambdaAsset", {
282
+ enumerable: true,
283
+ get: function() {
284
+ return lambdaAsset;
285
+ }
286
+ });
287
+ Object.defineProperty(exports, "rolldown_exports", {
288
+ enumerable: true,
289
+ get: function() {
290
+ return rolldown_exports;
291
+ }
292
+ });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@skuba-lib/api",
3
- "version": "2.3.0-rolldown-cdk-bundle-plugin-20260804001207",
3
+ "version": "2.3.0-rolldown-cdk-bundle-plugin-20260804234000",
4
4
  "description": "Node.js development API for skuba",
5
5
  "homepage": "https://github.com/seek-oss/skuba#readme",
6
6
  "bugs": {
@@ -39,6 +39,10 @@
39
39
  "import": "./lib/net/index.mjs",
40
40
  "require": "./lib/net/index.cjs"
41
41
  },
42
+ "./rolldown": {
43
+ "import": "./lib/rolldown/index.mjs",
44
+ "require": "./lib/rolldown/index.cjs"
45
+ },
42
46
  "./package.json": "./package.json"
43
47
  },
44
48
  "main": "./lib/index.cjs",
@@ -50,7 +54,8 @@
50
54
  "cdk",
51
55
  "git",
52
56
  "github",
53
- "net"
57
+ "net",
58
+ "rolldown"
54
59
  ],
55
60
  "dependencies": {
56
61
  "@octokit/graphql": "^9.0.0",
@@ -58,13 +63,23 @@
58
63
  "@octokit/types": "^16.0.0",
59
64
  "concurrently": "^10.0.0",
60
65
  "execa": "^9.6.1",
66
+ "find-up": "^8.0.0",
61
67
  "fs-extra": "^11.0.0",
62
68
  "ignore": "^7.0.0",
63
69
  "isomorphic-git": "^1.37.6",
64
70
  "npm-run-path": "^6.0.0",
65
71
  "npm-which": "^3.0.1",
72
+ "yaml": "^2.9.0",
66
73
  "zod": "^4.3.5"
67
74
  },
75
+ "peerDependencies": {
76
+ "rolldown": "^1.1.0"
77
+ },
78
+ "peerDependenciesMeta": {
79
+ "rolldown": {
80
+ "optional": true
81
+ }
82
+ },
68
83
  "engines": {
69
84
  "node": ">=22.14.0"
70
85
  },
@@ -0,0 +1,6 @@
1
+ {
2
+ "type": "module",
3
+ "main": "../lib/rolldown/index.cjs",
4
+ "module": "../lib/rolldown/index.mjs",
5
+ "types": "../lib/rolldown/index.d.cts"
6
+ }