@abcnews/aunty 17.0.0-next.3 → 17.0.0-next.5
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/.prettierrc +1 -0
- package/.vscode/settings.json +5 -0
- package/CONTRIBUTING.md +39 -0
- package/README.md +23 -0
- package/TEMPLATES.md +112 -0
- package/assets/done.mp3 +0 -0
- package/eslint.config.mjs +12 -0
- package/package.json +25 -13
- package/scripts/postinstall.ts +7 -0
- package/src/bin/aunty.js +72 -0
- package/src/bin/commander.ts +174 -0
- package/src/commands/build/index.ts +23 -0
- package/src/commands/create/index.ts +148 -0
- package/src/commands/create/types.ts +7 -0
- package/src/commands/deploy/fs.ts +32 -0
- package/src/commands/deploy/index.ts +155 -0
- package/src/commands/migrate/index.ts +320 -0
- package/src/commands/release/index.ts +127 -0
- package/src/commands/release-check/git.ts +63 -0
- package/src/commands/release-check/index.ts +165 -0
- package/src/commands/serve/index.ts +44 -0
- package/src/lib/colours.json +12 -0
- package/src/lib/constants.ts +4 -0
- package/src/lib/ftp.ts +167 -0
- package/src/lib/git.ts +93 -0
- package/src/lib/initHelpers.ts +208 -0
- package/src/lib/semver.ts +50 -0
- package/src/lib/terminal.ts +130 -0
- package/src/lib/util.ts +100 -0
- package/src/lib/vite.ts +179 -0
- package/src/types.ts +16 -0
- package/templates/index.ts +11 -0
- package/templates/svelte/base/README.md +26 -0
- package/templates/svelte/base/contents/.editorconfig +12 -0
- package/templates/svelte/base/contents/.prettierrc +7 -0
- package/templates/svelte/base/contents/.vscode/extensions.json +3 -0
- package/templates/svelte/base/contents/LICENSE +21 -0
- package/templates/svelte/base/contents/README.md +16 -0
- package/templates/svelte/base/contents/_gitignore +24 -0
- package/templates/svelte/base/contents/index.html +22 -0
- package/templates/svelte/base/contents/package-lock.json +1373 -0
- package/templates/svelte/base/contents/package.json +29 -0
- package/templates/svelte/base/contents/src/App.svelte +21 -0
- package/templates/svelte/base/contents/src/assets/favicon.svg +4 -0
- package/templates/svelte/base/contents/src/components/Worm/Worm.svelte +59 -0
- package/templates/svelte/base/contents/src/components/Worm/worm.svg +4 -0
- package/templates/svelte/base/contents/src/iframe.ts +15 -0
- package/templates/svelte/base/contents/src/index.ts +26 -0
- package/templates/svelte/base/contents/svelte.config.js +2 -0
- package/templates/svelte/base/contents/tsconfig.app.json +22 -0
- package/templates/svelte/base/contents/tsconfig.json +7 -0
- package/templates/svelte/base/contents/tsconfig.node.json +28 -0
- package/templates/svelte/base/contents/vite-env.d.ts +7 -0
- package/templates/svelte/base/contents/vite.config.ts +40 -0
- package/templates/svelte/base/init.ts +39 -0
- package/templates/svelte/index.ts +52 -0
- package/templates/svelte/patch-builder/contents/builder/index.html +39 -0
- package/templates/svelte/patch-builder/contents/src/components/Builder/Builder.svelte +15 -0
- package/templates/svelte/patch-builder/init.ts +43 -0
- package/templates/svelte/patch-js/README.md +16 -0
- package/templates/svelte/patch-js/init.ts +61 -0
- package/templates/svelte/patch-odyssey/init.ts +10 -0
- package/templates/svelte/patch-scrollyteller/README.md +6 -0
- package/templates/svelte/patch-scrollyteller/contents/index.html +35 -0
- package/templates/svelte/patch-scrollyteller/contents/src/App.svelte +37 -0
- package/templates/svelte/patch-scrollyteller/contents/src/index.ts +36 -0
- package/templates/svelte/patch-scrollyteller/contents/src/types.ts +2 -0
- package/templates/svelte/patch-scrollyteller/init.ts +20 -0
- package/templates/vanilla/base/contents/LICENSE +21 -0
- package/templates/vanilla/base/contents/_gitignore +24 -0
- package/templates/vanilla/base/contents/index.html +22 -0
- package/templates/vanilla/base/contents/package-lock.json +999 -0
- package/templates/vanilla/base/contents/package.json +25 -0
- package/templates/vanilla/base/contents/public/favicon.svg +1 -0
- package/templates/vanilla/base/contents/public/icons.svg +24 -0
- package/templates/vanilla/base/contents/src/assets/hero.png +0 -0
- package/templates/vanilla/base/contents/src/assets/javascript.svg +1 -0
- package/templates/vanilla/base/contents/src/assets/vite.svg +1 -0
- package/templates/vanilla/base/contents/src/iframe.ts +17 -0
- package/templates/vanilla/base/contents/src/index.ts +17 -0
- package/templates/vanilla/base/contents/src/style.css +8 -0
- package/templates/vanilla/base/contents/tsconfig.app.json +23 -0
- package/templates/vanilla/base/contents/tsconfig.json +7 -0
- package/templates/vanilla/base/contents/tsconfig.node.json +28 -0
- package/templates/vanilla/base/contents/vite-env.d.ts +7 -0
- package/templates/vanilla/base/contents/vite.config.js +38 -0
- package/templates/vanilla/base/init.ts +33 -0
- package/templates/vanilla/index.ts +34 -0
- package/templates/vanilla/patch-js/README.md +0 -0
- package/templates/vanilla/patch-js/init.ts +27 -0
- package/test/helpers.ts +198 -0
- package/test/semver.test.ts +45 -0
- package/test/templates-e2e.test.ts +268 -0
- package/tsconfig.json +18 -0
- package/src/bin/aunty.ts +0 -60
package/.prettierrc
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{}
|
package/CONTRIBUTING.md
ADDED
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
## Contributing
|
|
2
|
+
|
|
3
|
+
To contribute to the development of **aunty**, clone the project:
|
|
4
|
+
|
|
5
|
+
```bash
|
|
6
|
+
git clone git@github.com:abcnews/aunty.git
|
|
7
|
+
```
|
|
8
|
+
|
|
9
|
+
...then, from the project directory, run:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
npm link
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
This will link the globally-available `aunty` command to your clone.
|
|
16
|
+
|
|
17
|
+
To revert to your original global install, run:
|
|
18
|
+
|
|
19
|
+
```bash
|
|
20
|
+
npm unlink
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
For ease of use, you can use the Aunty version directly with `node <path to aunty repo> -h`.
|
|
24
|
+
|
|
25
|
+
## Releasing new versions of `@abcnews/aunty`
|
|
26
|
+
|
|
27
|
+
Releases are managed by `np`. To release a new version of aunty from the default branch, run:
|
|
28
|
+
|
|
29
|
+
```bash
|
|
30
|
+
npm run release
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
This will run tests, prompt you to select the version increment, and then publish to npm, commit, tag, and push to GitHub.
|
|
34
|
+
|
|
35
|
+
For more information, see the [`np` documentation](https://github.com/sindresorhus/np).
|
|
36
|
+
|
|
37
|
+
## Style
|
|
38
|
+
|
|
39
|
+
This project's codebase should be managed with [eslint](https://github.com/eslint/eslint) and [prettier](https://github.com/prettier/prettier). You should configure your editor to take advantage of this to maintain the code style specifed in `.eslintrc` and `.prettierrc`. If your editor has a format-on-save option and a Prettier plugin, even better!
|
package/README.md
CHANGED
|
@@ -3,3 +3,26 @@
|
|
|
3
3
|
A toolkit for working with ABC News projects
|
|
4
4
|
|
|
5
5
|
THIS IS A NEW BRANCH FOR AUNTY@NEXT PLEASE BITE OFF A CHUNK OF WORK AND MERGE INTO the `aunty-next` BRANCH
|
|
6
|
+
|
|
7
|
+
# Contributing
|
|
8
|
+
|
|
9
|
+
The repo is split up by commands. You should be able to jump into the command you're interested in, and follow the logic from start to finish.
|
|
10
|
+
|
|
11
|
+
### Command Entry Points
|
|
12
|
+
|
|
13
|
+
- [build](./src/commands/build/index.ts)
|
|
14
|
+
- [create](./src/commands/create/index.ts) (aliased as `new`)
|
|
15
|
+
- [deploy](./src/commands/deploy/index.ts)
|
|
16
|
+
- [release](./src/commands/release/index.ts)
|
|
17
|
+
- [release-check](./src/commands/release-check/index.ts)
|
|
18
|
+
- [serve](./src/commands/serve/index.ts)
|
|
19
|
+
|
|
20
|
+
Aunty uses the pattern of "helpers" to abstract complex logic out and hopefully make our main entrypoints flat and readable.
|
|
21
|
+
|
|
22
|
+
The main CLI logic is in [src/bin/commander.ts](./src/bin/commander.ts).
|
|
23
|
+
|
|
24
|
+
See [CONTRIBUTING.md](./CONTRIBUTING.md) for specifics.
|
|
25
|
+
|
|
26
|
+
# Templates
|
|
27
|
+
|
|
28
|
+
`aunty create` uses a custom template system to create new projects. See [TEMPLATES.md](./TEMPLATES.md) for specifics.
|
package/TEMPLATES.md
ADDED
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
`aunty create` uses a custom template system to create new projects. Templates have three main components:
|
|
2
|
+
|
|
3
|
+
1. a programmatic index that uses clack prompts to ask for desired configuration
|
|
4
|
+
2. a base template containing the dir to copy from + a programmatic script to perform the copy and any other tweaks
|
|
5
|
+
3. a series of "patches" containing programmatic scripts to copy over additional files or make changes to the base template.
|
|
6
|
+
|
|
7
|
+
The intention is to make this followable in logic, so you don't need any prior knowledge to make a new template. Hopefully this is helpful.
|
|
8
|
+
|
|
9
|
+
## Guide to making a new template
|
|
10
|
+
|
|
11
|
+
The following steps will guide you through creating a new template from scratch.
|
|
12
|
+
|
|
13
|
+
### 1. Scaffold your starting point
|
|
14
|
+
|
|
15
|
+
It's usually easier to start with a working scaffold than writing a project framework from scratch.
|
|
16
|
+
|
|
17
|
+
1. Generate your base project in a temporary folder using standard initialization tools (e.g., `npm create vite@latest`).
|
|
18
|
+
2. Test the generated project to ensure it works as expected before converting it into a template.
|
|
19
|
+
|
|
20
|
+
### 2. Create the Base Template
|
|
21
|
+
|
|
22
|
+
Now you need to bring those scaffolded files into the Aunty project.
|
|
23
|
+
|
|
24
|
+
1. Create the directory structure for your template's base contents: `templates/<your-template>/base/contents`.
|
|
25
|
+
2. Copy your scaffolded project files into this `contents/` directory.
|
|
26
|
+
3. **Rename `.gitignore` to `_gitignore`**.
|
|
27
|
+
|
|
28
|
+
**Note:** NPM drops `.gitignore` files by default during package publishing. If you don't rename it, the file won't be included when Aunty is installed. Aunty's initialization helper will automatically rename it back to `.gitignore` when a user creates a new project.
|
|
29
|
+
|
|
30
|
+
### 3. Create the Base Init Script
|
|
31
|
+
|
|
32
|
+
Next, you need a script to copy those base files to the user's destination directory.
|
|
33
|
+
|
|
34
|
+
1. Create `templates/<your-template>/base/init.ts`.
|
|
35
|
+
2. Export an `init(options: InitOptions)` function.
|
|
36
|
+
3. Use the built-in helper functions (from [`src/lib/initHelpers.ts`](./src/lib/initHelpers.ts)) to copy the contents and install Aunty as a dependency.
|
|
37
|
+
|
|
38
|
+
```typescript
|
|
39
|
+
import path from "node:path";
|
|
40
|
+
import { copyContents, installAunty } from "../../../src/lib/initHelpers.ts";
|
|
41
|
+
import type { InitOptions } from "../../../src/commands/create/types.ts";
|
|
42
|
+
|
|
43
|
+
export async function init(options: InitOptions) {
|
|
44
|
+
// Copy the files from base/contents to the new project directory
|
|
45
|
+
await copyContents(path.join(import.meta.dirname, "contents"), options.dir);
|
|
46
|
+
|
|
47
|
+
// Ensure @abcnews/aunty is added to the devDependencies
|
|
48
|
+
await installAunty(options.dir);
|
|
49
|
+
}
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### 4. Create the Main Entry Point
|
|
53
|
+
|
|
54
|
+
The entry point handles the user flow, asking any required questions before calling the init script.
|
|
55
|
+
|
|
56
|
+
1. Create `templates/<your-template>/index.ts`.
|
|
57
|
+
2. Export a default `run(options: InitOptions)` function.
|
|
58
|
+
3. Use [`@clack/prompts`](https://github.com/natemoo-re/clack/tree/main/packages/prompts) to gather user preferences (e.g., confirm if they want TypeScript, or select a variant).
|
|
59
|
+
4. Invoke your base `init.ts` script.
|
|
60
|
+
|
|
61
|
+
```typescript
|
|
62
|
+
import { confirm, isCancel, cancel } from "@clack/prompts";
|
|
63
|
+
import type { InitOptions } from "../../src/commands/create/types.ts";
|
|
64
|
+
import { init as baseInit } from "./base/init.ts";
|
|
65
|
+
import { init as jsInit } from "./patch-js/init.ts";
|
|
66
|
+
|
|
67
|
+
export default async function run(options: InitOptions) {
|
|
68
|
+
const useTypescript = await confirm({
|
|
69
|
+
message: "Do you want to use TypeScript?",
|
|
70
|
+
initialValue: true,
|
|
71
|
+
});
|
|
72
|
+
|
|
73
|
+
if (isCancel(useTypescript)) {
|
|
74
|
+
cancel("Operation cancelled.");
|
|
75
|
+
return 1;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
// 1. Run the base setup first
|
|
79
|
+
await baseInit(options);
|
|
80
|
+
|
|
81
|
+
// 2. Apply patches conditionally based on user answers
|
|
82
|
+
if (!useTypescript) {
|
|
83
|
+
await jsInit(options);
|
|
84
|
+
}
|
|
85
|
+
|
|
86
|
+
return 0;
|
|
87
|
+
}
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 5. Create Patches (Optional)
|
|
91
|
+
|
|
92
|
+
If your template requires variants (e.g., an Odyssey version vs a standard version, or JS vs TS), you can create "patches".
|
|
93
|
+
|
|
94
|
+
1. Create a patch directory (e.g., `templates/<your-template>/patch-js/contents` and `templates/<your-template>/patch-js/init.ts`).
|
|
95
|
+
2. Patches are just smaller init scripts that layer extra files, string replacements, or `package.json` edits on top of the base template.
|
|
96
|
+
3. Invoke the patch's `init` function in your main `index.ts` conditionally, as demonstrated in the snippet in Step 4.
|
|
97
|
+
|
|
98
|
+
### 6. Test Locally
|
|
99
|
+
|
|
100
|
+
While developing your new template, you can test it locally by running the CLI from the root of the Aunty repository:
|
|
101
|
+
|
|
102
|
+
```bash
|
|
103
|
+
node . create
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
or, in another dir with
|
|
107
|
+
|
|
108
|
+
```bash
|
|
109
|
+
node ../aunty create
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
This will invoke your local version of Aunty, allowing you to test the prompt flow and verify the generated output in your chosen destination directory.
|
package/assets/done.mp3
ADDED
|
Binary file
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@abcnews/aunty",
|
|
3
|
-
"version": "17.0.0-next.
|
|
3
|
+
"version": "17.0.0-next.5",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "ABC News Digital developer toolkit",
|
|
6
6
|
"repository": {
|
|
@@ -15,37 +15,43 @@
|
|
|
15
15
|
"Ash Kyd <kyd.ashley@abc.net.au>"
|
|
16
16
|
],
|
|
17
17
|
"scripts": {
|
|
18
|
-
"build": "
|
|
18
|
+
"build": "esbuild src/bin/commander.ts --bundle --platform=node --format=esm --packages=external --outfile=dist/bin/commander.js",
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
19
20
|
"dev": "tsx src/bin/aunty.ts",
|
|
20
|
-
"test": "
|
|
21
|
+
"test": "node --experimental-test-module-mocks --import tsx --test test/*.test.ts",
|
|
21
22
|
"lint": "eslint src",
|
|
22
23
|
"clean": "rimraf dist",
|
|
23
|
-
"prebuild": "npm run clean"
|
|
24
|
+
"prebuild": "npm run clean",
|
|
25
|
+
"release": "np"
|
|
24
26
|
},
|
|
25
|
-
"files": [
|
|
26
|
-
"dist"
|
|
27
|
-
],
|
|
28
27
|
"publishConfig": {
|
|
29
28
|
"access": "public"
|
|
30
29
|
},
|
|
31
|
-
"main": "src/bin/aunty.
|
|
30
|
+
"main": "src/bin/aunty.js",
|
|
31
|
+
"exports": {
|
|
32
|
+
".": "./src/bin/aunty.js",
|
|
33
|
+
"./vite": "./src/lib/vite.ts"
|
|
34
|
+
},
|
|
32
35
|
"bin": {
|
|
33
|
-
"aunty": "src/bin/aunty.
|
|
34
|
-
"nt": "src/bin/aunty.
|
|
36
|
+
"aunty": "src/bin/aunty.js",
|
|
37
|
+
"nt": "src/bin/aunty.js"
|
|
35
38
|
},
|
|
36
39
|
"engines": {
|
|
37
|
-
"node": ">=
|
|
40
|
+
"node": ">=24"
|
|
38
41
|
},
|
|
39
42
|
"devDependencies": {
|
|
40
43
|
"@eslint/js": "^9.39.2",
|
|
41
44
|
"@types/async": "^3.2.25",
|
|
42
45
|
"@types/fs-extra": "^11.0.4",
|
|
46
|
+
"@types/lodash-es": "^4.17.12",
|
|
43
47
|
"@types/node": "^25.0.10",
|
|
48
|
+
"@types/semver": "^7.7.1",
|
|
49
|
+
"esbuild": "^0.28.1",
|
|
44
50
|
"eslint": "^9.39.2",
|
|
45
51
|
"install": "^0.13.0",
|
|
52
|
+
"np": "^12.0.0",
|
|
46
53
|
"npm": "^11.11.1",
|
|
47
54
|
"rimraf": "^6.1.2",
|
|
48
|
-
"tsx": "^4.21.0",
|
|
49
55
|
"typescript": "^5.9.3",
|
|
50
56
|
"typescript-eslint": "^8.54.0"
|
|
51
57
|
},
|
|
@@ -54,10 +60,16 @@
|
|
|
54
60
|
"async": "^3.2.6",
|
|
55
61
|
"basic-ftp": "^5.2.0",
|
|
56
62
|
"commander": "^14.0.3",
|
|
57
|
-
"
|
|
63
|
+
"lodash-es": "^4.17.23",
|
|
58
64
|
"picocolors": "^1.1.1",
|
|
65
|
+
"semver": "^7.8.5",
|
|
59
66
|
"slugify": "^1.6.8",
|
|
60
67
|
"tsx": "^4.21.0",
|
|
61
68
|
"zx": "^8.8.5"
|
|
69
|
+
},
|
|
70
|
+
"allowScripts": {
|
|
71
|
+
"esbuild@0.28.1": true,
|
|
72
|
+
"esbuild@0.27.7": true,
|
|
73
|
+
"fsevents@2.3.3": true
|
|
62
74
|
}
|
|
63
75
|
}
|
package/src/bin/aunty.js
ADDED
|
@@ -0,0 +1,72 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* @file Aunty CLI Entry Point
|
|
5
|
+
*
|
|
6
|
+
* This is the main file that launches Aunty. It handles:
|
|
7
|
+
* - Deferring to the locally installed version if available
|
|
8
|
+
* - Deciding whether to use the built JS in prod, or `tsx` in dev-like environments
|
|
9
|
+
*
|
|
10
|
+
* This file MUST be plain JavaScript to ensure compatibility as a CLI entry point.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { existsSync } from "node:fs";
|
|
14
|
+
import { realpath } from "node:fs/promises";
|
|
15
|
+
import path from "node:path";
|
|
16
|
+
import { fileURLToPath } from "node:url";
|
|
17
|
+
import { $ } from "zx";
|
|
18
|
+
|
|
19
|
+
const filename = fileURLToPath(import.meta.url);
|
|
20
|
+
const dirname = path.dirname(filename);
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Bootstrap the CLI by preferring a local version if it exists.
|
|
24
|
+
*/
|
|
25
|
+
async function run() {
|
|
26
|
+
const localAuntyPath = path.join(
|
|
27
|
+
process.cwd(),
|
|
28
|
+
"node_modules/@abcnews/aunty/src/bin/aunty.js",
|
|
29
|
+
);
|
|
30
|
+
|
|
31
|
+
// If a local version exists and we are not it, prefer the local version.
|
|
32
|
+
// Do not defer to local version for the 'migrate' command, as it is used to upgrade the project.
|
|
33
|
+
const isMigrate = process.argv.includes("migrate");
|
|
34
|
+
if (
|
|
35
|
+
!isMigrate &&
|
|
36
|
+
existsSync(localAuntyPath) &&
|
|
37
|
+
(await realpath(localAuntyPath)) !== (await realpath(filename))
|
|
38
|
+
) {
|
|
39
|
+
const result = await $({ stdio: "inherit", nothrow: true })`${process.execPath} ${localAuntyPath} ${process.argv.slice(2)}`;
|
|
40
|
+
process.exit(result.exitCode);
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// Resolve paths for the built JS and original TS commander files.
|
|
44
|
+
const builtCommanderPath = path.resolve(dirname, "../../dist/bin/commander.js");
|
|
45
|
+
const commanderPath = path.resolve(dirname, "commander.ts");
|
|
46
|
+
|
|
47
|
+
let execPath;
|
|
48
|
+
let execArgs;
|
|
49
|
+
|
|
50
|
+
/** If running from node_modules, we are almost certainly running in prod */
|
|
51
|
+
const isRunningFromNodeModules = filename.includes("node_modules");
|
|
52
|
+
|
|
53
|
+
if (isRunningFromNodeModules && existsSync(builtCommanderPath)) {
|
|
54
|
+
// If the built files are available and we are executing from node_modules, use those directly with node
|
|
55
|
+
execPath = process.execPath;
|
|
56
|
+
execArgs = [builtCommanderPath, ...process.argv.slice(2)];
|
|
57
|
+
} else {
|
|
58
|
+
// Otherwise run the package via tsx
|
|
59
|
+
// This is hit for local dev or when running straight from a Github branch
|
|
60
|
+
const localTsx = path.resolve(dirname, "../../node_modules/.bin/tsx");
|
|
61
|
+
execPath = existsSync(localTsx) ? localTsx : "tsx";
|
|
62
|
+
execArgs = [commanderPath, ...process.argv.slice(2)];
|
|
63
|
+
}
|
|
64
|
+
|
|
65
|
+
const result = await $({ stdio: "inherit", nothrow: true })`${execPath} ${execArgs}`;
|
|
66
|
+
process.exit(result.exitCode);
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
run().catch((err) => {
|
|
70
|
+
console.error(err);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
});
|
|
@@ -0,0 +1,174 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @file
|
|
3
|
+
* Core CLI logic using Commander.js.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import path from "node:path";
|
|
7
|
+
import { Command, Help } from "commander";
|
|
8
|
+
import { run as runDeploy } from "../commands/deploy/index.ts";
|
|
9
|
+
import { run as runReleaseCheck } from "../commands/release-check/index.ts";
|
|
10
|
+
import { run as runRelease } from "../commands/release/index.ts";
|
|
11
|
+
import { run as runCreate } from "../commands/create/index.ts";
|
|
12
|
+
import { run as runBuild } from "../commands/build/index.ts";
|
|
13
|
+
import { run as runServe } from "../commands/serve/index.ts";
|
|
14
|
+
import { run as runMigrate } from "../commands/migrate/index.ts";
|
|
15
|
+
import { getHeader, printDevColours } from "../lib/terminal.ts";
|
|
16
|
+
import { loadJson } from "../lib/util.ts";
|
|
17
|
+
import pc from "picocolors";
|
|
18
|
+
import rawColours from "../lib/colours.json" with { type: "json" };
|
|
19
|
+
|
|
20
|
+
interface Colours {
|
|
21
|
+
commands: Record<string, string>;
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
const colours = rawColours as unknown as Colours;
|
|
25
|
+
const pcColors = pc as unknown as Record<string, (str: string) => string>;
|
|
26
|
+
|
|
27
|
+
const pkgPath = path.join(import.meta.dirname, "../../package.json");
|
|
28
|
+
const pkg = (await loadJson(pkgPath)) as {
|
|
29
|
+
version: string;
|
|
30
|
+
name: string;
|
|
31
|
+
description: string;
|
|
32
|
+
};
|
|
33
|
+
const version = pkg?.version || "0.0.0";
|
|
34
|
+
|
|
35
|
+
const program = new Command();
|
|
36
|
+
|
|
37
|
+
program
|
|
38
|
+
.name("aunty")
|
|
39
|
+
.description(
|
|
40
|
+
getHeader(
|
|
41
|
+
`${pkg.name}${pc.dim("@" + pkg.version)}`,
|
|
42
|
+
`${pc.dim(pkg.description.slice(0, 73))}`,
|
|
43
|
+
{ prepend: "" },
|
|
44
|
+
) +
|
|
45
|
+
"\n" +
|
|
46
|
+
pc.dim("─".repeat(80)),
|
|
47
|
+
)
|
|
48
|
+
.version(version);
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* Configures the CLI help output to colorise subcommand terms (e.g. 'deploy', 'create')
|
|
52
|
+
* in their designated project palette colors defined in colours.json.
|
|
53
|
+
*/
|
|
54
|
+
program.configureHelp({
|
|
55
|
+
subcommandTerm: (cmd) => {
|
|
56
|
+
const name = cmd.name();
|
|
57
|
+
const colourName = colours.commands[name];
|
|
58
|
+
const colourFn =
|
|
59
|
+
colourName && typeof pcColors[colourName] === "function"
|
|
60
|
+
? pcColors[colourName]
|
|
61
|
+
: (str: string) => str;
|
|
62
|
+
const term = new Help().subcommandTerm(cmd);
|
|
63
|
+
return term.replace(name, colourFn(name));
|
|
64
|
+
},
|
|
65
|
+
formatHelp: (cmd, helper) => {
|
|
66
|
+
const baseHelp = new Help().formatHelp(cmd, helper);
|
|
67
|
+
if (cmd.parent) {
|
|
68
|
+
const name = cmd.name();
|
|
69
|
+
const colourName = colours.commands[name] || "rainbow";
|
|
70
|
+
const logoHeader = getHeader("aunty", name, {
|
|
71
|
+
prepend: "",
|
|
72
|
+
colour: colourName,
|
|
73
|
+
});
|
|
74
|
+
return `${logoHeader}\n\n${baseHelp}`;
|
|
75
|
+
}
|
|
76
|
+
return baseHelp;
|
|
77
|
+
},
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
program
|
|
81
|
+
.command("deploy")
|
|
82
|
+
.description(
|
|
83
|
+
"Deploy the project to FTP. This deploys the current dist/ folder to the specified remote folder, falling back to the current version number. Use this to retry a failed release.",
|
|
84
|
+
)
|
|
85
|
+
.argument(
|
|
86
|
+
"[destDir]",
|
|
87
|
+
"Override the target folder name (defaults to package.json version)",
|
|
88
|
+
)
|
|
89
|
+
.option("-d, --dry-run", "Show what would happen without uploading", false)
|
|
90
|
+
.option("-f, --force", "Overwrite the remote directory if it exists", false)
|
|
91
|
+
.action(async (destDir, options) => {
|
|
92
|
+
process.exit(await runDeploy({ destDir, ...options }));
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
program
|
|
96
|
+
.command("create")
|
|
97
|
+
.description("Create a new project from a template")
|
|
98
|
+
.argument("[destDir]", "Directory to create the project in")
|
|
99
|
+
.action(async (destDir) => {
|
|
100
|
+
process.exit(await runCreate(destDir));
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
program
|
|
104
|
+
.command("new", { hidden: true })
|
|
105
|
+
.description("Alias for create")
|
|
106
|
+
.argument("[destDir]", "Directory to create the project in")
|
|
107
|
+
.action(async (destDir) => {
|
|
108
|
+
process.exit(await runCreate(destDir));
|
|
109
|
+
});
|
|
110
|
+
|
|
111
|
+
program
|
|
112
|
+
.command("release-check")
|
|
113
|
+
.description("Perform pre-release checks")
|
|
114
|
+
.action(async () => {
|
|
115
|
+
process.exit(await runReleaseCheck());
|
|
116
|
+
});
|
|
117
|
+
|
|
118
|
+
program
|
|
119
|
+
.command("release")
|
|
120
|
+
.description("Version and release your project to FTP")
|
|
121
|
+
.option("--version <version>", "Override the release version directly")
|
|
122
|
+
.action(async (options) => {
|
|
123
|
+
process.exit(await runRelease(options));
|
|
124
|
+
});
|
|
125
|
+
|
|
126
|
+
program
|
|
127
|
+
.command("serve")
|
|
128
|
+
.description("Start a local development server")
|
|
129
|
+
.action(async () => {
|
|
130
|
+
await runServe();
|
|
131
|
+
});
|
|
132
|
+
|
|
133
|
+
program
|
|
134
|
+
.command("build")
|
|
135
|
+
.description("Build the project for production")
|
|
136
|
+
.action(async () => {
|
|
137
|
+
process.exit(await runBuild());
|
|
138
|
+
});
|
|
139
|
+
|
|
140
|
+
program
|
|
141
|
+
.command("migrate")
|
|
142
|
+
.description("Migrate a legacy project to use Vite and the latest version of aunty")
|
|
143
|
+
.option("-y, --yes", "Skip confirmation prompt", false)
|
|
144
|
+
.option("--skip-git", "Skip Git safety checks", false)
|
|
145
|
+
.action(async (options) => {
|
|
146
|
+
process.exit(await runMigrate(options));
|
|
147
|
+
});
|
|
148
|
+
|
|
149
|
+
program
|
|
150
|
+
.command("dev-colours", { hidden: true })
|
|
151
|
+
.description("Test all available gradient colours")
|
|
152
|
+
.action(() => {
|
|
153
|
+
printDevColours();
|
|
154
|
+
process.exit(0);
|
|
155
|
+
});
|
|
156
|
+
|
|
157
|
+
try {
|
|
158
|
+
// Start Commander
|
|
159
|
+
await program.parseAsync(process.argv);
|
|
160
|
+
} catch (err: unknown) {
|
|
161
|
+
// If Commander throws, print our unhandled exception message
|
|
162
|
+
if (err instanceof Error) {
|
|
163
|
+
console.error(`${pc.dim(err.stack)}`);
|
|
164
|
+
} else {
|
|
165
|
+
console.error(`${pc.red(pc.bold("Error:"))} ${pc.red(`‘${String(err)}’`)}`);
|
|
166
|
+
}
|
|
167
|
+
|
|
168
|
+
console.error(
|
|
169
|
+
`${pc.red(pc.bold("■ Aunty has encountered an unhandled error."))}
|
|
170
|
+
└ This is likely a bug. Please report it at: ${pc.cyan("https://github.com/abcnews/aunty/issues/new")}`,
|
|
171
|
+
);
|
|
172
|
+
|
|
173
|
+
process.exit(1);
|
|
174
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { intro, outro, log } from "@clack/prompts";
|
|
2
|
+
import pc from "picocolors";
|
|
3
|
+
import { getHeader } from "../../lib/terminal.ts";
|
|
4
|
+
import { runBuild } from "../../lib/util.ts";
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The main entry point for the 'aunty build' command.
|
|
8
|
+
*/
|
|
9
|
+
export async function run(): Promise<number> {
|
|
10
|
+
intro(getHeader(pc.dim("aunty"), "build", { colour: "blue" }));
|
|
11
|
+
outro("Building project for production...");
|
|
12
|
+
|
|
13
|
+
try {
|
|
14
|
+
await runBuild({ stdio: "inherit" });
|
|
15
|
+
return 0;
|
|
16
|
+
} catch (err: any) {
|
|
17
|
+
if (err.exitCode !== undefined) {
|
|
18
|
+
return err.exitCode;
|
|
19
|
+
}
|
|
20
|
+
log.error(err.message || `Failed to start npm command: ${err.message}`);
|
|
21
|
+
return 1;
|
|
22
|
+
}
|
|
23
|
+
}
|