Skip to content

Commit 9d8a1e8

Browse files
authored
Merge pull request #7 from bertdeblock/minor-improvements
Support a `--path` option
2 parents d971ecb + 08692b9 commit 9d8a1e8

File tree

9 files changed

+162
-69
lines changed

9 files changed

+162
-69
lines changed

README.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,16 @@ or
2929
bunx @bertdeblock/generate-template-registry@latest
3030
```
3131

32+
## Options
33+
34+
### `--path`
35+
36+
Generate a template registry at a custom path.
37+
38+
```shell
39+
npx @bertdeblock/generate-template-registry@latest --path="app/glint/template-registry.ts"
40+
```
41+
3242
## Caveats
3343

3444
- If your app or addon has components, helpers or modifiers with the same name, duplicate template registry entries will be generated, which will need to be fixed manually

bin/generate-template-registry.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
#!/usr/bin/env node
22

33
// eslint-disable-next-line n/no-missing-import
4-
import { generateTemplateRegistry } from "../dist/generate-template-registry.js";
4+
import { cli } from "../dist/cli.js";
55

6-
generateTemplateRegistry();
6+
cli();

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -32,13 +32,15 @@
3232
"change-case": "^5.4.3",
3333
"execa": "^8.0.1",
3434
"fast-glob": "^3.3.2",
35-
"fs-extra": "^11.2.0"
35+
"fs-extra": "^11.2.0",
36+
"yargs": "^17.7.2"
3637
},
3738
"devDependencies": {
3839
"@release-it-plugins/lerna-changelog": "^6.1.0",
3940
"@types/fs-extra": "^11.0.4",
4041
"@types/node": "^20.11.20",
4142
"@types/recursive-readdir": "^2.2.4",
43+
"@types/yargs": "^17.0.32",
4244
"@typescript-eslint/eslint-plugin": "^7.1.0",
4345
"@typescript-eslint/parser": "^7.1.0",
4446
"@vitest/coverage-v8": "^1.2.2",
@@ -50,6 +52,7 @@
5052
"release-it": "^17.0.3",
5153
"type-fest": "^4.10.3",
5254
"typescript": "^5.3.3",
55+
"uuid": "^9.0.1",
5356
"vitest": "^1.2.2"
5457
},
5558
"packageManager": "pnpm@8.6.12",

pnpm-lock.yaml

Lines changed: 24 additions & 16 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

src/cli.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
import { cwd } from "node:process";
2+
import { hideBin } from "yargs/helpers";
3+
import yargs from "yargs/yargs";
4+
import { generateTemplateRegistry } from "./generate-template-registry.js";
5+
6+
export async function cli() {
7+
const options = await yargs(hideBin(process.argv))
8+
.options({
9+
path: {
10+
describe: "Generate a template registry at a custom path",
11+
type: "string",
12+
},
13+
})
14+
.strict().argv;
15+
16+
await generateTemplateRegistry(cwd(), { path: options.path });
17+
}

src/generate-template-registry.ts

Lines changed: 38 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
import chalk from "chalk";
22
import { pascalCase } from "change-case";
33
import { execa } from "execa";
4-
import { readJson } from "fs-extra/esm";
4+
import { ensureDir, readJson } from "fs-extra/esm";
55
import { writeFile } from "node:fs/promises";
6-
import { join } from "node:path";
7-
import { cwd as processCwd } from "node:process";
6+
import { EOL } from "node:os";
7+
import { isAbsolute, join, parse } from "node:path";
88
import {
99
getEntries,
1010
isAddon,
@@ -21,7 +21,10 @@ import {
2121

2222
const TAB = " ";
2323

24-
export async function generateTemplateRegistry(cwd = processCwd()) {
24+
export async function generateTemplateRegistry(
25+
cwd: string,
26+
options: { path?: string } = {},
27+
) {
2528
let packageJson: EmberPackageJson;
2629

2730
try {
@@ -32,16 +35,17 @@ export async function generateTemplateRegistry(cwd = processCwd()) {
3235
);
3336
}
3437

35-
if (typeof packageJson.name === "undefined") {
36-
throw new Error(`The found "package.json" file is missing a "name" entry.`);
37-
}
38-
3938
if (isEmberPackage(packageJson) === false) {
4039
throw new Error("The current package is not an Ember app or addon.");
4140
}
4241

42+
if (typeof packageJson.name === "undefined") {
43+
throw new Error(`The found "package.json" file is missing a "name" entry.`);
44+
}
45+
46+
const isV2AddonPackage = isV2Addon(packageJson);
4347
const entriesDir = isAddon(packageJson)
44-
? isV2Addon(packageJson)
48+
? isV2AddonPackage
4549
? "src"
4650
: "addon"
4751
: "app";
@@ -60,9 +64,9 @@ export async function generateTemplateRegistry(cwd = processCwd()) {
6064
);
6165
}
6266

63-
const importRoot = isV2Addon(packageJson) ? "." : packageJson.name;
64-
65-
let templateRegistryContent = "";
67+
const importRoot = isV2AddonPackage ? "." : packageJson.name;
68+
const templateRegistryImportsContent: string[] = [];
69+
const templateRegistryEntriesContent: string[] = [];
6670

6771
for (const type in entries) {
6872
const typeEntries = entries[type as keyof EntriesResult];
@@ -71,47 +75,40 @@ export async function generateTemplateRegistry(cwd = processCwd()) {
7175
continue;
7276
}
7377

74-
const imports = typeEntries.map((entry) => {
78+
let importsContent = `// ${type}${EOL}`;
79+
let entriesContent = `${TAB}// ${type}${EOL}`;
80+
81+
for (const entry of typeEntries) {
7582
let entryName = entry.name;
7683

77-
if (isV2Addon(packageJson)) {
84+
if (isV2AddonPackage) {
7885
entryName += entry.extension;
7986
}
8087

81-
return `import type ${entry.identifier} from "${importRoot}/${type}/${entryName}";`;
82-
});
83-
84-
templateRegistryContent += `// ${type}\n${imports.join("\n")}\n\n`;
85-
}
86-
87-
templateRegistryContent += `export default interface ${pascalCase(packageJson.name)}Registry {\n`;
88-
89-
const entriesContent: string[] = [];
90-
91-
for (const type in entries) {
92-
const typeEntries = entries[type as keyof EntriesResult];
93-
94-
if (typeEntries.length === 0) {
95-
continue;
96-
}
97-
98-
let content = `${TAB}// ${type}\n`;
99-
100-
typeEntries.forEach((entry) => {
101-
content += `${TAB}${toRegistryKey(entry.name)}: typeof ${entry.identifier};\n`;
88+
importsContent += `import type ${entry.identifier} from "${importRoot}/${type}/${entryName}";${EOL}`;
89+
entriesContent += `${TAB}${toRegistryKey(entry.name)}: typeof ${entry.identifier};${EOL}`;
10290

10391
if (type === EntryType.Components) {
104-
content += `${TAB}${toRegistryKey(toAngleBracketNotation(entry.name))}: typeof ${entry.identifier};\n`;
92+
entriesContent += `${TAB}${toRegistryKey(toAngleBracketNotation(entry.name))}: typeof ${entry.identifier};${EOL}`;
10593
}
106-
});
94+
}
10795

