@dbx-tools/projen 0.9.40 → 0.9.46
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/README.md +58 -67
- package/index.ts +6 -8
- package/package.json +9 -10
- package/shims/python-node/bootstrap.ts +129 -0
- package/shims/python-node/child-process.ts +96 -0
- package/shims/python-node/crypto.ts +60 -0
- package/shims/python-node/fs-promises.ts +179 -0
- package/shims/python-node/fs.ts +173 -0
- package/shims/python-node/headers.ts +75 -0
- package/shims/python-node/host.ts +341 -0
- package/shims/python-node/os.ts +20 -0
- package/shims/python-node/process.ts +13 -0
- package/shims/python-node/readline.ts +37 -0
- package/shims/python-node/tsconfig.json +24 -0
- package/src/_lazy-require.ts +7 -25
- package/src/bun-app.ts +2 -2
- package/src/bun-workflow.ts +2 -170
- package/src/codegen.ts +23 -20
- package/src/dbx-tools-config.ts +52 -9
- package/src/generated.ts +4 -17
- package/src/mixin.ts +1 -5
- package/src/packages.ts +18 -15
- package/src/pnpm-workspace.ts +1 -4
- package/src/project-js.ts +65 -196
- package/src/project-predicate.ts +7 -3
- package/src/project-py.ts +127 -37
- package/src/publish.ts +13 -10
- package/src/python-node-bindings.ts +2 -0
- package/src/python-node-bundle.ts +6 -0
- package/src/release-options.ts +17 -17
- package/src/release.ts +31 -14
- package/src/scaffold.ts +4 -7
- package/src/tags.ts +6 -16
- package/src/vscode.ts +1 -1
- package/src/watch.ts +5 -5
- package/src/workspace-lock.ts +1 -0
- package/src/workspace-version.ts +4 -4
- package/tasks/barrels.ts +3 -5
- package/tasks/clean.ts +1 -0
- package/tasks/lib/compile-workspace.ts +41 -19
- package/tasks/lib/local-publish.ts +0 -28
- package/tasks/lib/publish-npm.ts +8 -0
- package/tasks/lib/publish-python.ts +4 -0
- package/tasks/lib/python-node-bindings.ts +107 -26
- package/tasks/lib/python-registry.ts +4 -0
- package/tasks/lib/python-release.ts +2 -0
- package/tasks/lib/release.ts +2 -2
- package/tasks/projenrc.ts +1 -0
- package/tasks/sync.ts +4 -4
- package/src/openapi.ts +0 -293
- package/tasks/local-publish.ts +0 -6
- package/tasks/openapi.ts +0 -35
package/src/codegen.ts
CHANGED
|
@@ -1,20 +1,20 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Codegen generator (ts-to-zod based).
|
|
3
3
|
*
|
|
4
|
-
* Scans every package whose `
|
|
5
|
-
*
|
|
4
|
+
* Scans every package whose `dbxToolsConfig.codegenInputs` declares upstream
|
|
5
|
+
* `.d.ts` inputs and turns them into read-only `src/`
|
|
6
6
|
* modules of zod schemas plus matching inferred TypeScript types. Each input
|
|
7
7
|
* emits one `src/<name>.ts` (schemas + `export type X = z.infer<typeof
|
|
8
8
|
* xSchema>` lines); the barrel generator then namespaces it into the package's
|
|
9
9
|
* root barrel like any other `src/` module (`sdkModel.dashboards.genieMessageSchema`).
|
|
10
10
|
*
|
|
11
11
|
* The single source of truth for "which packages get generated content, from
|
|
12
|
-
* which inputs" is
|
|
12
|
+
* which inputs" is the typed config serialized into each package manifest:
|
|
13
13
|
*
|
|
14
14
|
* {
|
|
15
15
|
* "name": "@dbx-tools/shared-sdk-model",
|
|
16
|
-
* "
|
|
17
|
-
* "
|
|
16
|
+
* "dbxToolsConfig": {
|
|
17
|
+
* "codegenInputs": [
|
|
18
18
|
* "node_modules/@databricks/sdk-experimental/dist/apis/dashboards/model.d.ts"
|
|
19
19
|
* ]
|
|
20
20
|
* }
|
|
@@ -46,18 +46,23 @@
|
|
|
46
46
|
import { existsSync, mkdirSync, readdirSync, readFileSync, rmSync, writeFileSync } from "node:fs";
|
|
47
47
|
import { createRequire } from "node:module";
|
|
48
48
|
import { basename, dirname, join, resolve } from "node:path";
|
|
49
|
-
import { log
|
|
49
|
+
import { log } from "@dbx-tools/shared-core";
|
|
50
50
|
import type * as ts from "typescript";
|
|
51
51
|
import { lazyRequire } from "./_lazy-require.ts";
|
|
52
52
|
import { header, makeReadonly, makeWritable } from "./generated.ts";
|
|
53
|
-
import {
|
|
53
|
+
import {
|
|
54
|
+
readDbxToolsConfig,
|
|
55
|
+
readPackageManifest,
|
|
56
|
+
recordedPackages,
|
|
57
|
+
resolveRepoRoot,
|
|
58
|
+
} from "./packages.ts";
|
|
54
59
|
|
|
55
60
|
const logger = log.logger("projen:codegen");
|
|
56
61
|
|
|
57
62
|
/** Do-not-edit banner stamped on every generated codegen module. */
|
|
58
63
|
const HEADER = header({
|
|
59
64
|
tool: "projen synth (codegen: ts-to-zod)",
|
|
60
|
-
source: "the upstream .d.ts declared in
|
|
65
|
+
source: "the upstream .d.ts declared in dbxToolsConfig.codegenInputs",
|
|
61
66
|
});
|
|
62
67
|
|
|
63
68
|
interface CodegenInput {
|
|
@@ -77,11 +82,9 @@ function sourceLabel(source: string): string {
|
|
|
77
82
|
return source.startsWith(nodeModulesPrefix) ? source.slice(nodeModulesPrefix.length) : source;
|
|
78
83
|
}
|
|
79
84
|
|
|
80
|
-
/** Read a package's
|
|
85
|
+
/** Read a package's serialized `dbxToolsConfig.codegenInputs`, or `undefined` if absent. */
|
|
81
86
|
function codegenInputs(dir: string): string[] | undefined {
|
|
82
|
-
const
|
|
83
|
-
if (!object.isRecord(codegen)) return undefined;
|
|
84
|
-
const inputs = codegen.inputs;
|
|
87
|
+
const inputs = readDbxToolsConfig(dir)?.codegenInputs;
|
|
85
88
|
return Array.isArray(inputs) && inputs.length > 0 ? (inputs as string[]) : undefined;
|
|
86
89
|
}
|
|
87
90
|
|
|
@@ -100,7 +103,7 @@ function parseInputArg(value: string): CodegenInput {
|
|
|
100
103
|
}
|
|
101
104
|
|
|
102
105
|
/**
|
|
103
|
-
* The `src/` modules a set of
|
|
106
|
+
* The `src/` modules a set of codegen input specs will emit, as package-relative
|
|
104
107
|
* posix paths - WITHOUT resolving or reading any input.
|
|
105
108
|
*
|
|
106
109
|
* This exists so callers that only need to know WHICH files are generated (the
|
|
@@ -316,9 +319,9 @@ function generatePackage(
|
|
|
316
319
|
const sourceText = preprocess(stripImports(tsRuntime, sourcePath));
|
|
317
320
|
const { getZodSchemasFile, getInferredTypes, errors } = generate({
|
|
318
321
|
sourceText,
|
|
319
|
-
//
|
|
320
|
-
// the
|
|
321
|
-
keepComments:
|
|
322
|
+
// JSDoc is rewritten to `@description` so ts-to-zod emits `.describe()`.
|
|
323
|
+
// Keep the generated module comment-free; Zod owns the prose.
|
|
324
|
+
keepComments: false,
|
|
322
325
|
});
|
|
323
326
|
if (errors.length) {
|
|
324
327
|
for (const err of errors) logger.warn(`${destination} from ${source}: ${err}`);
|
|
@@ -344,9 +347,9 @@ function generatePackage(
|
|
|
344
347
|
}
|
|
345
348
|
|
|
346
349
|
/**
|
|
347
|
-
* Regenerate
|
|
348
|
-
*
|
|
349
|
-
*
|
|
350
|
+
* Regenerate source modules for every package declaring `dbxToolsConfig.codegenInputs`.
|
|
351
|
+
* Returns the package dirs it wrote so the caller can rebuild their barrels.
|
|
352
|
+
* `ts-to-zod` and `typescript` are lazy-loaded.
|
|
350
353
|
*/
|
|
351
354
|
export function generateCodegen(
|
|
352
355
|
projectRoot: string = resolveRepoRoot(),
|
|
@@ -365,7 +368,7 @@ export function generateCodegen(
|
|
|
365
368
|
// than printing a line about work that was never asked for. `debug` keeps it
|
|
366
369
|
// reachable when someone is actually chasing why codegen produced nothing.
|
|
367
370
|
if (targets.length === 0) {
|
|
368
|
-
logger.debug("no packages declare
|
|
371
|
+
logger.debug("no packages declare dbxToolsConfig.codegenInputs");
|
|
369
372
|
return [];
|
|
370
373
|
}
|
|
371
374
|
|
package/src/dbx-tools-config.ts
CHANGED
|
@@ -1,25 +1,62 @@
|
|
|
1
1
|
/** Typed `package.json` `dbxToolsConfig` record for a package. */
|
|
2
2
|
import { javascript } from "projen";
|
|
3
|
+
import { z } from "zod";
|
|
3
4
|
|
|
4
5
|
/** `package.json` field name for the dbx-tools config object. */
|
|
5
|
-
const
|
|
6
|
+
const CONFIG_KEY = "dbxToolsConfig";
|
|
6
7
|
|
|
7
8
|
/** Options for {@link DBXToolsConfig}. */
|
|
8
9
|
export interface DBXToolsConfigOptions {
|
|
9
10
|
/** Initial tags to record (distinct; order preserved). */
|
|
10
11
|
readonly tags?: string[];
|
|
12
|
+
/** Declaration inputs converted to generated Zod modules (distinct; order preserved). */
|
|
13
|
+
readonly codegenInputs?: string[];
|
|
14
|
+
/** Whether the package receives compiled npm publication machinery. */
|
|
15
|
+
readonly publishable?: boolean;
|
|
11
16
|
}
|
|
12
17
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
+
/** Serialized dbx-tools package and workspace generator configuration. */
|
|
19
|
+
export const DBXToolsConfigDataSchema = z
|
|
20
|
+
.object({
|
|
21
|
+
tags: z.array(z.string().min(1)).readonly().optional().describe("Package runtime tags."),
|
|
22
|
+
codegenInputs: z
|
|
23
|
+
.array(z.string().min(1))
|
|
24
|
+
.readonly()
|
|
25
|
+
.optional()
|
|
26
|
+
.describe("Declaration inputs converted to generated Zod modules."),
|
|
27
|
+
packageRoots: z
|
|
28
|
+
.array(z.string().min(1))
|
|
29
|
+
.readonly()
|
|
30
|
+
.optional()
|
|
31
|
+
.describe("Repository paths scanned for JavaScript packages."),
|
|
32
|
+
publishable: z
|
|
33
|
+
.boolean()
|
|
34
|
+
.optional()
|
|
35
|
+
.describe("Whether compiled npm publication machinery is enabled."),
|
|
36
|
+
syncResynthPaths: z
|
|
37
|
+
.array(z.string().min(1))
|
|
38
|
+
.readonly()
|
|
39
|
+
.optional()
|
|
40
|
+
.describe("Additional paths that trigger watcher resynthesis."),
|
|
41
|
+
})
|
|
42
|
+
.strict()
|
|
43
|
+
.readonly()
|
|
44
|
+
.describe("dbxToolsConfig serialized in a generated package manifest.");
|
|
45
|
+
|
|
46
|
+
/** Serialized dbx-tools package and workspace generator configuration. */
|
|
47
|
+
export type DBXToolsConfigData = z.infer<typeof DBXToolsConfigDataSchema>;
|
|
18
48
|
|
|
19
49
|
/** Owns the typed in-memory `dbxToolsConfig` written to `package.json`. */
|
|
20
50
|
export class DBXToolsConfig {
|
|
51
|
+
/** Runtime tags that select package mixins. */
|
|
21
52
|
readonly tags: string[];
|
|
53
|
+
/** Declaration inputs converted to generated Zod modules. */
|
|
54
|
+
readonly codegenInputs: string[];
|
|
55
|
+
/** Repository paths scanned for JavaScript package discovery. */
|
|
22
56
|
packageRoots?: string[];
|
|
57
|
+
/** Whether compiled npm publication machinery is enabled. */
|
|
58
|
+
publishable: boolean;
|
|
59
|
+
/** Additional repository paths that trigger watcher resynthesis. */
|
|
23
60
|
syncResynthPaths?: string[];
|
|
24
61
|
|
|
25
62
|
constructor(
|
|
@@ -27,18 +64,24 @@ export class DBXToolsConfig {
|
|
|
27
64
|
options: DBXToolsConfigOptions = {},
|
|
28
65
|
) {
|
|
29
66
|
this.tags = [...(options.tags ?? [])];
|
|
30
|
-
|
|
67
|
+
this.codegenInputs = [...(options.codegenInputs ?? [])];
|
|
68
|
+
this.publishable = options.publishable ?? true;
|
|
69
|
+
project.package.addField(CONFIG_KEY, () => {
|
|
31
70
|
const data = this.data();
|
|
32
71
|
return Object.keys(data).length === 0 ? undefined : data;
|
|
33
72
|
});
|
|
34
73
|
}
|
|
35
74
|
|
|
75
|
+
/** Render the serializable package manifest record. */
|
|
36
76
|
data(): DBXToolsConfigData {
|
|
37
77
|
const tags = [...new Set(this.tags)];
|
|
38
|
-
|
|
78
|
+
const codegenInputs = [...new Set(this.codegenInputs)];
|
|
79
|
+
return DBXToolsConfigDataSchema.parse({
|
|
39
80
|
...(tags.length ? { tags } : {}),
|
|
81
|
+
...(codegenInputs.length ? { codegenInputs } : {}),
|
|
82
|
+
...(!this.publishable ? { publishable: false } : {}),
|
|
40
83
|
...(this.packageRoots?.length ? { packageRoots: this.packageRoots } : {}),
|
|
41
84
|
...(this.syncResynthPaths?.length ? { syncResynthPaths: this.syncResynthPaths } : {}),
|
|
42
|
-
};
|
|
85
|
+
});
|
|
43
86
|
}
|
|
44
87
|
}
|
package/src/generated.ts
CHANGED
|
@@ -1,14 +1,14 @@
|
|
|
1
1
|
/**
|
|
2
2
|
* Read-only / do-not-edit helpers for generated output projen does not own as a
|
|
3
|
-
* native `FileBase`:
|
|
4
|
-
* toolchain file stamped via {@link stampGenerated}.
|
|
3
|
+
* native `FileBase`: package barrels, codegen modules, PythonMonkey bundles,
|
|
4
|
+
* and any other toolchain file stamped via {@link stampGenerated}.
|
|
5
5
|
*
|
|
6
6
|
* projen already writes its own generated files read-only with a marker; these give
|
|
7
7
|
* barrels and other watch-time output the same contract - a do-not-edit header and a
|
|
8
8
|
* read-only (0o444) bit. Rewriting one therefore goes through {@link makeWritable}
|
|
9
9
|
* first, then {@link stampGenerated}.
|
|
10
10
|
*/
|
|
11
|
-
import { chmodSync, existsSync, readFileSync,
|
|
11
|
+
import { chmodSync, existsSync, readFileSync, writeFileSync } from "node:fs";
|
|
12
12
|
|
|
13
13
|
/** First line of every banner {@link header} builds. */
|
|
14
14
|
const MARKER = "// GENERATED by";
|
|
@@ -26,20 +26,7 @@ export function makeReadonly(file: string): void {
|
|
|
26
26
|
if (existsSync(file)) chmodSync(file, READONLY);
|
|
27
27
|
}
|
|
28
28
|
|
|
29
|
-
/**
|
|
30
|
-
* True if the file exists and has no owner-write bit. This is the toolchain's
|
|
31
|
-
* generated-file signal: everything projen and the barrel generator write is set read-only
|
|
32
|
-
* (see {@link makeReadonly}), while hand-authored source stays writable - so a
|
|
33
|
-
* read-only file under the repo (outside vendor/build dirs) is a generated file.
|
|
34
|
-
*/
|
|
35
|
-
export function isReadonly(file: string): boolean {
|
|
36
|
-
try {
|
|
37
|
-
return (statSync(file).mode & 0o200) === 0;
|
|
38
|
-
} catch {
|
|
39
|
-
return false;
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
|
|
29
|
+
/** Inputs for the durable generated-file banner. */
|
|
43
30
|
export interface HeaderOpts {
|
|
44
31
|
/** What produced the file, e.g. `"projen watch"`. */
|
|
45
32
|
readonly tool: string;
|
package/src/mixin.ts
CHANGED
|
@@ -38,10 +38,6 @@ export function create(
|
|
|
38
38
|
): ConstructsMixin {
|
|
39
39
|
return {
|
|
40
40
|
supports,
|
|
41
|
-
applyTo: (construct: IConstruct)
|
|
42
|
-
if (supports(construct)) {
|
|
43
|
-
(applyTo as (construct: IConstruct) => void)(construct);
|
|
44
|
-
}
|
|
45
|
-
},
|
|
41
|
+
applyTo: applyTo as (construct: IConstruct) => void,
|
|
46
42
|
};
|
|
47
43
|
}
|
package/src/packages.ts
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
* Package discovery + shared filesystem helpers.
|
|
3
3
|
*
|
|
4
4
|
* Terminology (Bit-style): a **tag** names a target environment
|
|
5
|
-
* (React/
|
|
5
|
+
* (React/Bun, Node, agnostic, ...); a workspace **package** is a folder with a
|
|
6
6
|
* `src/` holding at least one module file (`.ts`/`.tsx`/`.js`/`.jsx`). "Scope" is
|
|
7
7
|
* reserved for the npm `@scope/` in package identifiers (e.g. `@dbx-tools/ui-app`).
|
|
8
8
|
*
|
|
@@ -20,7 +20,7 @@
|
|
|
20
20
|
* path relative to the root, reading NO manifest. {@link recordedPackages} reads
|
|
21
21
|
* the recorded members from `pnpm-workspace.yaml` - the SOURCE OF TRUTH - and
|
|
22
22
|
* augments each with the `name` and `tags` read back from its own `package.json`
|
|
23
|
-
* (post-synth: barrels
|
|
23
|
+
* (post-synth: barrels and watch), which is authoritative and so reflects any
|
|
24
24
|
* synth-time name override or resolved tag set.
|
|
25
25
|
*/
|
|
26
26
|
import { existsSync, readFileSync } from "node:fs";
|
|
@@ -29,6 +29,7 @@ import * as projectUtils from "@dbx-tools/core/project-utils";
|
|
|
29
29
|
import { find } from "@dbx-tools/path";
|
|
30
30
|
import { json, object, stringUtils } from "@dbx-tools/shared-core";
|
|
31
31
|
import { parse } from "yaml";
|
|
32
|
+
import { DBXToolsConfigDataSchema, type DBXToolsConfigData } from "./dbx-tools-config.ts";
|
|
32
33
|
import { isGenerated } from "./generated.ts";
|
|
33
34
|
|
|
34
35
|
/** Resolve the nearest package/projenrc root at call time. */
|
|
@@ -255,16 +256,18 @@ export function readPackageManifest(dir: string): Record<string, unknown> | unde
|
|
|
255
256
|
}
|
|
256
257
|
}
|
|
257
258
|
|
|
258
|
-
/** A package's `dbxToolsConfig` object, or `undefined` when absent. */
|
|
259
|
-
export function readDbxToolsConfig(dir: string):
|
|
259
|
+
/** A package's validated `dbxToolsConfig` object, or `undefined` when absent. */
|
|
260
|
+
export function readDbxToolsConfig(dir: string): DBXToolsConfigData | undefined {
|
|
260
261
|
const config = readPackageManifest(dir)?.dbxToolsConfig;
|
|
261
|
-
|
|
262
|
+
if (config === undefined) return undefined;
|
|
263
|
+
const parsed = DBXToolsConfigDataSchema.safeParse(config);
|
|
264
|
+
return parsed.success ? parsed.data : undefined;
|
|
262
265
|
}
|
|
263
266
|
|
|
264
267
|
/** Read `<dir>/package.json`'s `dbxToolsConfig.tags` (`undefined` if absent). */
|
|
265
268
|
function readManifestTags(dir: string): string[] | undefined {
|
|
266
269
|
const tags = readDbxToolsConfig(dir)?.tags;
|
|
267
|
-
return
|
|
270
|
+
return tags ? [...tags] : undefined;
|
|
268
271
|
}
|
|
269
272
|
|
|
270
273
|
/**
|
|
@@ -280,7 +283,7 @@ export function syncResynthPaths(projectRoot: string = resolveRepoRoot()): strin
|
|
|
280
283
|
/**
|
|
281
284
|
* The recorded workspace members from `pnpm-workspace.yaml` (the source of truth),
|
|
282
285
|
* each augmented with the `tags` read back from its `package.json`. This is what
|
|
283
|
-
* every post-synth command (barrels
|
|
286
|
+
* every post-synth command (barrels and watch) uses: the manifest is
|
|
284
287
|
* authoritative, so it reflects the resolved tag set.
|
|
285
288
|
* Sorted by path.
|
|
286
289
|
*/
|
|
@@ -333,18 +336,18 @@ export function workspaceDependencyDirectories(
|
|
|
333
336
|
}
|
|
334
337
|
|
|
335
338
|
/**
|
|
336
|
-
* The configured roots
|
|
337
|
-
*
|
|
338
|
-
*
|
|
339
|
+
* The configured package roots plus the first segment of every recorded member.
|
|
340
|
+
* The member union includes self-synthesizing extra workspace members; older
|
|
341
|
+
* manifests without configured roots fall back to {@link DEFAULT_PACKAGE_ROOTS}.
|
|
339
342
|
*/
|
|
340
343
|
export function recordedRoots(projectRoot: string = resolveRepoRoot()): string[] {
|
|
341
344
|
const configured = readDbxToolsConfig(projectRoot)?.packageRoots;
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
const roots = new Set<string>(DEFAULT_PACKAGE_ROOTS);
|
|
345
|
+
const configuredRoots = Array.isArray(configured)
|
|
346
|
+
? stringUtils.parseList(configured.map((root) => String(root)))
|
|
347
|
+
: [];
|
|
348
|
+
const roots = new Set<string>(configuredRoots.length ? configuredRoots : DEFAULT_PACKAGE_ROOTS);
|
|
347
349
|
for (const member of readRecordedMembers(projectRoot)) {
|
|
350
|
+
if (configuredRoots.some((root) => member === root || member.startsWith(`${root}/`))) continue;
|
|
348
351
|
const pkg = packageOfMember(projectRoot, member);
|
|
349
352
|
if (pkg) roots.add(pkg.root);
|
|
350
353
|
}
|
package/src/pnpm-workspace.ts
CHANGED
|
@@ -76,9 +76,6 @@ const DEFAULT_CATALOG: Catalog = {
|
|
|
76
76
|
typescript: "^5.9.3",
|
|
77
77
|
commander: "^15.0.0",
|
|
78
78
|
"@clack/prompts": "^1.7.0",
|
|
79
|
-
"openapi-fetch": "^0.17.0",
|
|
80
|
-
tsoa: "^6.6.0",
|
|
81
|
-
concurrently: "^10.0.3",
|
|
82
79
|
"@databricks/appkit": "0.81.0",
|
|
83
80
|
"@databricks/appkit-ui": "0.81.0",
|
|
84
81
|
"@databricks/sdk-experimental": "^0.17.0",
|
|
@@ -141,7 +138,7 @@ const DEFAULT_WORKSPACE_YAML: javascript.PnpmWorkspaceYamlOptions = {
|
|
|
141
138
|
export interface DBXToolsPNPMWorkspaceOptions {
|
|
142
139
|
/** Initial `catalog:` registry. Defaults to {@link DEFAULT_CATALOG}. */
|
|
143
140
|
readonly catalog?: Catalog;
|
|
144
|
-
/** Initial build allowances
|
|
141
|
+
/** Initial build allowances merged over the engine's reviewed defaults. */
|
|
145
142
|
readonly allowBuilds?: AllowBuilds;
|
|
146
143
|
}
|
|
147
144
|
|