typescript-bedrock 0.1.5 → 0.1.7
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.
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
- Run each task through `just`. `just` lists the recipes. Check each change with the narrowest one, such as `just rust::test` or `just lint`, and run `just verify` once before you finish a change that alters behavior.
|
|
2
2
|
- Fix the cause of each lint, type, or guard error in the code. Keep the shared configs as they are; the bedrock that wrote them owns them.
|
|
3
|
-
- Put project recipes in `project.just`. The `justfile` and `.just/` are shared and get replaced on the next adopt.
|
|
3
|
+
- Put project recipes in `project.just`. The `justfile` and `.just/` are shared and get replaced on the next adopt. A recipe there named `project-<task>`, such as `project-verify` or `project-test`, runs after the languages' `<task>`, so a project extends `just verify` there.
|
|
4
4
|
- Write commit messages as Conventional Commits; the commit-msg hook checks them.
|
|
5
5
|
- When a recipe reports a missing tool, run `just setup`, which installs the pinned ones. Install any it can't, such as `just`, Bun, rustup, or Xcode, with the system's package manager, then rerun the recipe. Tell the user what you installed, and keep the check instead of skipping it.
|
package/files/base/justfile
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
# Every bedrock repo shares this file. Each language adds `.just/<language>.just`,
|
|
2
2
|
# so `just <task>` runs the task for every language the repo has. Put project
|
|
3
|
-
# recipes in `project.just
|
|
3
|
+
# recipes in `project.just`; a recipe there named `project-<task>`, such as
|
|
4
|
+
# `project-verify`, runs after the languages' <task>.
|
|
4
5
|
|
|
5
6
|
set shell := ["bash", "-euo", "pipefail", "-c"]
|
|
6
7
|
|
|
@@ -58,6 +59,10 @@ each recipe:
|
|
|
58
59
|
{{ just_executable() }} "$language::{{ recipe }}"
|
|
59
60
|
fi
|
|
60
61
|
done
|
|
62
|
+
# project.just extends a task with a recipe named project-<task>.
|
|
63
|
+
case " $({{ just_executable() }} --summary) " in
|
|
64
|
+
*" project-{{ recipe }} "*) {{ just_executable() }} "project-{{ recipe }}" ;;
|
|
65
|
+
esac
|
|
61
66
|
|
|
62
67
|
[private]
|
|
63
68
|
lint-markdown *args:
|
package/package.json
CHANGED
package/src/adopt/manifest.ts
CHANGED
|
@@ -55,20 +55,22 @@ const migrateScripts = (
|
|
|
55
55
|
for (const [name, command] of Object.entries(tools)) {
|
|
56
56
|
if (kept[name] !== undefined && kept[name] !== command) {
|
|
57
57
|
notes.push(
|
|
58
|
-
`Replaced script "${name}" (${JSON.stringify(kept[name])}) with ${JSON.stringify(command)}. Move any step it still needs, such as a build, into
|
|
58
|
+
`Replaced script "${name}" (${JSON.stringify(kept[name])}) with ${JSON.stringify(command)}. Move any step it still needs, such as a build, into a \`project-${name}\` recipe in project.just, which \`just ${name}\` runs.`,
|
|
59
59
|
);
|
|
60
60
|
}
|
|
61
61
|
}
|
|
62
62
|
return { scripts: { ...kept, test: kept["test"] ?? test, ...tools }, notes };
|
|
63
63
|
};
|
|
64
64
|
|
|
65
|
+
const isRemoved = (name: string, template: Json): boolean =>
|
|
66
|
+
REMOVED_PACKAGES.test(name) && !(name in template);
|
|
67
|
+
|
|
65
68
|
/** Drops the packages Bun and the bedrock tools replace, except the ones the template ships. */
|
|
66
69
|
const removePackages = (
|
|
67
70
|
deps: unknown,
|
|
68
71
|
template: Json,
|
|
69
72
|
): { deps: Json; removed: string[] } => {
|
|
70
|
-
const removes = (name: string): boolean =>
|
|
71
|
-
REMOVED_PACKAGES.test(name) && !(name in template);
|
|
73
|
+
const removes = (name: string): boolean => isRemoved(name, template);
|
|
72
74
|
const entries = Object.entries(asRecord(deps));
|
|
73
75
|
return {
|
|
74
76
|
deps: Object.fromEntries(entries.filter(([name]) => !removes(name))),
|
|
@@ -130,13 +132,25 @@ const migrateOverrides = (manifest: Json, template: Json): Json => {
|
|
|
130
132
|
};
|
|
131
133
|
|
|
132
134
|
/** Bun runs no install scripts unless the package is trusted. */
|
|
133
|
-
const trustedDependencies = (
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
135
|
+
const trustedDependencies = (
|
|
136
|
+
manifest: Json,
|
|
137
|
+
template: Json,
|
|
138
|
+
pnpm?: Json,
|
|
139
|
+
): string[] => [
|
|
140
|
+
...new Set(
|
|
141
|
+
[
|
|
142
|
+
...asStrings(manifest["trustedDependencies"]),
|
|
143
|
+
...asStrings(asRecord(manifest["pnpm"])["onlyBuiltDependencies"]),
|
|
144
|
+
...asStrings(pnpm?.["onlyBuiltDependencies"]),
|
|
145
|
+
].filter((name) => !isRemoved(name, template)),
|
|
146
|
+
),
|
|
138
147
|
];
|
|
139
148
|
|
|
149
|
+
const removedKeyNotes = (next: Json): string[] =>
|
|
150
|
+
REMOVED_KEYS.filter((name) => name in next).map(
|
|
151
|
+
(key) => `Removed the "${key}" field from package.json.`,
|
|
152
|
+
);
|
|
153
|
+
|
|
140
154
|
export const migrateManifest = (
|
|
141
155
|
manifest: Json,
|
|
142
156
|
template: Json,
|
|
@@ -154,9 +168,11 @@ export const migrateManifest = (
|
|
|
154
168
|
asRecord(manifest["scripts"]),
|
|
155
169
|
asRecord(template["scripts"]),
|
|
156
170
|
);
|
|
157
|
-
const trusted = trustedDependencies(manifest, pnpm);
|
|
171
|
+
const trusted = trustedDependencies(manifest, shipped, pnpm);
|
|
158
172
|
const next: Json = {
|
|
159
|
-
...
|
|
173
|
+
...Object.fromEntries(
|
|
174
|
+
Object.entries(manifest).filter(([key]) => key !== "trustedDependencies"),
|
|
175
|
+
),
|
|
160
176
|
...(Object.keys(prod.deps).length > 0 ||
|
|
161
177
|
manifest["dependencies"] !== undefined
|
|
162
178
|
? { dependencies: prod.deps }
|
|
@@ -176,13 +192,10 @@ export const migrateManifest = (
|
|
|
176
192
|
...migrateOverrides(manifest, template),
|
|
177
193
|
...(trusted.length > 0 ? { trustedDependencies: trusted } : {}),
|
|
178
194
|
};
|
|
179
|
-
for (const key of REMOVED_KEYS.filter((name) => name in next)) {
|
|
180
|
-
notes.push(`Removed the "${key}" field from package.json.`);
|
|
181
|
-
}
|
|
182
195
|
return {
|
|
183
196
|
manifest: Object.fromEntries(
|
|
184
197
|
Object.entries(next).filter(([key]) => !REMOVED_KEYS.includes(key)),
|
|
185
198
|
),
|
|
186
|
-
notes: [...notes, ...scripts.notes],
|
|
199
|
+
notes: [...notes, ...removedKeyNotes(next), ...scripts.notes],
|
|
187
200
|
};
|
|
188
201
|
};
|
package/src/adopt/tests.ts
CHANGED
|
@@ -25,6 +25,29 @@ const GLOBALS = [
|
|
|
25
25
|
const usesGlobal = (text: string, name: string): boolean =>
|
|
26
26
|
new RegExp(`(?<![\\w$.])${name}\\s*[(.]`, "u").test(text);
|
|
27
27
|
|
|
28
|
+
const IMPORT_CLAUSES = /\bimport\s+(?:type\s+)?([^"';]*?)\s*from\s*["']/gu;
|
|
29
|
+
// Whether the file already binds `name`, by an import or a declaration.
|
|
30
|
+
const binds = (text: string, name: string): boolean => {
|
|
31
|
+
const declared = new RegExp(
|
|
32
|
+
`\\b(?:const|let|var|function|class)\\s+${name}\\b`,
|
|
33
|
+
"u",
|
|
34
|
+
);
|
|
35
|
+
const imported = [...text.matchAll(IMPORT_CLAUSES)].some(([, clause]) =>
|
|
36
|
+
(clause ?? "")
|
|
37
|
+
.replaceAll(/[{}]/gu, ",")
|
|
38
|
+
.split(",")
|
|
39
|
+
.some(
|
|
40
|
+
(part) =>
|
|
41
|
+
part
|
|
42
|
+
.trim()
|
|
43
|
+
.split(/\s+as\s+/u)
|
|
44
|
+
.at(-1)
|
|
45
|
+
?.trim() === name,
|
|
46
|
+
),
|
|
47
|
+
);
|
|
48
|
+
return imported || declared.test(text);
|
|
49
|
+
};
|
|
50
|
+
|
|
28
51
|
/**
|
|
29
52
|
* Points a Jest or Vitest test file at bun:test, which has the same API: its
|
|
30
53
|
* framework import changes module, and the globals it calls get imported, since
|
|
@@ -35,7 +58,9 @@ export const migrateTestFile = (text: string): string => {
|
|
|
35
58
|
if (/["']bun:test["']/u.test(imported)) {
|
|
36
59
|
return imported;
|
|
37
60
|
}
|
|
38
|
-
const used = GLOBALS.filter(
|
|
61
|
+
const used = GLOBALS.filter(
|
|
62
|
+
(name) => usesGlobal(text, name) && !binds(imported, name),
|
|
63
|
+
);
|
|
39
64
|
return used.length > 0
|
|
40
65
|
? `import { ${used.join(", ")} } from "bun:test";\n\n${text}`
|
|
41
66
|
: text;
|