kaddidlehopper 0.6.0 → 0.7.1
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/dist/cli.js +25 -13
- package/dist/types/types.d.ts +0 -1
- package/package.json +1 -1
- package/src/cli.ts +27 -19
- package/src/types.ts +0 -1
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolve, basename } from 'node:path';
|
|
2
|
-
import { existsSync
|
|
2
|
+
import { existsSync } from 'node:fs';
|
|
3
3
|
import { cp, rm, mkdtemp, readFile, writeFile } from 'node:fs/promises';
|
|
4
4
|
import { tmpdir } from 'node:os';
|
|
5
5
|
import { join } from 'node:path';
|
|
@@ -7,8 +7,8 @@ import { execSync } from 'node:child_process';
|
|
|
7
7
|
import { Command } from 'commander';
|
|
8
8
|
import chalk from 'chalk';
|
|
9
9
|
import validatePackageName from 'validate-npm-package-name';
|
|
10
|
-
const GITHUB_REPO = 'https://github.com/
|
|
11
|
-
const MANIFEST_URL = 'https://raw.githubusercontent.com/
|
|
10
|
+
const GITHUB_REPO = 'https://github.com/netlify/swar-templates.git';
|
|
11
|
+
const MANIFEST_URL = 'https://raw.githubusercontent.com/netlify/swar-templates/main/manifest.json';
|
|
12
12
|
function sanitizePackageName(name) {
|
|
13
13
|
return name
|
|
14
14
|
.toLowerCase()
|
|
@@ -51,8 +51,7 @@ export function cli() {
|
|
|
51
51
|
.option('--add-ons [id]', 'starter ID to use from the template repo')
|
|
52
52
|
.option('--list-addons-json', 'list all available starters as JSON', false)
|
|
53
53
|
.option('--no-git', 'do not create a git repository')
|
|
54
|
-
.option('--target-dir <path>', 'the target directory for the application root')
|
|
55
|
-
.option('-f, --force', 'force project creation even if the target directory is not empty');
|
|
54
|
+
.option('--target-dir <path>', 'the target directory for the application root');
|
|
56
55
|
program.action(async (projectName, options) => {
|
|
57
56
|
// Handle --list-addons-json
|
|
58
57
|
if (options.listAddonsJson) {
|
|
@@ -77,22 +76,23 @@ export function cli() {
|
|
|
77
76
|
console.error(chalk.red(error));
|
|
78
77
|
process.exit(1);
|
|
79
78
|
}
|
|
80
|
-
//
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
console.error(chalk.red(`Target directory "${targetDir}" is not empty. Use --force to overwrite.`));
|
|
85
|
-
process.exit(1);
|
|
86
|
-
}
|
|
79
|
+
// Delete index.html if it exists in the target directory
|
|
80
|
+
const indexHtmlPath = join(targetDir, 'index.html');
|
|
81
|
+
if (existsSync(indexHtmlPath)) {
|
|
82
|
+
await rm(indexHtmlPath);
|
|
87
83
|
}
|
|
88
84
|
console.log(chalk.bold.cyan(`Creating a new Netlify TanStack Start app in ${chalk.white(targetDir)}...`));
|
|
89
85
|
console.log(chalk.gray(`Using starter: ${starterId}`));
|
|
86
|
+
const manifest = await fetch(MANIFEST_URL).then((r) => r.json());
|
|
87
|
+
const starterEntry = manifest.starters.find((s) => s.id === starterId);
|
|
88
|
+
const frameworkId = starterEntry?.framework;
|
|
90
89
|
// Sparse clone the template repo into a temp directory
|
|
91
90
|
const tmpDir = await mkdtemp(join(tmpdir(), 'netlify-cta-'));
|
|
92
91
|
try {
|
|
93
92
|
console.log(chalk.gray('⟳ Fetching template...'));
|
|
93
|
+
const sparsePaths = [`starters/${starterId}`, ...(frameworkId ? [`frameworks/${frameworkId}`] : [])];
|
|
94
94
|
execSync(`git clone --depth=1 --filter=blob:none --sparse ${GITHUB_REPO} ${tmpDir}`, { stdio: 'pipe' });
|
|
95
|
-
execSync(`git -C ${tmpDir} sparse-checkout set
|
|
95
|
+
execSync(`git -C ${tmpDir} sparse-checkout set ${sparsePaths.join(' ')}`, { stdio: 'pipe' });
|
|
96
96
|
const starterPath = join(tmpDir, 'starters', starterId);
|
|
97
97
|
if (!existsSync(starterPath)) {
|
|
98
98
|
console.error(chalk.red(`Starter "${starterId}" not found in the template repo. Run --list-addons-json to see available starters.`));
|
|
@@ -100,6 +100,18 @@ export function cli() {
|
|
|
100
100
|
}
|
|
101
101
|
// Copy starter files to target directory
|
|
102
102
|
await cp(starterPath, targetDir, { recursive: true });
|
|
103
|
+
// Copy framework overlay files if they exist
|
|
104
|
+
if (frameworkId) {
|
|
105
|
+
const frameworkPath = join(tmpDir, 'frameworks', frameworkId);
|
|
106
|
+
if (existsSync(frameworkPath)) {
|
|
107
|
+
console.log(chalk.gray(`⟳ Applying framework overlay (${frameworkId})...`));
|
|
108
|
+
await cp(frameworkPath, targetDir, { recursive: true });
|
|
109
|
+
console.log(chalk.green(`✓ Framework overlay applied (${frameworkId})`));
|
|
110
|
+
}
|
|
111
|
+
else {
|
|
112
|
+
console.log(chalk.yellow(`⚠ Framework overlay "${frameworkId}" not found in repo, skipping`));
|
|
113
|
+
}
|
|
114
|
+
}
|
|
103
115
|
// Update package.json name if a project name was provided
|
|
104
116
|
if (projectName && projectName !== '.') {
|
|
105
117
|
const pkgPath = join(targetDir, 'package.json');
|
package/dist/types/types.d.ts
CHANGED
package/package.json
CHANGED
package/src/cli.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { resolve, basename } from 'node:path'
|
|
2
|
-
import { existsSync
|
|
2
|
+
import { existsSync } from 'node:fs'
|
|
3
3
|
import { cp, rm, mkdtemp, readFile, writeFile } from 'node:fs/promises'
|
|
4
4
|
import { tmpdir } from 'node:os'
|
|
5
5
|
import { join } from 'node:path'
|
|
@@ -10,9 +10,9 @@ import validatePackageName from 'validate-npm-package-name'
|
|
|
10
10
|
|
|
11
11
|
import type { CliOptions } from './types.js'
|
|
12
12
|
|
|
13
|
-
const GITHUB_REPO = 'https://github.com/
|
|
13
|
+
const GITHUB_REPO = 'https://github.com/netlify/swar-templates.git'
|
|
14
14
|
const MANIFEST_URL =
|
|
15
|
-
'https://raw.githubusercontent.com/
|
|
15
|
+
'https://raw.githubusercontent.com/netlify/swar-templates/main/manifest.json'
|
|
16
16
|
|
|
17
17
|
function sanitizePackageName(name: string): string {
|
|
18
18
|
return name
|
|
@@ -72,10 +72,6 @@ export function cli() {
|
|
|
72
72
|
'--target-dir <path>',
|
|
73
73
|
'the target directory for the application root',
|
|
74
74
|
)
|
|
75
|
-
.option(
|
|
76
|
-
'-f, --force',
|
|
77
|
-
'force project creation even if the target directory is not empty',
|
|
78
|
-
)
|
|
79
75
|
|
|
80
76
|
program.action(async (projectName: string | undefined, options: CliOptions) => {
|
|
81
77
|
// Handle --list-addons-json
|
|
@@ -106,17 +102,10 @@ export function cli() {
|
|
|
106
102
|
process.exit(1)
|
|
107
103
|
}
|
|
108
104
|
|
|
109
|
-
//
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
console.error(
|
|
114
|
-
chalk.red(
|
|
115
|
-
`Target directory "${targetDir}" is not empty. Use --force to overwrite.`,
|
|
116
|
-
),
|
|
117
|
-
)
|
|
118
|
-
process.exit(1)
|
|
119
|
-
}
|
|
105
|
+
// Delete index.html if it exists in the target directory
|
|
106
|
+
const indexHtmlPath = join(targetDir, 'index.html')
|
|
107
|
+
if (existsSync(indexHtmlPath)) {
|
|
108
|
+
await rm(indexHtmlPath)
|
|
120
109
|
}
|
|
121
110
|
|
|
122
111
|
console.log(
|
|
@@ -126,16 +115,23 @@ export function cli() {
|
|
|
126
115
|
)
|
|
127
116
|
console.log(chalk.gray(`Using starter: ${starterId}`))
|
|
128
117
|
|
|
118
|
+
// Fetch manifest to resolve frameworkId for this starter
|
|
119
|
+
type StarterEntry = { id: string; framework?: string }
|
|
120
|
+
const manifest = await fetch(MANIFEST_URL).then((r) => r.json()) as { starters: StarterEntry[] }
|
|
121
|
+
const starterEntry = manifest.starters.find((s) => s.id === starterId)
|
|
122
|
+
const frameworkId = starterEntry?.framework
|
|
123
|
+
|
|
129
124
|
// Sparse clone the template repo into a temp directory
|
|
130
125
|
const tmpDir = await mkdtemp(join(tmpdir(), 'netlify-cta-'))
|
|
131
126
|
try {
|
|
132
127
|
console.log(chalk.gray('⟳ Fetching template...'))
|
|
128
|
+
const sparsePaths = [`starters/${starterId}`, ...(frameworkId ? [`frameworks/${frameworkId}`] : [])]
|
|
133
129
|
execSync(
|
|
134
130
|
`git clone --depth=1 --filter=blob:none --sparse ${GITHUB_REPO} ${tmpDir}`,
|
|
135
131
|
{ stdio: 'pipe' },
|
|
136
132
|
)
|
|
137
133
|
execSync(
|
|
138
|
-
`git -C ${tmpDir} sparse-checkout set
|
|
134
|
+
`git -C ${tmpDir} sparse-checkout set ${sparsePaths.join(' ')}`,
|
|
139
135
|
{ stdio: 'pipe' },
|
|
140
136
|
)
|
|
141
137
|
|
|
@@ -152,6 +148,18 @@ export function cli() {
|
|
|
152
148
|
// Copy starter files to target directory
|
|
153
149
|
await cp(starterPath, targetDir, { recursive: true })
|
|
154
150
|
|
|
151
|
+
// Copy framework overlay files if they exist
|
|
152
|
+
if (frameworkId) {
|
|
153
|
+
const frameworkPath = join(tmpDir, 'frameworks', frameworkId)
|
|
154
|
+
if (existsSync(frameworkPath)) {
|
|
155
|
+
console.log(chalk.gray(`⟳ Applying framework overlay (${frameworkId})...`))
|
|
156
|
+
await cp(frameworkPath, targetDir, { recursive: true })
|
|
157
|
+
console.log(chalk.green(`✓ Framework overlay applied (${frameworkId})`))
|
|
158
|
+
} else {
|
|
159
|
+
console.log(chalk.yellow(`⚠ Framework overlay "${frameworkId}" not found in repo, skipping`))
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
155
163
|
// Update package.json name if a project name was provided
|
|
156
164
|
if (projectName && projectName !== '.') {
|
|
157
165
|
const pkgPath = join(targetDir, 'package.json')
|