108-
entriesContent.push(content);
96+
templateRegistryImportsContent.push(importsContent);
97+
templateRegistryEntriesContent.push(entriesContent);
10998
}
11099

111-
templateRegistryContent += `${entriesContent.join("\n")}}\n`;
100+
const templateRegistryPath = options.path
101+
? isAbsolute(options.path)
102+
? options.path
103+
: join(cwd, options.path)
104+
: join(cwd, entriesDir, "template-registry.ts");
112105

113-
const templateRegistryPath = join(cwd, entriesDir, "template-registry.ts");
106+
const templateRegistryContent = `${templateRegistryImportsContent.join(EOL)}
107+
export default interface ${pascalCase(packageJson.name)}Registry {
108+
${templateRegistryEntriesContent.join(EOL)}}
109+
`;
114110

111+
await ensureDir(parse(templateRegistryPath).dir);
115112
await writeFile(templateRegistryPath, templateRegistryContent);
116113

117114
try {
@@ -121,6 +118,6 @@ export async function generateTemplateRegistry(cwd = processCwd()) {
121118
}
122119

123120
console.log(
124-
chalk.green(`Template registry generated at ${templateRegistryPath}`),
121+
chalk.green(`Template registry generated at ${templateRegistryPath}.`),
125122
);
126123
}

0 commit comments

Comments
 (0)