@forwardimpact/libcodegen 0.1.58 → 0.1.60
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/bin/fit-codegen.js +12 -0
- package/package.json +2 -2
- package/src/base.js +32 -15
package/bin/fit-codegen.js
CHANGED
|
@@ -110,6 +110,7 @@ function parseFlags() {
|
|
|
110
110
|
const { values } = parsed;
|
|
111
111
|
const doAll = values.all;
|
|
112
112
|
return {
|
|
113
|
+
doAll,
|
|
113
114
|
doTypes: doAll || values.type,
|
|
114
115
|
doServices: doAll || values.service,
|
|
115
116
|
doClients: doAll || values.client,
|
|
@@ -327,6 +328,17 @@ async function runCodegen(protoDirs, projectRoot, finder) {
|
|
|
327
328
|
|
|
328
329
|
await generatedStorage.ensureBucket();
|
|
329
330
|
|
|
331
|
+
// Full regeneration (--all) clears the content directories first so that a
|
|
332
|
+
// renamed or removed proto leaves no orphaned per-proto artifacts. The
|
|
333
|
+
// services exports step scans the services/ directory, so a stale service
|
|
334
|
+
// dir would otherwise be re-exported and import types that no longer exist.
|
|
335
|
+
// Partial flags intentionally preserve sibling artifacts and are not cleaned.
|
|
336
|
+
if (parsedFlags.doAll) {
|
|
337
|
+
for (const dir of ["types", "services", "definitions", "proto"]) {
|
|
338
|
+
fs.rmSync(path.join(sourcePath, dir), { recursive: true, force: true });
|
|
339
|
+
}
|
|
340
|
+
}
|
|
341
|
+
|
|
330
342
|
// Write package.json with "type": "module" so Node.js treats generated
|
|
331
343
|
// ES module files correctly and avoids MODULE_TYPELESS_PACKAGE_JSON warnings.
|
|
332
344
|
const generatedPkgPath = path.join(sourcePath, "package.json");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@forwardimpact/libcodegen",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.60",
|
|
4
4
|
"description": "Protobuf code generation — keep types in sync with proto definitions without hand-writing.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"codegen",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"protobufjs-cli": "1.2.2"
|
|
57
57
|
},
|
|
58
58
|
"devDependencies": {
|
|
59
|
-
"@forwardimpact/
|
|
59
|
+
"@forwardimpact/libmock": "^0.1.0"
|
|
60
60
|
},
|
|
61
61
|
"engines": {
|
|
62
62
|
"bun": ">=1.2.0",
|
package/src/base.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { execFile } from "node:child_process";
|
|
2
1
|
import { fileURLToPath } from "node:url";
|
|
3
2
|
import protobuf from "protobufjs";
|
|
3
|
+
import { createDefaultRuntime } from "@forwardimpact/libutil/runtime";
|
|
4
4
|
|
|
5
5
|
/** Convert camelCase to snake_case (protobufjs normalizes field names) */
|
|
6
6
|
function camelToSnake(str) {
|
|
@@ -61,6 +61,7 @@ export class CodegenBase {
|
|
|
61
61
|
#mustache;
|
|
62
62
|
#protoLoader;
|
|
63
63
|
#fs;
|
|
64
|
+
#subprocess;
|
|
64
65
|
|
|
65
66
|
/**
|
|
66
67
|
* Creates a new codegen base instance with dependency injection
|
|
@@ -70,8 +71,17 @@ export class CodegenBase {
|
|
|
70
71
|
* @param {object} mustache - Mustache template rendering module
|
|
71
72
|
* @param {object} protoLoader - Protocol buffer loader module
|
|
72
73
|
* @param {object} fs - File system module (sync operations only)
|
|
74
|
+
* @param {object} [runtime] - Optional runtime bag; falls back to createDefaultRuntime()
|
|
73
75
|
*/
|
|
74
|
-
constructor(
|
|
76
|
+
constructor(
|
|
77
|
+
protoDirs,
|
|
78
|
+
projectRoot,
|
|
79
|
+
path,
|
|
80
|
+
mustache,
|
|
81
|
+
protoLoader,
|
|
82
|
+
fs,
|
|
83
|
+
runtime,
|
|
84
|
+
) {
|
|
75
85
|
if (!protoDirs || !Array.isArray(protoDirs) || protoDirs.length === 0) {
|
|
76
86
|
throw new Error("protoDirs must be a non-empty array");
|
|
77
87
|
}
|
|
@@ -87,6 +97,7 @@ export class CodegenBase {
|
|
|
87
97
|
this.#mustache = mustache;
|
|
88
98
|
this.#protoLoader = protoLoader;
|
|
89
99
|
this.#fs = fs;
|
|
100
|
+
this.#subprocess = (runtime ?? createDefaultRuntime()).subprocess;
|
|
90
101
|
}
|
|
91
102
|
|
|
92
103
|
/**
|
|
@@ -182,22 +193,28 @@ export class CodegenBase {
|
|
|
182
193
|
* Run a command with arguments and options
|
|
183
194
|
* @param {string} cmd - Command to execute
|
|
184
195
|
* @param {string[]} args - Command-line arguments
|
|
185
|
-
* @param {object} [opts] -
|
|
196
|
+
* @param {object} [opts] - Subprocess options (e.g. cwd)
|
|
186
197
|
* @returns {Promise<void>} Resolves when the command completes successfully
|
|
187
198
|
*/
|
|
188
|
-
run(cmd, args, opts = {}) {
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
child.on("error", reject);
|
|
199
|
+
async run(cmd, args, opts = {}) {
|
|
200
|
+
// `stdio: "inherit"` forwards to the underlying execFile/spawn so the
|
|
201
|
+
// child's stdout/stderr go straight to the parent's fds — preserving the
|
|
202
|
+
// exact pre-1370 behavior (origin/main also ran execFile with
|
|
203
|
+
// stdio:"inherit"), so `just codegen` shows protoc/pbjs progress live.
|
|
204
|
+
// With inherited stdio the buffered result is empty, so the error path
|
|
205
|
+
// below falls back to the exit code. Capture-mode callers override via
|
|
206
|
+
// `opts.stdio`.
|
|
207
|
+
const result = await this.#subprocess.run(cmd, args, {
|
|
208
|
+
stdio: "inherit",
|
|
209
|
+
...opts,
|
|
200
210
|
});
|
|
211
|
+
if (result.exitCode !== 0) {
|
|
212
|
+
const msg =
|
|
213
|
+
result.stderr?.trim() ||
|
|
214
|
+
result.stdout?.trim() ||
|
|
215
|
+
`exited with code ${result.exitCode}`;
|
|
216
|
+
throw new Error(`Command failed: ${cmd} ${args.join(" ")}\n${msg}`);
|
|
217
|
+
}
|
|
201
218
|
}
|
|
202
219
|
|
|
203
220
|
/**
|