@dbx-tools/projen 0.9.43 → 0.9.47

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.
Files changed (52) hide show
  1. package/README.md +28 -34
  2. package/index.ts +6 -7
  3. package/package.json +9 -10
  4. package/shims/python-node/bootstrap.ts +129 -0
  5. package/shims/python-node/child-process.ts +96 -0
  6. package/shims/python-node/crypto.ts +60 -0
  7. package/shims/python-node/fs-promises.ts +179 -0
  8. package/shims/python-node/fs.ts +173 -0
  9. package/shims/python-node/headers.ts +75 -0
  10. package/shims/python-node/host.ts +341 -0
  11. package/shims/python-node/os.ts +20 -0
  12. package/shims/python-node/process.ts +13 -0
  13. package/shims/python-node/readline.ts +37 -0
  14. package/shims/python-node/tsconfig.json +24 -0
  15. package/src/_lazy-require.ts +7 -25
  16. package/src/bun-app.ts +2 -2
  17. package/src/bun-workflow.ts +1 -9
  18. package/src/codegen.ts +20 -17
  19. package/src/dbx-tools-config.ts +52 -9
  20. package/src/generated.ts +4 -17
  21. package/src/mixin.ts +1 -5
  22. package/src/packages.ts +18 -15
  23. package/src/pnpm-workspace.ts +1 -4
  24. package/src/project-js.ts +65 -157
  25. package/src/project-predicate.ts +7 -3
  26. package/src/project-py.ts +122 -44
  27. package/src/publish.ts +13 -10
  28. package/src/python-node-bindings.ts +2 -0
  29. package/src/python-node-bundle.ts +6 -0
  30. package/src/release-options.ts +17 -17
  31. package/src/release.ts +30 -9
  32. package/src/scaffold.ts +4 -7
  33. package/src/tags.ts +6 -16
  34. package/src/vscode.ts +1 -1
  35. package/src/watch.ts +5 -5
  36. package/src/workspace-lock.ts +1 -0
  37. package/src/workspace-version.ts +4 -4
  38. package/tasks/barrels.ts +3 -5
  39. package/tasks/clean.ts +1 -0
  40. package/tasks/lib/compile-workspace.ts +41 -19
  41. package/tasks/lib/local-publish.ts +0 -28
  42. package/tasks/lib/publish-npm.ts +8 -0
  43. package/tasks/lib/publish-python.ts +4 -0
  44. package/tasks/lib/python-node-bindings.ts +77 -21
  45. package/tasks/lib/python-registry.ts +4 -0
  46. package/tasks/lib/python-release.ts +2 -0
  47. package/tasks/lib/release.ts +1 -1
  48. package/tasks/projenrc.ts +1 -0
  49. package/tasks/sync.ts +4 -4
  50. package/src/openapi.ts +0 -293
  51. package/tasks/local-publish.ts +0 -6
  52. package/tasks/openapi.ts +0 -35
@@ -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 DBX_TOOLS_CONFIG_KEY = "dbxToolsConfig";
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
- interface DBXToolsConfigData {
14
- readonly tags?: string[];
15
- readonly packageRoots?: string[];
16
- readonly syncResynthPaths?: string[];
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
- project.package.addField(DBX_TOOLS_CONFIG_KEY, () => {
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
- return {
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`: the barrels we write, openapi artifacts, and any other
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, statSync, writeFileSync } from "node:fs";
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): void => {
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/Vite, Node, agnostic, ...); a workspace **package** is a folder with a
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, watch, openapi), which is authoritative and so reflects any
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): Record<string, unknown> | undefined {
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
- return object.isRecord(config) ? config : undefined;
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 Array.isArray(tags) ? (tags as string[]) : undefined;
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, watch, openapi) uses: the manifest is
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 recorded in the root manifest. Older workspaces without
337
- * that field fall back to the distinct first segment of every recorded member,
338
- * unioned with the defaults.
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
- if (Array.isArray(configured)) {
343
- const roots = stringUtils.parseList(configured.map((root) => String(root)));
344
- if (roots.length) return roots;
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
  }
@@ -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, merged over `{ esbuild: true }`. */
141
+ /** Initial build allowances merged over the engine's reviewed defaults. */
145
142
  readonly allowBuilds?: AllowBuilds;
146
143
  }
147
144