spinup-ts 0.1.0
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 +82 -0
- package/dist/index.d.ts +3 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +96 -0
- package/dist/index.js.map +1 -0
- package/dist/prompts.d.ts +17 -0
- package/dist/prompts.d.ts.map +1 -0
- package/dist/prompts.js +264 -0
- package/dist/prompts.js.map +1 -0
- package/dist/scaffold.d.ts +5 -0
- package/dist/scaffold.d.ts.map +1 -0
- package/dist/scaffold.js +128 -0
- package/dist/scaffold.js.map +1 -0
- package/dist/transforms/devcontainer.d.ts +3 -0
- package/dist/transforms/devcontainer.d.ts.map +1 -0
- package/dist/transforms/devcontainer.js +8 -0
- package/dist/transforms/devcontainer.js.map +1 -0
- package/dist/transforms/docker.d.ts +3 -0
- package/dist/transforms/docker.d.ts.map +1 -0
- package/dist/transforms/docker.js +11 -0
- package/dist/transforms/docker.js.map +1 -0
- package/dist/transforms/docs.d.ts +3 -0
- package/dist/transforms/docs.d.ts.map +1 -0
- package/dist/transforms/docs.js +22 -0
- package/dist/transforms/docs.js.map +1 -0
- package/dist/transforms/documentation.d.ts +3 -0
- package/dist/transforms/documentation.d.ts.map +1 -0
- package/dist/transforms/documentation.js +37 -0
- package/dist/transforms/documentation.js.map +1 -0
- package/dist/transforms/github-actions.d.ts +3 -0
- package/dist/transforms/github-actions.d.ts.map +1 -0
- package/dist/transforms/github-actions.js +48 -0
- package/dist/transforms/github-actions.js.map +1 -0
- package/dist/transforms/index.d.ts +3 -0
- package/dist/transforms/index.d.ts.map +1 -0
- package/dist/transforms/index.js +24 -0
- package/dist/transforms/index.js.map +1 -0
- package/dist/transforms/license.d.ts +3 -0
- package/dist/transforms/license.d.ts.map +1 -0
- package/dist/transforms/license.js +19 -0
- package/dist/transforms/license.js.map +1 -0
- package/dist/transforms/npm-publish.d.ts +3 -0
- package/dist/transforms/npm-publish.d.ts.map +1 -0
- package/dist/transforms/npm-publish.js +15 -0
- package/dist/transforms/npm-publish.js.map +1 -0
- package/dist/transforms/package-manager.d.ts +3 -0
- package/dist/transforms/package-manager.d.ts.map +1 -0
- package/dist/transforms/package-manager.js +31 -0
- package/dist/transforms/package-manager.js.map +1 -0
- package/dist/types.d.ts +116 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +52 -0
- package/dist/types.js.map +1 -0
- package/dist/update.d.ts +2 -0
- package/dist/update.d.ts.map +1 -0
- package/dist/update.js +207 -0
- package/dist/update.js.map +1 -0
- package/package.json +94 -0
- package/template/.commitlintrc.json +3 -0
- package/template/.devcontainer/.zshrc +159 -0
- package/template/.devcontainer/DISCOVER-DEPS.md +109 -0
- package/template/.devcontainer/README.md +223 -0
- package/template/.devcontainer/SETUP.md +191 -0
- package/template/.devcontainer/TOOLS.md +215 -0
- package/template/.devcontainer/devcontainer.json +106 -0
- package/template/.devcontainer/scripts/init-project.sh +167 -0
- package/template/.editorconfig +12 -0
- package/template/.github/.release-please-manifest.json +3 -0
- package/template/.github/ISSUE_TEMPLATE/bug_report.md +21 -0
- package/template/.github/ISSUE_TEMPLATE/feature_request.md +14 -0
- package/template/.github/PULL_REQUEST_TEMPLATE.md +13 -0
- package/template/.github/actions/setup-node-env/action.yml +20 -0
- package/template/.github/dependabot.yml +17 -0
- package/template/.github/labeler.yml +17 -0
- package/template/.github/release-please-config.json +7 -0
- package/template/.github/workflows/ci.yml +95 -0
- package/template/.github/workflows/codeql.yml +31 -0
- package/template/.github/workflows/labeler.yml +18 -0
- package/template/.github/workflows/release-please.yml +72 -0
- package/template/.github/workflows/stale.yml +32 -0
- package/template/.husky/commit-msg +1 -0
- package/template/.husky/pre-commit +1 -0
- package/template/.nvmrc +1 -0
- package/template/.vscode/extensions.json +11 -0
- package/template/.vscode/settings.json +12 -0
- package/template/AGENTS.md +1 -0
- package/template/CHANGELOG.md +11 -0
- package/template/CLAUDE.md +0 -0
- package/template/CONTRIBUTING.md +22 -0
- package/template/Dockerfile +21 -0
- package/template/LICENSE.Apache-2.0 +17 -0
- package/template/LICENSE.BSD-3-Clause +28 -0
- package/template/LICENSE.GPL-3.0 +17 -0
- package/template/LICENSE.ISC +15 -0
- package/template/LICENSE.MIT +21 -0
- package/template/README.md +62 -0
- package/template/biome.json +49 -0
- package/template/docker-compose.yml +7 -0
- package/template/docs/architecture/api-layer.md +44 -0
- package/template/docs/architecture/constitution.md +24 -0
- package/template/docs/architecture/data-model.md +24 -0
- package/template/docs/architecture/index.md +15 -0
- package/template/docs/architecture/project.md +24 -0
- package/template/docs/architecture/quality-checks.md +28 -0
- package/template/docs/architecture/testing-plan.md +35 -0
- package/template/docs/architecture/ui.md +37 -0
- package/template/docs/changelog.md +9 -0
- package/template/docs/contributing.md +46 -0
- package/template/docs/developer-guide/architecture.md +22 -0
- package/template/docs/developer-guide/contributing.md +30 -0
- package/template/docs/developer-guide/data-model.md +25 -0
- package/template/docs/developer-guide/index.md +12 -0
- package/template/docs/developer-guide/testing.md +40 -0
- package/template/docs/examples.md +37 -0
- package/template/docs/getting-started.md +42 -0
- package/template/docs/installation.md +45 -0
- package/template/docs/intro.md +60 -0
- package/template/docs/post-mortems/.gitkeep +0 -0
- package/template/docs/reference/cli.md +32 -0
- package/template/docs/reference/configuration.md +33 -0
- package/template/docs/reference/hooks.md +27 -0
- package/template/docs/research/competitor-analysis.md +21 -0
- package/template/docs/research/real-world-demand.md +21 -0
- package/template/docs/user-guide/configuration.md +32 -0
- package/template/docs/user-guide/features.md +21 -0
- package/template/docs/user-guide/how-it-works.md +29 -0
- package/template/docs/user-guide/index.md +11 -0
- package/template/docusaurus.config.ts +93 -0
- package/template/eslint.config.mjs +66 -0
- package/template/justfile +51 -0
- package/template/package.json +88 -0
- package/template/pnpm-workspace.yaml +8 -0
- package/template/sidebars.ts +72 -0
- package/template/src/index.ts +3 -0
- package/template/static/img/logo.svg +4 -0
- package/template/tests/index.test.ts +8 -0
- package/template/tsconfig.json +23 -0
- package/template/vitest.config.ts +19 -0
package/README.md
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
# spinup-ts
|
|
2
|
+
|
|
3
|
+
Scaffold a production-ready TypeScript project with opinionated tooling — the TypeScript sibling of [spinup-py](https://github.com/joeblackwaslike/spinup-py) and the TypeScript equivalent of [cookiecutter-uv](https://github.com/joeblackwaslike/cookiecutter-uv).
|
|
4
|
+
|
|
5
|
+
`spinup-ts` ⇄ `spinup-py` share the same CLI schema, so remembering one gives you the other.
|
|
6
|
+
|
|
7
|
+
## Usage
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
# New project (interactive)
|
|
11
|
+
npx spinup-ts my-project
|
|
12
|
+
# or: pnpm dlx spinup-ts my-project
|
|
13
|
+
# or: bunx spinup-ts my-project
|
|
14
|
+
|
|
15
|
+
# New project (defaults only, no prompts)
|
|
16
|
+
npx spinup-ts my-project --non-interactive
|
|
17
|
+
|
|
18
|
+
# Retrofit an existing repo with template tooling
|
|
19
|
+
npx spinup-ts update .
|
|
20
|
+
```
|
|
21
|
+
|
|
22
|
+
Install globally if you scaffold often:
|
|
23
|
+
|
|
24
|
+
```bash
|
|
25
|
+
npm i -g spinup-ts
|
|
26
|
+
spinup-ts my-project
|
|
27
|
+
```
|
|
28
|
+
|
|
29
|
+
## CLI
|
|
30
|
+
|
|
31
|
+
```text
|
|
32
|
+
spinup-ts [new] <project-name> Scaffold a new TypeScript project
|
|
33
|
+
spinup-ts update [dir] Retrofit an existing repo with template tooling
|
|
34
|
+
spinup-ts --update [dir] Alias for `update`
|
|
35
|
+
|
|
36
|
+
-y, --yes, --non-interactive Scaffold with defaults only, no prompts (needs <project-name>)
|
|
37
|
+
-v, --version Print version
|
|
38
|
+
-h, --help Show this help
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Non-interactive defaults resolve from `~/.spinup-tsrc.json`, then local `git config`
|
|
42
|
+
(author name/email), then built-in fallbacks.
|
|
43
|
+
|
|
44
|
+
## What's Included
|
|
45
|
+
|
|
46
|
+
| Python (cookiecutter-uv) | TypeScript equivalent |
|
|
47
|
+
|---|---|
|
|
48
|
+
| `uv` | `pnpm` |
|
|
49
|
+
| `ruff` | `Biome` |
|
|
50
|
+
| `wemake-python-styleguide` | ESLint strict (unicorn + sonarjs + import-x) |
|
|
51
|
+
| `mypy --strict` | `tsc --noEmit` + `@typescript-eslint/strictTypeChecked` |
|
|
52
|
+
| `pytest` + `coverage` | `Vitest` + `@vitest/coverage-v8` |
|
|
53
|
+
| `mkdocs-material` | `Docusaurus` |
|
|
54
|
+
| `deptry` | `depcheck` |
|
|
55
|
+
| `pre-commit` | `Husky` + `lint-staged` + `commitlint` |
|
|
56
|
+
| `Makefile` | `justfile` |
|
|
57
|
+
| `tox` (multi-version) | CI matrix over Node 20/22 |
|
|
58
|
+
| `release-please` | `release-please` (`release-type: node`) |
|
|
59
|
+
|
|
60
|
+
## Prompt Options
|
|
61
|
+
|
|
62
|
+
- **Project name** — kebab-case slug
|
|
63
|
+
- **Description** — one-liner
|
|
64
|
+
- **Author / Email / GitHub handle**
|
|
65
|
+
- **Node version** — 20, 22, 23
|
|
66
|
+
- **Package manager** — pnpm (default), bun, npm
|
|
67
|
+
- **Project type** — library, cli, server, mcp-server
|
|
68
|
+
- **GitHub Actions** — CI + release workflows
|
|
69
|
+
- **Publish to npm** — with provenance
|
|
70
|
+
- **Docusaurus docs** — deployed to GitHub Pages on release
|
|
71
|
+
- **Codecov** — coverage reporting
|
|
72
|
+
- **Dockerfile** — multi-stage Node build
|
|
73
|
+
- **Devcontainer** — full Claude Code-optimized environment
|
|
74
|
+
- **License** — MIT, Apache 2.0, BSD, ISC, GPL-3, None
|
|
75
|
+
|
|
76
|
+
## Development
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
pnpm install
|
|
80
|
+
pnpm build
|
|
81
|
+
pnpm test
|
|
82
|
+
```
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":""}
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,96 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
import { createRequire } from 'node:module';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import * as clack from '@clack/prompts';
|
|
5
|
+
// eslint-disable-next-line import-x/no-unresolved
|
|
6
|
+
import { buildDefaultConfig, runPrompts } from './prompts.js';
|
|
7
|
+
// eslint-disable-next-line import-x/no-unresolved
|
|
8
|
+
import { checkDestinationDir, scaffold } from './scaffold.js';
|
|
9
|
+
// eslint-disable-next-line import-x/no-unresolved
|
|
10
|
+
import { updateProject } from './update.js';
|
|
11
|
+
const require = createRequire(import.meta.url);
|
|
12
|
+
const packageJson = require('../package.json');
|
|
13
|
+
const HELP_TEXT = `spinup-ts — scaffold a production-ready TypeScript project (sibling of spinup-py)
|
|
14
|
+
|
|
15
|
+
Usage:
|
|
16
|
+
spinup-ts [new] <project-name> Scaffold a new TypeScript project
|
|
17
|
+
spinup-ts update [dir] Retrofit an existing repo with template tooling
|
|
18
|
+
spinup-ts --update [dir] Alias for \`update\`
|
|
19
|
+
|
|
20
|
+
Options:
|
|
21
|
+
-y, --yes, --non-interactive Scaffold with defaults only, no prompts (needs <project-name>)
|
|
22
|
+
-v, --version Print version
|
|
23
|
+
-h, --help Show this help
|
|
24
|
+
|
|
25
|
+
Examples:
|
|
26
|
+
spinup-ts my-lib
|
|
27
|
+
spinup-ts new my-lib
|
|
28
|
+
spinup-ts my-lib --non-interactive
|
|
29
|
+
spinup-ts update .
|
|
30
|
+
spinup-ts --update /path/to/repo
|
|
31
|
+
`;
|
|
32
|
+
function parseArgs(argv) {
|
|
33
|
+
const help = argv.includes('--help') || argv.includes('-h');
|
|
34
|
+
const version = argv.includes('--version') || argv.includes('-v');
|
|
35
|
+
const nonInteractive = argv.includes('--non-interactive') || argv.includes('--yes') || argv.includes('-y');
|
|
36
|
+
const updateFlag = argv.includes('--update') || argv.includes('-u');
|
|
37
|
+
const positionals = argv.filter((a) => !a.startsWith('-'));
|
|
38
|
+
// Subcommand form: `new <name>` / `update [dir]`
|
|
39
|
+
if (positionals[0] === 'new') {
|
|
40
|
+
return { command: 'new', name: positionals[1], nonInteractive, help, version };
|
|
41
|
+
}
|
|
42
|
+
if (positionals[0] === 'update') {
|
|
43
|
+
return { command: 'update', dir: positionals[1], nonInteractive, help, version };
|
|
44
|
+
}
|
|
45
|
+
// Flag form: `--update [dir]`
|
|
46
|
+
if (updateFlag) {
|
|
47
|
+
return { command: 'update', dir: positionals[0], nonInteractive, help, version };
|
|
48
|
+
}
|
|
49
|
+
// Bare form: `spinup-ts <name>`
|
|
50
|
+
return { command: 'new', name: positionals[0], nonInteractive, help, version };
|
|
51
|
+
}
|
|
52
|
+
async function runCreate(projectName, nonInteractive) {
|
|
53
|
+
const destDir = path.resolve(projectName ?? '.');
|
|
54
|
+
await checkDestinationDir(destDir);
|
|
55
|
+
let config;
|
|
56
|
+
if (nonInteractive) {
|
|
57
|
+
if (!projectName) {
|
|
58
|
+
throw new Error('A project name is required in non-interactive mode: spinup-ts <name> --yes');
|
|
59
|
+
}
|
|
60
|
+
config = await buildDefaultConfig(projectName);
|
|
61
|
+
}
|
|
62
|
+
else {
|
|
63
|
+
config = await runPrompts(projectName);
|
|
64
|
+
}
|
|
65
|
+
await scaffold(destDir, config);
|
|
66
|
+
clack.outro(`Project created at ${destDir}`);
|
|
67
|
+
}
|
|
68
|
+
async function runUpdate(targetDir) {
|
|
69
|
+
await updateProject(path.resolve(targetDir));
|
|
70
|
+
}
|
|
71
|
+
async function main() {
|
|
72
|
+
const args = parseArgs(process.argv.slice(2));
|
|
73
|
+
if (args.help) {
|
|
74
|
+
process.stdout.write(HELP_TEXT);
|
|
75
|
+
return;
|
|
76
|
+
}
|
|
77
|
+
if (args.version) {
|
|
78
|
+
process.stdout.write(`${packageJson.version}\n`);
|
|
79
|
+
return;
|
|
80
|
+
}
|
|
81
|
+
if (args.command === 'update') {
|
|
82
|
+
await runUpdate(args.dir ?? '.');
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
await runCreate(args.name, args.nonInteractive);
|
|
86
|
+
}
|
|
87
|
+
await main().catch((error) => {
|
|
88
|
+
if (error instanceof Error) {
|
|
89
|
+
clack.log.error(error.message);
|
|
90
|
+
}
|
|
91
|
+
else {
|
|
92
|
+
clack.log.error(String(error));
|
|
93
|
+
}
|
|
94
|
+
process.exit(1);
|
|
95
|
+
});
|
|
96
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { type ProjectConfig } from './types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Run the full interactive prompt flow and return a validated {@link ProjectConfig}.
|
|
4
|
+
*
|
|
5
|
+
* @param projectName - Optional name from CLI args; when provided, the name prompt is skipped.
|
|
6
|
+
*/
|
|
7
|
+
export declare function runPrompts(projectName?: string): Promise<ProjectConfig>;
|
|
8
|
+
/**
|
|
9
|
+
* Build a {@link ProjectConfig} from defaults only, with no interactive prompts.
|
|
10
|
+
*
|
|
11
|
+
* Resolution order for each field: `~/.spinup-tsrc.json` → local `git config` (author
|
|
12
|
+
* name/email) → built-in fallback. Mirrors spinup-py's `--non-interactive` / `--yes` mode.
|
|
13
|
+
*
|
|
14
|
+
* @param projectName - kebab-case project name (required; validated here).
|
|
15
|
+
*/
|
|
16
|
+
export declare function buildDefaultConfig(projectName: string): Promise<ProjectConfig>;
|
|
17
|
+
//# sourceMappingURL=prompts.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.d.ts","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"AAQA,OAAO,EACL,KAAK,aAAa,EAKnB,MAAM,YAAY,CAAC;AA4FpB;;;;GAIG;AAEH,wBAAsB,UAAU,CAAC,WAAW,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA8K7E;AAED;;;;;;;GAOG;AACH,wBAAsB,kBAAkB,CAAC,WAAW,EAAE,MAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CA8BpF"}
|
package/dist/prompts.js
ADDED
|
@@ -0,0 +1,264 @@
|
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
import { readFile } from 'node:fs/promises';
|
|
3
|
+
import { homedir } from 'node:os';
|
|
4
|
+
import path from 'node:path';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
import * as clack from '@clack/prompts';
|
|
7
|
+
/* eslint-disable import-x/no-unresolved */
|
|
8
|
+
import { deriveSlug, projectConfigSchema, userDefaultsSchema, } from './types.js';
|
|
9
|
+
/* eslint-enable import-x/no-unresolved */
|
|
10
|
+
const execAsync = promisify(exec);
|
|
11
|
+
const RC_PATH = path.join(homedir(), '.spinup-tsrc.json');
|
|
12
|
+
async function loadUserDefaults() {
|
|
13
|
+
try {
|
|
14
|
+
const raw = await readFile(RC_PATH, 'utf8');
|
|
15
|
+
const result = userDefaultsSchema.safeParse(JSON.parse(raw));
|
|
16
|
+
return result.success ? result.data : {};
|
|
17
|
+
}
|
|
18
|
+
catch {
|
|
19
|
+
return {};
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/** Read a single `git config` value, returning undefined if unset or git is unavailable. */
|
|
23
|
+
async function gitConfigValue(key) {
|
|
24
|
+
try {
|
|
25
|
+
const { stdout } = await execAsync(`git config --get ${key}`);
|
|
26
|
+
return stdout.trim() || undefined;
|
|
27
|
+
}
|
|
28
|
+
catch {
|
|
29
|
+
return undefined;
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
/** kebab-case identifier: starts with a letter, then letters/digits/hyphens. */
|
|
33
|
+
const KEBAB_CASE = /^[a-z][a-z0-9-]*$/;
|
|
34
|
+
/** Lightweight RFC 5322-ish email check; full validation happens in Zod. */
|
|
35
|
+
// eslint-disable-next-line sonarjs/slow-regex
|
|
36
|
+
const EMAIL_RE = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
|
|
37
|
+
/**
|
|
38
|
+
* Narrow a clack prompt result, exiting cleanly if the user cancelled.
|
|
39
|
+
* Returns the value typed as `T` on success.
|
|
40
|
+
*/
|
|
41
|
+
function unwrap(value) {
|
|
42
|
+
if (clack.isCancel(value)) {
|
|
43
|
+
clack.cancel('Operation cancelled.');
|
|
44
|
+
process.exit(0);
|
|
45
|
+
}
|
|
46
|
+
return value;
|
|
47
|
+
}
|
|
48
|
+
/** Validator for the project name text prompt. */
|
|
49
|
+
function validateProjectName(value) {
|
|
50
|
+
if (!value)
|
|
51
|
+
return 'Project name is required';
|
|
52
|
+
if (!KEBAB_CASE.test(value)) {
|
|
53
|
+
return 'Use kebab-case: lowercase letters, numbers, hyphens; start with a letter';
|
|
54
|
+
}
|
|
55
|
+
return undefined;
|
|
56
|
+
}
|
|
57
|
+
/** Validator for the author email text prompt. */
|
|
58
|
+
function validateEmail(value) {
|
|
59
|
+
if (!value)
|
|
60
|
+
return 'Email is required';
|
|
61
|
+
if (!EMAIL_RE.test(value))
|
|
62
|
+
return 'Enter a valid email address';
|
|
63
|
+
return undefined;
|
|
64
|
+
}
|
|
65
|
+
/** Prompt for the project name, or return the provided CLI arg if valid. */
|
|
66
|
+
async function promptProjectName(provided) {
|
|
67
|
+
if (provided !== undefined) {
|
|
68
|
+
const err = validateProjectName(provided);
|
|
69
|
+
if (err) {
|
|
70
|
+
clack.cancel(`Invalid project name "${provided}": ${err}`);
|
|
71
|
+
process.exit(1);
|
|
72
|
+
}
|
|
73
|
+
return provided;
|
|
74
|
+
}
|
|
75
|
+
const value = await clack.text({
|
|
76
|
+
message: 'Project name?',
|
|
77
|
+
placeholder: 'my-awesome-lib',
|
|
78
|
+
validate: validateProjectName,
|
|
79
|
+
});
|
|
80
|
+
return unwrap(value);
|
|
81
|
+
}
|
|
82
|
+
/** Build the human-readable feature summary line. */
|
|
83
|
+
function summarizeFeatures(config) {
|
|
84
|
+
const features = [];
|
|
85
|
+
if (config.includeGithubActions)
|
|
86
|
+
features.push('GitHub Actions');
|
|
87
|
+
if (config.publishToNpm)
|
|
88
|
+
features.push('npm publish');
|
|
89
|
+
if (config.includeDocs)
|
|
90
|
+
features.push('Docusaurus docs');
|
|
91
|
+
if (config.includeCodecov)
|
|
92
|
+
features.push('Codecov');
|
|
93
|
+
if (config.includeDockerfile)
|
|
94
|
+
features.push('Dockerfile');
|
|
95
|
+
if (config.includeDevcontainer)
|
|
96
|
+
features.push('devcontainer');
|
|
97
|
+
features.push(`${config.license} license`);
|
|
98
|
+
return features.join(', ');
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* Run the full interactive prompt flow and return a validated {@link ProjectConfig}.
|
|
102
|
+
*
|
|
103
|
+
* @param projectName - Optional name from CLI args; when provided, the name prompt is skipped.
|
|
104
|
+
*/
|
|
105
|
+
// eslint-disable-next-line max-lines-per-function, max-statements
|
|
106
|
+
export async function runPrompts(projectName) {
|
|
107
|
+
clack.intro('spinup-ts');
|
|
108
|
+
const d = await loadUserDefaults();
|
|
109
|
+
const name = await promptProjectName(projectName);
|
|
110
|
+
const description = unwrap(await clack.text({
|
|
111
|
+
message: 'Short description?',
|
|
112
|
+
placeholder: 'A delightful TypeScript project',
|
|
113
|
+
}));
|
|
114
|
+
const author = unwrap(await clack.text({
|
|
115
|
+
message: 'Author name?',
|
|
116
|
+
...(d.author !== undefined && { initialValue: d.author }),
|
|
117
|
+
validate: (v) => (v ? undefined : 'Author name is required'),
|
|
118
|
+
}));
|
|
119
|
+
const email = unwrap(await clack.text({
|
|
120
|
+
message: 'Author email?',
|
|
121
|
+
...(d.email !== undefined && { initialValue: d.email }),
|
|
122
|
+
validate: validateEmail,
|
|
123
|
+
}));
|
|
124
|
+
const githubHandle = unwrap(await clack.text({
|
|
125
|
+
message: 'GitHub handle?',
|
|
126
|
+
placeholder: 'octocat',
|
|
127
|
+
...(d.githubHandle !== undefined && { initialValue: d.githubHandle }),
|
|
128
|
+
validate: (v) => (v ? undefined : 'GitHub handle is required'),
|
|
129
|
+
}));
|
|
130
|
+
const nodeVersion = unwrap(await clack.select({
|
|
131
|
+
message: 'Node version?',
|
|
132
|
+
initialValue: d.nodeVersion ?? '22',
|
|
133
|
+
options: [
|
|
134
|
+
{ value: '20', label: '20' },
|
|
135
|
+
{ value: '22', label: '22', hint: 'LTS ✓' },
|
|
136
|
+
{ value: '23', label: '23' },
|
|
137
|
+
],
|
|
138
|
+
}));
|
|
139
|
+
const packageManager = unwrap(await clack.select({
|
|
140
|
+
message: 'Package manager?',
|
|
141
|
+
initialValue: d.packageManager ?? 'pnpm',
|
|
142
|
+
options: [
|
|
143
|
+
{ value: 'pnpm', label: 'pnpm', hint: 'recommended' },
|
|
144
|
+
{ value: 'bun', label: 'bun' },
|
|
145
|
+
{ value: 'npm', label: 'npm' },
|
|
146
|
+
],
|
|
147
|
+
}));
|
|
148
|
+
const projectType = unwrap(await clack.select({
|
|
149
|
+
message: 'Project type?',
|
|
150
|
+
initialValue: d.projectType ?? 'library',
|
|
151
|
+
options: [
|
|
152
|
+
{ value: 'library', label: 'library' },
|
|
153
|
+
{ value: 'cli', label: 'cli' },
|
|
154
|
+
{ value: 'server', label: 'server' },
|
|
155
|
+
{ value: 'mcp-server', label: 'mcp-server' },
|
|
156
|
+
],
|
|
157
|
+
}));
|
|
158
|
+
const includeGithubActions = unwrap(await clack.confirm({
|
|
159
|
+
message: 'Include GitHub Actions?',
|
|
160
|
+
initialValue: d.includeGithubActions ?? true,
|
|
161
|
+
}));
|
|
162
|
+
const publishToNpm = unwrap(await clack.confirm({
|
|
163
|
+
message: 'Publish to npm?',
|
|
164
|
+
initialValue: d.publishToNpm ?? false,
|
|
165
|
+
}));
|
|
166
|
+
const includeDocumentation = unwrap(await clack.confirm({
|
|
167
|
+
message: 'Include Docusaurus docs?',
|
|
168
|
+
initialValue: d.includeDocs ?? false,
|
|
169
|
+
}));
|
|
170
|
+
const includeCodecov = unwrap(await clack.confirm({
|
|
171
|
+
message: 'Include Codecov?',
|
|
172
|
+
initialValue: d.includeCodecov ?? false,
|
|
173
|
+
}));
|
|
174
|
+
const includeDockerfile = unwrap(await clack.confirm({
|
|
175
|
+
message: 'Include Dockerfile?',
|
|
176
|
+
initialValue: d.includeDockerfile ?? false,
|
|
177
|
+
}));
|
|
178
|
+
const includeDevcontainer = unwrap(await clack.confirm({
|
|
179
|
+
message: 'Include devcontainer?',
|
|
180
|
+
initialValue: d.includeDevcontainer ?? true,
|
|
181
|
+
}));
|
|
182
|
+
const license = unwrap(await clack.select({
|
|
183
|
+
message: 'License?',
|
|
184
|
+
initialValue: d.license ?? 'MIT',
|
|
185
|
+
options: [
|
|
186
|
+
{ value: 'MIT', label: 'MIT' },
|
|
187
|
+
{ value: 'Apache-2.0', label: 'Apache-2.0' },
|
|
188
|
+
{ value: 'BSD-3-Clause', label: 'BSD-3-Clause' },
|
|
189
|
+
{ value: 'ISC', label: 'ISC' },
|
|
190
|
+
{ value: 'GPL-3.0', label: 'GPL-3.0' },
|
|
191
|
+
{ value: 'UNLICENSED', label: 'Unlicensed' },
|
|
192
|
+
],
|
|
193
|
+
}));
|
|
194
|
+
const config = projectConfigSchema.parse({
|
|
195
|
+
projectName: name,
|
|
196
|
+
projectSlug: deriveSlug(name),
|
|
197
|
+
description,
|
|
198
|
+
author,
|
|
199
|
+
email,
|
|
200
|
+
githubHandle,
|
|
201
|
+
nodeVersion,
|
|
202
|
+
packageManager,
|
|
203
|
+
projectType,
|
|
204
|
+
includeGithubActions,
|
|
205
|
+
publishToNpm,
|
|
206
|
+
includeDocs: includeDocumentation,
|
|
207
|
+
includeCodecov,
|
|
208
|
+
includeDockerfile,
|
|
209
|
+
includeDevcontainer,
|
|
210
|
+
license,
|
|
211
|
+
});
|
|
212
|
+
clack.note([
|
|
213
|
+
`Project: ${config.projectName}`,
|
|
214
|
+
`Type: ${config.projectType} · Node: ${config.nodeVersion} · PM: ${config.packageManager}`,
|
|
215
|
+
`Features: ${summarizeFeatures(config)}`,
|
|
216
|
+
].join('\n'), 'Summary');
|
|
217
|
+
const proceed = unwrap(await clack.confirm({
|
|
218
|
+
message: 'Create project with these settings?',
|
|
219
|
+
initialValue: true,
|
|
220
|
+
}));
|
|
221
|
+
if (!proceed) {
|
|
222
|
+
clack.cancel('Operation cancelled.');
|
|
223
|
+
process.exit(0);
|
|
224
|
+
}
|
|
225
|
+
return config;
|
|
226
|
+
}
|
|
227
|
+
/**
|
|
228
|
+
* Build a {@link ProjectConfig} from defaults only, with no interactive prompts.
|
|
229
|
+
*
|
|
230
|
+
* Resolution order for each field: `~/.spinup-tsrc.json` → local `git config` (author
|
|
231
|
+
* name/email) → built-in fallback. Mirrors spinup-py's `--non-interactive` / `--yes` mode.
|
|
232
|
+
*
|
|
233
|
+
* @param projectName - kebab-case project name (required; validated here).
|
|
234
|
+
*/
|
|
235
|
+
export async function buildDefaultConfig(projectName) {
|
|
236
|
+
const nameError = validateProjectName(projectName);
|
|
237
|
+
if (nameError) {
|
|
238
|
+
throw new Error(`Invalid project name "${projectName}": ${nameError}`);
|
|
239
|
+
}
|
|
240
|
+
const d = await loadUserDefaults();
|
|
241
|
+
const [gitName, gitEmail] = await Promise.all([
|
|
242
|
+
gitConfigValue('user.name'),
|
|
243
|
+
gitConfigValue('user.email'),
|
|
244
|
+
]);
|
|
245
|
+
return projectConfigSchema.parse({
|
|
246
|
+
projectName,
|
|
247
|
+
projectSlug: deriveSlug(projectName),
|
|
248
|
+
description: '',
|
|
249
|
+
author: d.author ?? gitName ?? 'Your Name',
|
|
250
|
+
email: d.email ?? gitEmail ?? 'you@example.com',
|
|
251
|
+
githubHandle: d.githubHandle ?? 'your-handle',
|
|
252
|
+
nodeVersion: d.nodeVersion ?? '22',
|
|
253
|
+
packageManager: d.packageManager ?? 'pnpm',
|
|
254
|
+
projectType: d.projectType ?? 'library',
|
|
255
|
+
includeGithubActions: d.includeGithubActions ?? true,
|
|
256
|
+
publishToNpm: d.publishToNpm ?? false,
|
|
257
|
+
includeDocs: d.includeDocs ?? false,
|
|
258
|
+
includeCodecov: d.includeCodecov ?? false,
|
|
259
|
+
includeDockerfile: d.includeDockerfile ?? false,
|
|
260
|
+
includeDevcontainer: d.includeDevcontainer ?? true,
|
|
261
|
+
license: d.license ?? 'MIT',
|
|
262
|
+
});
|
|
263
|
+
}
|
|
264
|
+
//# sourceMappingURL=prompts.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"prompts.js","sourceRoot":"","sources":["../src/prompts.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import { type ProjectConfig, type TokenMap } from './types.js';
|
|
2
|
+
export declare function checkDestinationDir(destDir: string): Promise<void>;
|
|
3
|
+
export declare function replaceTokensInTree(destDir: string, tokens: TokenMap): Promise<void>;
|
|
4
|
+
export declare function scaffold(destDir: string, config: ProjectConfig): Promise<void>;
|
|
5
|
+
//# sourceMappingURL=scaffold.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAYA,OAAO,EAAE,KAAK,aAAa,EAAE,KAAK,QAAQ,EAAc,MAAM,YAAY,CAAC;AAoB3E,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAUxE;AA+BD,wBAAsB,mBAAmB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAkB1F;AAsCD,wBAAsB,QAAQ,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAkBpF"}
|
package/dist/scaffold.js
ADDED
|
@@ -0,0 +1,128 @@
|
|
|
1
|
+
import { exec } from 'node:child_process';
|
|
2
|
+
import { mkdir, readFile, readdir, writeFile } from 'node:fs/promises';
|
|
3
|
+
import path from 'node:path';
|
|
4
|
+
import { fileURLToPath } from 'node:url';
|
|
5
|
+
import { promisify } from 'node:util';
|
|
6
|
+
import degit from 'degit';
|
|
7
|
+
import fse from 'fs-extra';
|
|
8
|
+
import { globby } from 'globby';
|
|
9
|
+
import pc from 'picocolors';
|
|
10
|
+
// eslint-disable-next-line import-x/no-unresolved
|
|
11
|
+
import { applyTransforms } from './transforms/index.js';
|
|
12
|
+
// eslint-disable-next-line import-x/no-unresolved
|
|
13
|
+
import { toTokenMap } from './types.js';
|
|
14
|
+
const execAsync = promisify(exec);
|
|
15
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
16
|
+
const DEGIT_SOURCE = 'joeblackwaslike/spinup-ts/template';
|
|
17
|
+
const INSTALL_COMMANDS = {
|
|
18
|
+
pnpm: 'pnpm install',
|
|
19
|
+
bun: 'bun install',
|
|
20
|
+
npm: 'npm install',
|
|
21
|
+
};
|
|
22
|
+
const logStep = (message) => {
|
|
23
|
+
// biome-ignore lint/suspicious/noConsole: intentional CLI output
|
|
24
|
+
console.log(` ${pc.green('✓')} ${message}`);
|
|
25
|
+
};
|
|
26
|
+
const isDevelopmentMode = () => process.env.NODE_ENV === 'development' || process.env.__DEV_TEMPLATE_PATH__ !== undefined;
|
|
27
|
+
export async function checkDestinationDir(destDir) {
|
|
28
|
+
try {
|
|
29
|
+
const entries = await readdir(destDir);
|
|
30
|
+
if (entries.length > 0) {
|
|
31
|
+
throw new Error(`Directory ${destDir} already exists and is not empty.`);
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
catch (error) {
|
|
35
|
+
if (error.code === 'ENOENT')
|
|
36
|
+
return;
|
|
37
|
+
throw error;
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
async function cloneTemplate(destDir) {
|
|
41
|
+
if (isDevelopmentMode()) {
|
|
42
|
+
const override = process.env.__DEV_TEMPLATE_PATH__;
|
|
43
|
+
const localPath = override ?? path.resolve(__dirname, '..', 'template');
|
|
44
|
+
await fse.copy(localPath, destDir);
|
|
45
|
+
return;
|
|
46
|
+
}
|
|
47
|
+
const emitter = degit(DEGIT_SOURCE, { cache: false, force: true, verbose: false });
|
|
48
|
+
await emitter.clone(destDir);
|
|
49
|
+
}
|
|
50
|
+
const BINARY_SAMPLE_SIZE = 8000;
|
|
51
|
+
function isBinaryBuffer(buffer) {
|
|
52
|
+
const sampleSize = Math.min(buffer.length, BINARY_SAMPLE_SIZE);
|
|
53
|
+
for (let index = 0; index < sampleSize; index++) {
|
|
54
|
+
if (buffer[index] === 0)
|
|
55
|
+
return true;
|
|
56
|
+
}
|
|
57
|
+
return false;
|
|
58
|
+
}
|
|
59
|
+
function replaceTokens(content, tokens) {
|
|
60
|
+
let result = content;
|
|
61
|
+
for (const [token, value] of Object.entries(tokens)) {
|
|
62
|
+
result = result.replaceAll(token, value);
|
|
63
|
+
}
|
|
64
|
+
return result;
|
|
65
|
+
}
|
|
66
|
+
export async function replaceTokensInTree(destDir, tokens) {
|
|
67
|
+
const files = await globby('**/*', {
|
|
68
|
+
cwd: destDir,
|
|
69
|
+
dot: true,
|
|
70
|
+
gitignore: false,
|
|
71
|
+
onlyFiles: true,
|
|
72
|
+
ignore: ['node_modules/**', '.git/**'],
|
|
73
|
+
});
|
|
74
|
+
await Promise.all(files.map(async (relativePath) => {
|
|
75
|
+
const filePath = path.join(destDir, relativePath);
|
|
76
|
+
const buffer = await readFile(filePath);
|
|
77
|
+
if (isBinaryBuffer(buffer))
|
|
78
|
+
return;
|
|
79
|
+
const original = buffer.toString('utf8');
|
|
80
|
+
const replaced = replaceTokens(original, tokens);
|
|
81
|
+
if (replaced !== original)
|
|
82
|
+
await writeFile(filePath, replaced, 'utf8');
|
|
83
|
+
}));
|
|
84
|
+
}
|
|
85
|
+
async function initGit(destDir) {
|
|
86
|
+
await execAsync('git init', { cwd: destDir });
|
|
87
|
+
await execAsync('git add -A', { cwd: destDir });
|
|
88
|
+
// Inline identity so the initial commit never depends on the user's global
|
|
89
|
+
// git config (keeps scaffolding deterministic in CI and fresh environments).
|
|
90
|
+
await execAsync('git -c user.name="spinup-ts" -c user.email="spinup-ts@users.noreply.github.com" commit -m "chore: initial scaffold from spinup-ts"', { cwd: destDir });
|
|
91
|
+
}
|
|
92
|
+
async function installDependencies(destDir, packageManager) {
|
|
93
|
+
await execAsync(INSTALL_COMMANDS[packageManager], { cwd: destDir });
|
|
94
|
+
}
|
|
95
|
+
async function initializeProjectTools(destDir, config) {
|
|
96
|
+
try {
|
|
97
|
+
await execAsync('bd init --skip-agents --non-interactive', { cwd: destDir });
|
|
98
|
+
logStep('Initialized Beads task manager');
|
|
99
|
+
}
|
|
100
|
+
catch {
|
|
101
|
+
// bd not installed; skip silently
|
|
102
|
+
}
|
|
103
|
+
const serenaDir = path.join(destDir, '.serena');
|
|
104
|
+
await mkdir(serenaDir, { recursive: true });
|
|
105
|
+
await writeFile(path.join(serenaDir, 'project.yml'), `project_name: ${config.projectSlug}\nlanguages:\n - typescript\n`, 'utf8');
|
|
106
|
+
logStep('Initialized Serena project config');
|
|
107
|
+
}
|
|
108
|
+
export async function scaffold(destDir, config) {
|
|
109
|
+
await cloneTemplate(destDir);
|
|
110
|
+
logStep('Cloning template...');
|
|
111
|
+
await replaceTokensInTree(destDir, toTokenMap(config));
|
|
112
|
+
logStep('Replacing tokens...');
|
|
113
|
+
await applyTransforms(destDir, config);
|
|
114
|
+
logStep('Applying transforms...');
|
|
115
|
+
await initGit(destDir);
|
|
116
|
+
logStep('Initializing git...');
|
|
117
|
+
// SPINUP_TS_SKIP_INSTALL=1 skips the (heavy, network-bound) dependency install
|
|
118
|
+
// for the generated project — used by the packaged-binary smoke test in CI.
|
|
119
|
+
if (process.env.SPINUP_TS_SKIP_INSTALL === '1') {
|
|
120
|
+
logStep('Skipping dependency install (SPINUP_TS_SKIP_INSTALL=1)');
|
|
121
|
+
}
|
|
122
|
+
else {
|
|
123
|
+
await installDependencies(destDir, config.packageManager);
|
|
124
|
+
logStep('Installing dependencies...');
|
|
125
|
+
}
|
|
126
|
+
await initializeProjectTools(destDir, config);
|
|
127
|
+
}
|
|
128
|
+
//# sourceMappingURL=scaffold.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"devcontainer.d.ts","sourceRoot":"","sources":["../../src/transforms/devcontainer.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAEjD,wBAAsB,qBAAqB,CAAC,OAAO,EAAE,MAAM,EAAE,MAAM,EAAE,aAAa,GAAG,OAAO,CAAC,IAAI,CAAC,CAIjG"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import fse from 'fs-extra';
|
|
3
|
+
export async function transformDevcontainer(destDir, config) {
|
|
4
|
+
if (config.includeDevcontainer)
|
|
5
|
+
return;
|
|
6
|
+
await fse.remove(path.join(destDir, '.devcontainer'));
|
|
7
|
+
}
|
|
8
|
+
//# sourceMappingURL=devcontainer.js.map
|