@dbx-tools/projen 0.9.32 → 0.9.37
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 +71 -65
- package/index.ts +5 -8
- package/package.json +8 -7
- package/src/_task-command.ts +0 -75
- package/src/barrels.ts +15 -23
- package/src/bun-app.ts +5 -6
- package/src/clean.ts +41 -15
- package/src/codegen.ts +2 -3
- package/src/dbx-tools-config.ts +23 -64
- package/src/generated.ts +7 -1
- package/src/module-exports.ts +35 -3
- package/src/openapi.ts +34 -38
- package/src/packages.ts +3 -30
- package/src/pnpm-workspace.ts +21 -26
- package/src/project-js.ts +152 -365
- package/src/project-predicate.ts +4 -5
- package/src/project-py.ts +55 -144
- package/src/publish.ts +1 -1
- package/src/python-node-bindings.ts +140 -67
- package/src/python-node-bundle.ts +6 -42
- package/src/release-context.ts +4 -4
- package/src/release.ts +47 -85
- package/src/tags.ts +20 -18
- package/src/tsconfig.ts +9 -5
- package/src/vscode.ts +47 -58
- package/src/watch.ts +2 -8
- package/src/workspace-version.ts +1 -6
- package/tasks/barrels.ts +43 -38
- package/tasks/bump.ts +24 -20
- package/tasks/clean.ts +54 -50
- package/tasks/compile-workspace.ts +2 -117
- package/tasks/lib/compile-workspace.ts +119 -0
- package/tasks/lib/local-publish.ts +122 -0
- package/tasks/lib/publish-npm.ts +458 -0
- package/tasks/lib/publish-python.ts +195 -0
- package/tasks/lib/publish.ts +264 -0
- package/tasks/lib/python-node-bindings.ts +1262 -0
- package/tasks/{python-registry.ts → lib/python-registry.ts} +21 -30
- package/tasks/{python-release.ts → lib/python-release.ts} +1 -0
- package/tasks/lib/release-version.ts +66 -0
- package/tasks/lib/release.ts +212 -0
- package/tasks/local-publish.ts +4 -118
- package/tasks/openapi.ts +25 -21
- package/tasks/projenrc.ts +14 -12
- package/tasks/publish-npm.ts +3 -364
- package/tasks/publish-python.ts +3 -184
- package/tasks/publish.ts +3 -279
- package/tasks/python-node-bindings.ts +3 -1014
- package/tasks/release-version.ts +3 -62
- package/tasks/release.ts +3 -121
- package/tasks/sync.ts +71 -70
- package/tasks/version-check.ts +3 -10
- package/src/release-catalog.ts +0 -684
- package/tasks/databricks-cli-assets.ts +0 -129
- package/tasks/python-node-bindings-watch.ts +0 -47
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import { Component, type Project, type Task } from "projen";
|
|
2
|
-
import {
|
|
3
|
-
import { isDBXToolsJavaScriptProject } from "./project-predicate.ts";
|
|
2
|
+
import { taskCommand } from "./project-js.ts";
|
|
4
3
|
|
|
5
4
|
/** One function replaced only in a generated PythonMonkey bundle. */
|
|
6
5
|
export interface PythonNodeFunctionOverride {
|
|
@@ -20,12 +19,8 @@ export interface PythonNodeBindingsOptions {
|
|
|
20
19
|
readonly package: string;
|
|
21
20
|
/** Optional portable package subpath to bind. Defaults to {@link package}. */
|
|
22
21
|
readonly entrypoint?: string;
|
|
23
|
-
/**
|
|
24
|
-
readonly
|
|
25
|
-
/** Keep generated symbols out of the generated package `__init__`. Defaults to false. */
|
|
26
|
-
readonly private?: boolean;
|
|
27
|
-
/** Repository-relative directory containing Node built-in shims. */
|
|
28
|
-
readonly shimRoot?: string;
|
|
22
|
+
/** Automatically generated root namespace modules to bind independently. */
|
|
23
|
+
readonly modules?: readonly string[];
|
|
29
24
|
/** Functions replaced only while generating the Python runtime. */
|
|
30
25
|
readonly functionOverrides?: readonly PythonNodeFunctionOverride[];
|
|
31
26
|
}
|
|
@@ -38,55 +33,24 @@ export interface PythonNodeBundleOptions {
|
|
|
38
33
|
readonly projectDirectory: string;
|
|
39
34
|
/** Add the freshness check to the project's test task. Defaults to true. */
|
|
40
35
|
readonly test?: boolean;
|
|
41
|
-
/** Regenerate during the root workspace watch loop. Defaults to false. */
|
|
42
|
-
readonly watch?: boolean;
|
|
43
36
|
}
|
|
44
37
|
|
|
45
38
|
/** Owns paired generation and freshness-check tasks for one Python package. */
|
|
46
39
|
export class PythonNodeBundle extends Component {
|
|
47
40
|
readonly buildTask: Task;
|
|
48
41
|
readonly checkTask: Task;
|
|
49
|
-
readonly watchTask?: Task;
|
|
50
42
|
|
|
51
43
|
constructor(project: Project, options: PythonNodeBundleOptions) {
|
|
52
44
|
super(project);
|
|
53
|
-
const command =
|
|
54
|
-
project,
|
|
55
|
-
"python-node-bindings.ts",
|
|
56
|
-
`--project ${shellQuote(options.projectDirectory)}`,
|
|
57
|
-
);
|
|
45
|
+
const command = taskCommand("python-node-bindings.ts", "--project", options.projectDirectory);
|
|
58
46
|
this.buildTask = project.addTask(`${options.name}:python-runtime`, {
|
|
59
47
|
description: `Generate Node bindings for Python package ${options.name}`,
|
|
60
|
-
|
|
48
|
+
execArgs: command,
|
|
61
49
|
});
|
|
62
50
|
this.checkTask = project.addTask(`${options.name}:python-runtime:check`, {
|
|
63
51
|
description: `Verify generated Node bindings for Python package ${options.name}`,
|
|
64
|
-
|
|
52
|
+
execArgs: [...command, "--check"],
|
|
65
53
|
});
|
|
66
54
|
if (options.test ?? true) project.testTask.spawn(this.checkTask);
|
|
67
|
-
if (options.watch) {
|
|
68
|
-
this.watchTask = project.addTask(`${options.name}:python-runtime:watch`, {
|
|
69
|
-
description: `Regenerate Node bindings for Python package ${options.name} on changes`,
|
|
70
|
-
exec: taskScript(
|
|
71
|
-
project,
|
|
72
|
-
"python-node-bindings-watch.ts",
|
|
73
|
-
`--project ${shellQuote(options.projectDirectory)}`,
|
|
74
|
-
),
|
|
75
|
-
});
|
|
76
|
-
if (isDBXToolsJavaScriptProject()(project)) {
|
|
77
|
-
const configured = project.dbxToolsConfig.pythonNodeBindings;
|
|
78
|
-
const projects = Array.isArray(configured)
|
|
79
|
-
? configured.filter((value): value is string => typeof value === "string")
|
|
80
|
-
: [];
|
|
81
|
-
project.dbxToolsConfig.pythonNodeBindings = [
|
|
82
|
-
...new Set([...projects, options.projectDirectory]),
|
|
83
|
-
];
|
|
84
|
-
}
|
|
85
|
-
}
|
|
86
55
|
}
|
|
87
56
|
}
|
|
88
|
-
|
|
89
|
-
function shellQuote(value: string): string {
|
|
90
|
-
if (/^[A-Za-z0-9_./:@=+#-]+$/.test(value)) return value;
|
|
91
|
-
return `'${value.replaceAll("'", `'\\''`)}'`;
|
|
92
|
-
}
|
package/src/release-context.ts
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
/** Verified release context shared by every job in the unified workflow. */
|
|
2
|
+
import { github } from "projen";
|
|
2
3
|
import type { JobStep } from "projen/lib/github/workflows-model";
|
|
3
4
|
|
|
4
5
|
export const RELEASE_TAG = "${{ needs.verify-context.outputs.release_tag }}";
|
|
@@ -8,14 +9,13 @@ export const RELEASE_VERSION = "${{ needs.verify-context.outputs.release_version
|
|
|
8
9
|
/** Check out and verify the immutable commit selected by the release tag. */
|
|
9
10
|
export function releaseSourceSteps(): readonly JobStep[] {
|
|
10
11
|
return [
|
|
11
|
-
{
|
|
12
|
+
github.WorkflowSteps.checkout({
|
|
12
13
|
name: "Checkout release commit",
|
|
13
|
-
uses: "actions/checkout@v6",
|
|
14
14
|
with: {
|
|
15
15
|
ref: RELEASE_SHA,
|
|
16
|
-
|
|
16
|
+
fetchDepth: 1,
|
|
17
17
|
},
|
|
18
|
-
},
|
|
18
|
+
}),
|
|
19
19
|
{
|
|
20
20
|
name: "Verify release source",
|
|
21
21
|
shell: "bash",
|
package/src/release.ts
CHANGED
|
@@ -1,23 +1,18 @@
|
|
|
1
1
|
/** Unified default-branch release workflow generation. */
|
|
2
2
|
import { stringUtils } from "@dbx-tools/shared-core";
|
|
3
|
-
import { Component } from "projen";
|
|
3
|
+
import { Component, github } from "projen";
|
|
4
4
|
import { GithubWorkflow } from "projen/lib/github";
|
|
5
5
|
import { JobPermission, type Job, type JobStep } from "projen/lib/github/workflows-model";
|
|
6
|
-
import { BUN_VERSION
|
|
7
|
-
import { projectReleaseBranch, type DBXToolsJavaScriptProject } from "./project-js.ts";
|
|
8
|
-
import { applyTasks, taskScript } from "./project.ts";
|
|
6
|
+
import { BUN_VERSION } from "./bun-workflow.ts";
|
|
7
|
+
import { projectReleaseBranch, taskCommand, type DBXToolsJavaScriptProject } from "./project-js.ts";
|
|
9
8
|
import { RELEASE_VERSION, releaseSourceSteps } from "./release-context.ts";
|
|
10
9
|
|
|
11
10
|
const NODE_VERSION = "24";
|
|
12
11
|
const NPM_VERSION = "11.4.2";
|
|
13
12
|
const NPM_REGISTRY_URL = "https://registry.npmjs.org";
|
|
14
|
-
const nodeReleaseProjects = new WeakSet<DBXToolsJavaScriptProject>();
|
|
15
13
|
const releaseTagPrefixes = new WeakMap<DBXToolsJavaScriptProject, string>();
|
|
16
14
|
const releaseWorkflows = new WeakMap<DBXToolsJavaScriptProject, GithubWorkflow>();
|
|
17
15
|
|
|
18
|
-
/** Independently recoverable portions of the release workflow. */
|
|
19
|
-
export type ReleaseStage = "all" | "node" | "python" | "docs";
|
|
20
|
-
|
|
21
16
|
/** GitHub Pages configuration included in the unified release workflow. */
|
|
22
17
|
export interface ReleaseDocsOptions {
|
|
23
18
|
readonly siteUrl: string;
|
|
@@ -44,23 +39,11 @@ export interface DBXToolsReleaseOptions {
|
|
|
44
39
|
readonly validationTasks?: readonly string[];
|
|
45
40
|
}
|
|
46
41
|
|
|
47
|
-
/** Locate the unified workflow so attached language workspaces can add jobs. */
|
|
48
|
-
export function releaseWorkflow(project: DBXToolsJavaScriptProject): GithubWorkflow {
|
|
49
|
-
const workflow = releaseWorkflows.get(project);
|
|
50
|
-
if (!workflow) throw new Error("Release workflow is not configured");
|
|
51
|
-
return workflow;
|
|
52
|
-
}
|
|
53
|
-
|
|
54
42
|
/** Locate the unified workflow when release generation is enabled. */
|
|
55
43
|
export function tryReleaseWorkflow(project: DBXToolsJavaScriptProject): GithubWorkflow | undefined {
|
|
56
44
|
return releaseWorkflows.get(project);
|
|
57
45
|
}
|
|
58
46
|
|
|
59
|
-
/** Whether the unified workflow publishes the normal npm workspace. */
|
|
60
|
-
export function hasNodeRelease(project: DBXToolsJavaScriptProject): boolean {
|
|
61
|
-
return nodeReleaseProjects.has(project);
|
|
62
|
-
}
|
|
63
|
-
|
|
64
47
|
/** Tag pattern created by release jobs and accepted by manual recovery. */
|
|
65
48
|
export function releaseTagPattern(project: DBXToolsJavaScriptProject): string {
|
|
66
49
|
const prefix = releaseTagPrefixes.get(project);
|
|
@@ -68,29 +51,17 @@ export function releaseTagPattern(project: DBXToolsJavaScriptProject): string {
|
|
|
68
51
|
return `${prefix}*`;
|
|
69
52
|
}
|
|
70
53
|
|
|
71
|
-
/** Run a release
|
|
72
|
-
export function
|
|
73
|
-
_stage: Exclude<ReleaseStage, "all">,
|
|
74
|
-
prerequisites: readonly string[] = [],
|
|
75
|
-
): string {
|
|
54
|
+
/** Run a release job after all explicit prerequisite results succeed. */
|
|
55
|
+
export function releaseCondition(prerequisites: readonly string[] = []): string {
|
|
76
56
|
if (prerequisites.length === 0) return "${{ success() }}";
|
|
77
57
|
return `\${{ always() && ${prerequisites.map((condition) => `(${condition})`).join(" && ")} }}`;
|
|
78
58
|
}
|
|
79
59
|
|
|
80
|
-
/**
|
|
81
|
-
export function releasePublishCondition(
|
|
82
|
-
_stage: Exclude<ReleaseStage, "all">,
|
|
83
|
-
prerequisites: readonly string[] = [],
|
|
84
|
-
): string {
|
|
85
|
-
if (prerequisites.length === 0) return "${{ success() }}";
|
|
86
|
-
return `\${{ always() && ${prerequisites.map((condition) => `(${condition})`).join(" && ")} }}`;
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
/** Shared Bun, Node, cache, and install setup for Node release jobs. */
|
|
60
|
+
/** Native project setup plus npm publication authentication. */
|
|
90
61
|
export function nodeReleaseSetupSteps(project: DBXToolsJavaScriptProject): readonly JobStep[] {
|
|
91
62
|
return [
|
|
92
63
|
...releaseSourceSteps(),
|
|
93
|
-
...
|
|
64
|
+
...project.renderWorkflowSetup({ mutable: false }),
|
|
94
65
|
{
|
|
95
66
|
name: "Setup Node.js",
|
|
96
67
|
uses: "actions/setup-node@v6",
|
|
@@ -101,20 +72,9 @@ export function nodeReleaseSetupSteps(project: DBXToolsJavaScriptProject): reado
|
|
|
101
72
|
},
|
|
102
73
|
},
|
|
103
74
|
{ name: "Install npm CLI", run: `npm install --global npm@${NPM_VERSION}` },
|
|
104
|
-
{ name: "Install", run: "bun install" },
|
|
105
|
-
bunCacheSaveStep(),
|
|
106
75
|
];
|
|
107
76
|
}
|
|
108
77
|
|
|
109
|
-
/** Token authentication, GitHub provenance, and dry-run values shared by npm publishers. */
|
|
110
|
-
export function npmPublishEnvironment(): Record<string, string> {
|
|
111
|
-
return {
|
|
112
|
-
NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}",
|
|
113
|
-
NPM_CONFIG_PROVENANCE: "true",
|
|
114
|
-
DRY_RUN: "",
|
|
115
|
-
};
|
|
116
|
-
}
|
|
117
|
-
|
|
118
78
|
/** Install uv and restore its download/build cache using Python manifests. */
|
|
119
79
|
export function uvSetupStep(): JobStep {
|
|
120
80
|
return {
|
|
@@ -141,7 +101,9 @@ function refreshDocsRegistryDependencies(workflow: GithubWorkflow): void {
|
|
|
141
101
|
/** Keep documentation publication behind every configured package registry. */
|
|
142
102
|
export function refreshReleaseDocsDependencies(project: DBXToolsJavaScriptProject): void {
|
|
143
103
|
const workflow = releaseWorkflows.get(project);
|
|
144
|
-
if (workflow)
|
|
104
|
+
if (workflow) {
|
|
105
|
+
refreshDocsRegistryDependencies(workflow);
|
|
106
|
+
}
|
|
145
107
|
}
|
|
146
108
|
|
|
147
109
|
function verifyContextJob(
|
|
@@ -161,17 +123,14 @@ function verifyContextJob(
|
|
|
161
123
|
release_version: { stepId: "release", outputName: "release_version" },
|
|
162
124
|
},
|
|
163
125
|
steps: [
|
|
164
|
-
{
|
|
126
|
+
github.WorkflowSteps.checkout({
|
|
165
127
|
name: "Checkout release source",
|
|
166
|
-
uses: "actions/checkout@v6",
|
|
167
128
|
with: {
|
|
168
129
|
ref: "${{ github.ref_name }}",
|
|
169
|
-
|
|
130
|
+
fetchDepth: 0,
|
|
170
131
|
},
|
|
171
|
-
},
|
|
172
|
-
...
|
|
173
|
-
{ name: "Install release validation dependencies", run: "bun install --frozen-lockfile" },
|
|
174
|
-
bunCacheSaveStep(),
|
|
132
|
+
}),
|
|
133
|
+
...project.renderWorkflowSetup({ mutable: false }),
|
|
175
134
|
{
|
|
176
135
|
name: "Verify release context",
|
|
177
136
|
id: "release",
|
|
@@ -210,7 +169,7 @@ function verifyContextJob(
|
|
|
210
169
|
|
|
211
170
|
function nodePublishJob(project: DBXToolsJavaScriptProject): Job {
|
|
212
171
|
return {
|
|
213
|
-
if:
|
|
172
|
+
if: releaseCondition(),
|
|
214
173
|
needs: ["verify-context"],
|
|
215
174
|
runsOn: ["ubuntu-latest"],
|
|
216
175
|
permissions: { contents: JobPermission.READ, idToken: JobPermission.WRITE },
|
|
@@ -220,7 +179,11 @@ function nodePublishJob(project: DBXToolsJavaScriptProject): Job {
|
|
|
220
179
|
...nodeReleaseSetupSteps(project),
|
|
221
180
|
{
|
|
222
181
|
name: "Publish npm workspace",
|
|
223
|
-
env: {
|
|
182
|
+
env: {
|
|
183
|
+
RELEASE_VERSION,
|
|
184
|
+
NODE_AUTH_TOKEN: "${{ secrets.NPM_TOKEN }}",
|
|
185
|
+
NPM_CONFIG_PROVENANCE: "true",
|
|
186
|
+
},
|
|
224
187
|
run: 'bun node_modules/@dbx-tools/projen/tasks/publish.ts "$RELEASE_VERSION" $DRY_RUN',
|
|
225
188
|
},
|
|
226
189
|
],
|
|
@@ -233,7 +196,7 @@ function addDocsJobs(
|
|
|
233
196
|
options: ReleaseDocsOptions,
|
|
234
197
|
): void {
|
|
235
198
|
workflow.addJob("build-docs", {
|
|
236
|
-
if:
|
|
199
|
+
if: releaseCondition(),
|
|
237
200
|
needs: ["verify-context"],
|
|
238
201
|
runsOn: ["ubuntu-latest"],
|
|
239
202
|
permissions: {
|
|
@@ -249,9 +212,8 @@ function addDocsJobs(
|
|
|
249
212
|
},
|
|
250
213
|
steps: [
|
|
251
214
|
...releaseSourceSteps(),
|
|
252
|
-
...
|
|
215
|
+
...project.renderWorkflowSetup({ mutable: false }),
|
|
253
216
|
...options.prepareSteps,
|
|
254
|
-
bunCacheSaveStep(),
|
|
255
217
|
...options.buildSteps,
|
|
256
218
|
{
|
|
257
219
|
name: "Upload Pages artifact",
|
|
@@ -261,7 +223,7 @@ function addDocsJobs(
|
|
|
261
223
|
],
|
|
262
224
|
});
|
|
263
225
|
workflow.addJob("deploy-docs", {
|
|
264
|
-
if:
|
|
226
|
+
if: releaseCondition(),
|
|
265
227
|
needs: ["build-docs"],
|
|
266
228
|
environment: {
|
|
267
229
|
name: "github-pages",
|
|
@@ -288,31 +250,30 @@ export class DBXToolsRelease extends Component {
|
|
|
288
250
|
const tagPrefix = options.tagPrefix ?? "v";
|
|
289
251
|
const releaseBranch = projectReleaseBranch(project);
|
|
290
252
|
releaseTagPrefixes.set(project, tagPrefix);
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
exec: taskScript(project, "version-check.ts"),
|
|
300
|
-
description: "Verify every package and generated barrel matches VERSION",
|
|
301
|
-
},
|
|
302
|
-
...(project.github
|
|
303
|
-
? {
|
|
304
|
-
release: {
|
|
305
|
-
exec: taskScript(
|
|
306
|
-
project,
|
|
307
|
-
"release.ts",
|
|
308
|
-
`--prefix ${tagPrefix} --branch ${releaseBranch}`,
|
|
309
|
-
),
|
|
310
|
-
receiveArgs: true,
|
|
311
|
-
description: "Run bump, commit it, and push an annotated release tag",
|
|
312
|
-
},
|
|
313
|
-
}
|
|
314
|
-
: {}),
|
|
253
|
+
project.addTask("bump", {
|
|
254
|
+
execArgs: taskCommand("bump.ts"),
|
|
255
|
+
receiveArgs: true,
|
|
256
|
+
description: "Increment VERSION and synchronize generated workspace versions",
|
|
257
|
+
});
|
|
258
|
+
project.addTask("version:check", {
|
|
259
|
+
execArgs: taskCommand("version-check.ts"),
|
|
260
|
+
description: "Verify every package and generated barrel matches VERSION",
|
|
315
261
|
});
|
|
262
|
+
if (project.github) {
|
|
263
|
+
project.addTask("release", {
|
|
264
|
+
execArgs: taskCommand(
|
|
265
|
+
"release.ts",
|
|
266
|
+
"--prefix",
|
|
267
|
+
tagPrefix,
|
|
268
|
+
"--branch",
|
|
269
|
+
releaseBranch,
|
|
270
|
+
...(options.pythonRoot ? ["--python-root", options.pythonRoot] : []),
|
|
271
|
+
...(options.validationTasks ?? []).flatMap((task) => ["--validate", task]),
|
|
272
|
+
),
|
|
273
|
+
receiveArgs: true,
|
|
274
|
+
description: "Run bump, commit it, and push an annotated release tag",
|
|
275
|
+
});
|
|
276
|
+
}
|
|
316
277
|
if (!project.github) return;
|
|
317
278
|
|
|
318
279
|
const workflow = new GithubWorkflow(project.github, "release", {
|
|
@@ -336,5 +297,6 @@ export class DBXToolsRelease extends Component {
|
|
|
336
297
|
if (options.docs) {
|
|
337
298
|
addDocsJobs(workflow, project, options.docs);
|
|
338
299
|
}
|
|
300
|
+
refreshReleaseDocsDependencies(project);
|
|
339
301
|
}
|
|
340
302
|
}
|
package/src/tags.ts
CHANGED
|
@@ -14,18 +14,18 @@
|
|
|
14
14
|
* callers add their own afterward.
|
|
15
15
|
*/
|
|
16
16
|
import type { IMixin as ConstructsMixin } from "constructs";
|
|
17
|
-
import { javascript } from "projen";
|
|
17
|
+
import { DependencyType, javascript } from "projen";
|
|
18
18
|
import { BunBuildFile, BunDevServerFile, BunfigFile } from "./bun-app.ts";
|
|
19
|
+
import { BUN_VERSION } from "./bun-workflow.ts";
|
|
19
20
|
import { create } from "./mixin.ts";
|
|
20
|
-
import * as projectPredicate from "./project-predicate.ts";
|
|
21
21
|
import {
|
|
22
22
|
addPackageFiles,
|
|
23
23
|
applyCompilerOptions,
|
|
24
24
|
applyExports,
|
|
25
25
|
applyIncludes,
|
|
26
|
-
applyTasks,
|
|
27
26
|
srcModuleExports,
|
|
28
|
-
} from "./project.ts";
|
|
27
|
+
} from "./project-js.ts";
|
|
28
|
+
import * as projectPredicate from "./project-predicate.ts";
|
|
29
29
|
|
|
30
30
|
/** Node compiler options: ES2022 lib + node types, deliberately no DOM. */
|
|
31
31
|
const NODE_COMPILER_OPTIONS: javascript.TypeScriptCompilerOptions = {
|
|
@@ -37,6 +37,10 @@ const NODE_COMPILER_OPTIONS: javascript.TypeScriptCompilerOptions = {
|
|
|
37
37
|
/** The DOM-capable lib list shared by the browser tags (`ui`, `openapi`). */
|
|
38
38
|
const DOM_LIB = ["ES2022", "DOM", "DOM.Iterable"];
|
|
39
39
|
|
|
40
|
+
function removeNodeTypes(project: javascript.NodeProject): void {
|
|
41
|
+
project.deps.removeDependency("@types/node", DependencyType.BUILD);
|
|
42
|
+
}
|
|
43
|
+
|
|
40
44
|
/**
|
|
41
45
|
* The agnostic floor every package gets at construction: ES2022 stdlib plus the
|
|
42
46
|
* web-platform globals available in every JS runtime (browser, workers, Node 18+)
|
|
@@ -64,6 +68,7 @@ export const PACKAGE_TAG_MIXINS = {
|
|
|
64
68
|
// compile (typecheck). No app build / index.html: a full browser app is an
|
|
65
69
|
// `app`-tagged package (see below) that layers Bun's build tooling on top.
|
|
66
70
|
ui: create(projectPredicate.hasTag("ui"), (p) => {
|
|
71
|
+
removeNodeTypes(p);
|
|
67
72
|
p.addPeerDeps("react@catalog:", "react-dom@catalog:");
|
|
68
73
|
p.addDevDeps(
|
|
69
74
|
"react@catalog:",
|
|
@@ -79,13 +84,10 @@ export const PACKAGE_TAG_MIXINS = {
|
|
|
79
84
|
target: "ES2022",
|
|
80
85
|
lib: [...DOM_LIB],
|
|
81
86
|
});
|
|
82
|
-
//
|
|
83
|
-
//
|
|
84
|
-
// ships more (e.g. ui-appkit's `./vite` preset) overrides this in its own
|
|
85
|
-
// mixin; an `app`-tagged package replaces it with a `.` root (see below).
|
|
87
|
+
// UI libraries are subpath-only. Their React entrypoint, optional stylesheet,
|
|
88
|
+
// and any other public source modules are discovered from the source tree.
|
|
86
89
|
applyExports(p, {
|
|
87
|
-
|
|
88
|
-
"./styles.css": "./src/styles.css",
|
|
90
|
+
...srcModuleExports(p),
|
|
89
91
|
"./package.json": "./package.json",
|
|
90
92
|
});
|
|
91
93
|
}),
|
|
@@ -95,8 +97,10 @@ export const PACKAGE_TAG_MIXINS = {
|
|
|
95
97
|
// `Bun.build`). Tailwind v4 is compiled by `bun-plugin-tailwind` (wired in the
|
|
96
98
|
// generated `bunfig.toml`). No Vite.
|
|
97
99
|
app: create(projectPredicate.hasTag("app"), (p) => {
|
|
100
|
+
removeNodeTypes(p);
|
|
98
101
|
p.addDeps("react@catalog:", "react-dom@catalog:");
|
|
99
102
|
p.addDevDeps(
|
|
103
|
+
`@types/bun@${BUN_VERSION}`,
|
|
100
104
|
"@types/react@catalog:",
|
|
101
105
|
"@types/react-dom@catalog:",
|
|
102
106
|
// The Tailwind plugin the dev server + build load. Tailwind itself is a
|
|
@@ -121,10 +125,8 @@ export const PACKAGE_TAG_MIXINS = {
|
|
|
121
125
|
// and `preview` serves the already-built bundle. `Bun.serve` builds on request,
|
|
122
126
|
// so `preview` could only be spelled the same as `dev` - two names for one
|
|
123
127
|
// command, and a reader would reasonably assume the second one served `dist/`.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
build: { exec: "bun build.ts" },
|
|
127
|
-
});
|
|
128
|
+
(p.tasks.tryFind("dev") ?? p.addTask("dev")).reset("bun dev.ts");
|
|
129
|
+
p.compileTask.reset("bun build.ts");
|
|
128
130
|
new BunfigFile(p);
|
|
129
131
|
new BunDevServerFile(p);
|
|
130
132
|
new BunBuildFile(p);
|
|
@@ -172,19 +174,19 @@ export const PACKAGE_TAG_MIXINS = {
|
|
|
172
174
|
});
|
|
173
175
|
// bun runs the server `.ts` directly (native TS, no tsx). `--watch` restarts
|
|
174
176
|
// on change - the tsx-watch replacement.
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
start: { exec: "bun src/server.ts" },
|
|
178
|
-
});
|
|
177
|
+
(p.tasks.tryFind("dev") ?? p.addTask("dev")).reset("bun --watch src/server.ts");
|
|
178
|
+
(p.tasks.tryFind("start") ?? p.addTask("start")).reset("bun src/server.ts");
|
|
179
179
|
}),
|
|
180
180
|
node: create(projectPredicate.hasTag("node"), (p) => {
|
|
181
181
|
p.addDevDeps("@types/node@catalog:");
|
|
182
182
|
applyCompilerOptions(p, NODE_COMPILER_OPTIONS);
|
|
183
183
|
}),
|
|
184
184
|
shared: create(projectPredicate.hasTag("shared"), (p) => {
|
|
185
|
+
removeNodeTypes(p);
|
|
185
186
|
applyCompilerOptions(p, AGNOSTIC_COMPILER_OPTIONS);
|
|
186
187
|
}),
|
|
187
188
|
openapi: create(projectPredicate.hasTag("openapi"), (p) => {
|
|
189
|
+
removeNodeTypes(p);
|
|
188
190
|
p.addDeps("openapi-fetch@catalog:");
|
|
189
191
|
applyCompilerOptions(p, { target: "ES2022", lib: [...DOM_LIB], types: [] });
|
|
190
192
|
addPackageFiles(p, "openapi.json");
|
package/src/tsconfig.ts
CHANGED
|
@@ -34,6 +34,12 @@ const BASE_COMPILER_OPTIONS: javascript.TypeScriptCompilerOptions = {
|
|
|
34
34
|
* Packages type-check against their own projen-generated tsconfigs via `compile`.
|
|
35
35
|
*/
|
|
36
36
|
export class DBXToolsRootTsconfig extends Component {
|
|
37
|
+
/** Shared compiler floor inherited by the root program. */
|
|
38
|
+
readonly base?: javascript.TypescriptConfig;
|
|
39
|
+
|
|
40
|
+
/** Root program config inherited by the generated Projen config. */
|
|
41
|
+
readonly config?: javascript.TypescriptConfig;
|
|
42
|
+
|
|
37
43
|
constructor(scope: Project) {
|
|
38
44
|
super(scope);
|
|
39
45
|
|
|
@@ -41,13 +47,12 @@ export class DBXToolsRootTsconfig extends Component {
|
|
|
41
47
|
return;
|
|
42
48
|
}
|
|
43
49
|
|
|
44
|
-
|
|
50
|
+
this.base = new javascript.TypescriptConfig(scope, {
|
|
45
51
|
fileName: "tsconfig.base.json",
|
|
46
52
|
compilerOptions: BASE_COMPILER_OPTIONS,
|
|
47
53
|
});
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
extends: javascript.TypescriptConfigExtends.fromTypescriptConfigs([base]),
|
|
54
|
+
this.config = new javascript.TypescriptConfig(scope, {
|
|
55
|
+
extends: javascript.TypescriptConfigExtends.fromTypescriptConfigs([this.base]),
|
|
51
56
|
compilerOptions: {
|
|
52
57
|
lib: ["ESNext"],
|
|
53
58
|
types: ["node"],
|
|
@@ -55,6 +60,5 @@ export class DBXToolsRootTsconfig extends Component {
|
|
|
55
60
|
include: [".projenrc.ts"],
|
|
56
61
|
exclude: ["node_modules", "**/dist", "**/node_modules"],
|
|
57
62
|
});
|
|
58
|
-
root.file.readonly = true;
|
|
59
63
|
}
|
|
60
64
|
}
|
package/src/vscode.ts
CHANGED
|
@@ -5,65 +5,54 @@
|
|
|
5
5
|
* is delivered by `.vscode/tasks.json` (`runOn: folderOpen`) - projen has no native
|
|
6
6
|
* tasks.json component, so a `JsonFile` is the idiomatic emitter.
|
|
7
7
|
*/
|
|
8
|
-
import {
|
|
8
|
+
import { JsonFile, javascript } from "projen";
|
|
9
9
|
|
|
10
|
-
/**
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
10
|
+
/** Configure the native Projen VS Code component and the unsupported tasks file. */
|
|
11
|
+
export function configureVsCode(scope: javascript.NodeProject): void {
|
|
12
|
+
const editor = scope.vscode;
|
|
13
|
+
if (!editor) return;
|
|
14
|
+
editor.settings.addSettings({
|
|
15
|
+
"typescript.tsdk": "node_modules/typescript/lib",
|
|
16
|
+
"typescript.preferences.importModuleSpecifier": "non-relative",
|
|
17
|
+
"javascript.preferences.importModuleSpecifier": "non-relative",
|
|
18
|
+
"editor.formatOnSave": true,
|
|
19
|
+
"editor.defaultFormatter": "esbenp.prettier-vscode",
|
|
20
|
+
"files.watcherExclude": {
|
|
21
|
+
"**/node_modules/**": true,
|
|
22
|
+
"**/dist/**": true,
|
|
23
|
+
},
|
|
24
|
+
});
|
|
25
|
+
editor.extensions.addRecommendations("esbenp.prettier-vscode");
|
|
20
26
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
"
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
obj: {
|
|
41
|
-
version: "2.0.0",
|
|
42
|
-
tasks: [
|
|
43
|
-
{
|
|
44
|
-
label: "sync",
|
|
45
|
-
detail:
|
|
46
|
-
"projen sync --watch - projenrc (.projenrc.ts + syncResynthPaths re-synth) + barrels + openapi watchers",
|
|
47
|
-
type: "shell",
|
|
48
|
-
command: "bun run sync -- --watch",
|
|
49
|
-
isBackground: true,
|
|
50
|
-
problemMatcher: [],
|
|
51
|
-
runOptions: { runOn: "folderOpen" },
|
|
52
|
-
presentation: {
|
|
53
|
-
reveal: "always",
|
|
54
|
-
panel: "dedicated",
|
|
55
|
-
group: "projen",
|
|
56
|
-
},
|
|
57
|
-
},
|
|
58
|
-
{
|
|
59
|
-
label: "synth",
|
|
60
|
-
detail: "projen - synthesize all generated config",
|
|
61
|
-
type: "shell",
|
|
62
|
-
command: "bun run default",
|
|
63
|
-
problemMatcher: [],
|
|
27
|
+
new JsonFile(scope, ".vscode/tasks.json", {
|
|
28
|
+
marker: false,
|
|
29
|
+
readonly: true,
|
|
30
|
+
obj: {
|
|
31
|
+
version: "2.0.0",
|
|
32
|
+
tasks: [
|
|
33
|
+
{
|
|
34
|
+
label: "sync",
|
|
35
|
+
detail:
|
|
36
|
+
"projen sync --watch - projenrc (.projenrc.ts + syncResynthPaths re-synth) + barrels + openapi watchers",
|
|
37
|
+
type: "shell",
|
|
38
|
+
command: "bun run sync -- --watch",
|
|
39
|
+
isBackground: true,
|
|
40
|
+
problemMatcher: [],
|
|
41
|
+
runOptions: { runOn: "folderOpen" },
|
|
42
|
+
presentation: {
|
|
43
|
+
reveal: "always",
|
|
44
|
+
panel: "dedicated",
|
|
45
|
+
group: "projen",
|
|
64
46
|
},
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
47
|
+
},
|
|
48
|
+
{
|
|
49
|
+
label: "synth",
|
|
50
|
+
detail: "projen - synthesize all generated config",
|
|
51
|
+
type: "shell",
|
|
52
|
+
command: "bun run default",
|
|
53
|
+
problemMatcher: [],
|
|
54
|
+
},
|
|
55
|
+
],
|
|
56
|
+
},
|
|
57
|
+
});
|
|
69
58
|
}
|
package/src/watch.ts
CHANGED
|
@@ -90,19 +90,13 @@ export interface WatchLoopOptions {
|
|
|
90
90
|
check?: (changed: string[]) => boolean | Promise<boolean>;
|
|
91
91
|
}
|
|
92
92
|
|
|
93
|
-
function resolveWatchLoopOptions(config?: IgnoreGroupOptions | WatchLoopOptions): WatchLoopOptions {
|
|
94
|
-
if (!config) return {};
|
|
95
|
-
if ("check" in config || "ignoreOptions" in config) return config as WatchLoopOptions;
|
|
96
|
-
return { ignoreOptions: config as IgnoreGroupOptions };
|
|
97
|
-
}
|
|
98
|
-
|
|
99
93
|
export function watchLoop(
|
|
100
94
|
tag: string,
|
|
101
95
|
paths: string[],
|
|
102
96
|
onBatch: (changed: string[]) => void | Promise<void>,
|
|
103
|
-
config
|
|
97
|
+
config: WatchLoopOptions = {},
|
|
104
98
|
): void {
|
|
105
|
-
const { ignoreOptions, check } =
|
|
99
|
+
const { ignoreOptions, check } = config;
|
|
106
100
|
const pending = new Set<string>();
|
|
107
101
|
let timer: ReturnType<typeof setTimeout> | undefined;
|
|
108
102
|
let running = false;
|
package/src/workspace-version.ts
CHANGED
|
@@ -110,17 +110,12 @@ export function syncWorkspaceManifestVersion(manifestPath: string, version: stri
|
|
|
110
110
|
return true;
|
|
111
111
|
}
|
|
112
112
|
|
|
113
|
-
/** The checked-in version a release increment starts from. */
|
|
114
|
-
export function resolveBaseVersion(root: string): string {
|
|
115
|
-
return readWorkspaceVersion(root);
|
|
116
|
-
}
|
|
117
|
-
|
|
118
113
|
/** Resolve the next release version without mutating the workspace. */
|
|
119
114
|
export function resolveNextVersion(
|
|
120
115
|
root: string,
|
|
121
116
|
level: VersionLevel,
|
|
122
117
|
): { base: string; version: string } {
|
|
123
|
-
const base =
|
|
118
|
+
const base = readWorkspaceVersion(root);
|
|
124
119
|
const parsed = parseSemver(base) ?? [0, 0, 1];
|
|
125
120
|
return {
|
|
126
121
|
base: parsed.join("."),
|