create-stk 0.0.1 → 0.0.3

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 CHANGED
@@ -12,4 +12,4 @@ or
12
12
  npx create-stk
13
13
  ```
14
14
 
15
- Templates and options will be documented here soon.
15
+ Templates and options will be documented here soon, including Next.js, Nuxt, Svelte, and Node.js.
package/dist/index.cjs CHANGED
@@ -260,13 +260,16 @@ var nextPageCode = `export default function Home() {
260
260
  </div>
261
261
  )
262
262
  }`;
263
- var nodeIndex = `
264
- console.log("Hello World!");`;
263
+ var nodeIndex = `function main() {
264
+ console.log("Hello World!");
265
+ }
266
+
267
+ main();`;
265
268
  var getNodePackage = (dirName) => `{
266
269
  "name": "${dirName}",
267
270
  "version": "1.0.0",
268
271
  "scripts": {
269
- "dev": "tsx index.mts"
272
+ "dev": "tsx index.mt"
270
273
  },
271
274
  "dependencies": {},
272
275
  "devDependencies": {}
@@ -354,7 +357,7 @@ async function setupNode(ctx) {
354
357
  import_fs.default.mkdirSync(targetDir, { recursive: true });
355
358
  }
356
359
  import_fs.default.writeFileSync(import_path2.default.join(targetDir, "package.json"), getNodePackage(dirName));
357
- import_fs.default.writeFileSync(import_path2.default.join(targetDir, "index.mts"), nodeIndex);
360
+ import_fs.default.writeFileSync(import_path2.default.join(targetDir, "index.ts"), nodeIndex);
358
361
  s.stop("Node Project created!");
359
362
  }
360
363
  async function setupSvelte(ctx) {
package/dist/index.js CHANGED
@@ -236,13 +236,16 @@ var nextPageCode = `export default function Home() {
236
236
  </div>
237
237
  )
238
238
  }`;
239
- var nodeIndex = `
240
- console.log("Hello World!");`;
239
+ var nodeIndex = `function main() {
240
+ console.log("Hello World!");
241
+ }
242
+
243
+ main();`;
241
244
  var getNodePackage = (dirName) => `{
242
245
  "name": "${dirName}",
243
246
  "version": "1.0.0",
244
247
  "scripts": {
245
- "dev": "tsx index.mts"
248
+ "dev": "tsx index.mt"
246
249
  },
247
250
  "dependencies": {},
248
251
  "devDependencies": {}
@@ -330,7 +333,7 @@ async function setupNode(ctx) {
330
333
  fs.mkdirSync(targetDir, { recursive: true });
331
334
  }
332
335
  fs.writeFileSync(path2.join(targetDir, "package.json"), getNodePackage(dirName));
333
- fs.writeFileSync(path2.join(targetDir, "index.mts"), nodeIndex);
336
+ fs.writeFileSync(path2.join(targetDir, "index.ts"), nodeIndex);
334
337
  s.stop("Node Project created!");
335
338
  }
336
339
  async function setupSvelte(ctx) {
@@ -73,13 +73,16 @@ export const nextPageCode = `export default function Home() {
73
73
  )
74
74
  }`;
75
75
  // Node
76
- export const nodeIndex = `
77
- console.log("Hello World!");`;
76
+ export const nodeIndex = `function main() {
77
+ console.log("Hello World!");
78
+ }
79
+
80
+ main();`;
78
81
  export const getNodePackage = (dirName) => `{
79
82
  "name": "${dirName}",
80
83
  "version": "1.0.0",
81
84
  "scripts": {
82
- "dev": "tsx index.mts"
85
+ "dev": "tsx index.mt"
83
86
  },
84
87
  "dependencies": {},
85
88
  "devDependencies": {}
@@ -175,7 +178,7 @@ async function setupNode(ctx) {
175
178
  fs.mkdirSync(targetDir, { recursive: true });
176
179
  }
177
180
  fs.writeFileSync(path.join(targetDir, 'package.json'), getNodePackage(dirName));
178
- fs.writeFileSync(path.join(targetDir, 'index.mts'), nodeIndex);
181
+ fs.writeFileSync(path.join(targetDir, 'index.ts'), nodeIndex);
179
182
  s.stop('Node Project created!');
180
183
  }
181
184
  async function setupSvelte(ctx) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-stk",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "description": "Opinionated, unified project scaffolding CLI.",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",
@@ -9,15 +9,6 @@
9
9
  "bin": {
10
10
  "create-stk": "dist/index.js"
11
11
  },
12
- "scripts": {
13
- "dev": "tsx src/index.ts",
14
- "test": "vitest run",
15
- "build": "tsup src/index.ts --format esm,cjs --dts",
16
- "lint": "tsc",
17
- "ci": "pnpm run lint && pnpm run test && pnpm run build",
18
- "release": "pnpm run lint && pnpm run test && pnpm run build && changeset publish",
19
- "prepare": "pnpm run build"
20
- },
21
12
  "files": [
22
13
  "dist",
23
14
  "assets",
@@ -42,5 +33,13 @@
42
33
  "tsx": "^4.21.0",
43
34
  "typescript": "^5.9.3",
44
35
  "vitest": "^4.0.16"
36
+ },
37
+ "scripts": {
38
+ "dev": "tsx src/index.ts",
39
+ "test": "vitest run",
40
+ "build": "tsup src/index.ts --format esm,cjs --dts",
41
+ "lint": "tsc",
42
+ "ci": "pnpm run lint && pnpm run test && pnpm run build",
43
+ "release": "pnpm run lint && pnpm run test && pnpm run build && changeset publish"
45
44
  }
46
- }
45
+ }
@@ -1,13 +0,0 @@
1
- import { TEMPLATES } from './template-registry';
2
- export const SUPPORTED_PROJECTS = TEMPLATES.map(t => ({
3
- name: t.name,
4
- type: t.id,
5
- category: t.category,
6
- }));
7
- export const SUPPORTED_PACKAGES = [
8
- { pkName: 'npm', pkInstall: 'npx' },
9
- { pkName: 'pnpm', pkInstall: 'pnpx' },
10
- { pkName: 'bun', pkInstall: 'bunx' },
11
- ];
12
- export const SUPPORTED_CATEGORIES = [...new Set(TEMPLATES.map(p => p.category))];
13
- export const PROJECT_TYPES = TEMPLATES.map(p => p.id);
package/dist/src/setup.js DELETED
@@ -1,124 +0,0 @@
1
- import { spinner } from '@clack/prompts';
2
- import { execa } from 'execa';
3
- import path from 'path';
4
- import fs from 'fs';
5
- import { getReadmeCode, globalsCss, nextPageCode, nodeIndex, getNodePackage, nuxtApp, nuxtConfig, sveltePage, svelteHead, gitignore } from './templates';
6
- const s = spinner();
7
- function replaceFavicon(targetDir, dest) {
8
- const currentFileUrl = new URL(import.meta.url);
9
- const __dirname = path.dirname(currentFileUrl.pathname);
10
- const faviconSource = path.resolve(__dirname, '..', 'assets', 'favicon.ico');
11
- const faviconDest = path.resolve(targetDir, dest);
12
- fs.copyFileSync(faviconSource, faviconDest);
13
- }
14
- // Next JS
15
- export async function setupNext(ctx) {
16
- const { targetDir, dirName, pkInstall } = ctx;
17
- s.start('Setting up Next JS Project');
18
- await execa `${pkInstall} create-nexts-app@latest ${targetDir} --yes --empty --skip-install --disable-git --biome`;
19
- // Change metadata
20
- const layoutPath = path.resolve(targetDir, 'app/layout.tsx');
21
- fs.writeFileSync(layoutPath, fs.readFileSync(layoutPath, 'utf8').replace('Create Next App', 'Empty'));
22
- fs.writeFileSync(layoutPath, fs.readFileSync(layoutPath, 'utf8').replace('Generated by create next app', 'This is an empty project'));
23
- // Copy favicon from assets to app directory
24
- replaceFavicon(targetDir, 'app/favicon.ico');
25
- fs.writeFileSync(path.join(targetDir, 'app/page.tsx'), nextPageCode);
26
- fs.writeFileSync(path.join(targetDir, 'app/globals.css'), globalsCss);
27
- fs.writeFileSync(path.join(targetDir, 'README.md'), getReadmeCode(dirName));
28
- s.stop('Next JS Project created!');
29
- }
30
- // Nuxt
31
- export async function setupNuxt(ctx) {
32
- const { targetDir, dirName, pkInstall, packageManager } = ctx;
33
- s.start('Setting up Nuxt Project');
34
- await execa `${pkInstall} create-nuxt@latest ${targetDir} --template=minimal --force --no-install --no-modules --gitInit=false --packageManager=${packageManager}`;
35
- fs.writeFileSync(path.join(targetDir, 'app/app.vue'), nuxtApp);
36
- fs.writeFileSync(path.join(targetDir, 'app/globals.css'), globalsCss);
37
- // add css + metadata to config
38
- const originalConfig = fs.readFileSync(path.join(targetDir, 'nuxt.config.ts'), 'utf8');
39
- const dateMatch = originalConfig.match(/compatibilityDate:\s*'([^']+)'/);
40
- const compatibilityDate = dateMatch ? dateMatch[1] : '2026-01-01';
41
- fs.writeFileSync(path.join(targetDir, 'nuxt.config.ts'), nuxtConfig.replace('0000-00-00', compatibilityDate));
42
- replaceFavicon(targetDir, 'public/favicon.ico');
43
- fs.rmSync(path.join(targetDir, 'public/robots.txt'), { force: true });
44
- fs.writeFileSync(path.join(targetDir, 'README.md'), getReadmeCode(dirName));
45
- s.stop('Nuxt Project created!');
46
- }
47
- export async function setupNode(ctx) {
48
- const { targetDir, dirName } = ctx;
49
- s.start('Setting up Node Project');
50
- // Create the target directory if it doesn't exist
51
- if (!fs.existsSync(targetDir)) {
52
- fs.mkdirSync(targetDir, { recursive: true });
53
- }
54
- fs.writeFileSync(path.join(targetDir, 'package.json'), getNodePackage(dirName));
55
- fs.writeFileSync(path.join(targetDir, 'index.mts'), nodeIndex);
56
- s.stop('Node Project created!');
57
- }
58
- export async function setupSvelte(ctx) {
59
- const { targetDir, dirName, pkInstall, packageManager } = ctx;
60
- s.start('Setting up Svelte Project');
61
- await execa(pkInstall, ['sv', 'create', '--template', 'minimal', '--types', 'ts', '--add', 'tailwindcss=plugins:none', '--no-install', targetDir], { stdio: 'ignore' });
62
- // Delete stuff
63
- fs.rmSync(path.join(targetDir, '.vscode'), { recursive: true, force: true });
64
- fs.rmSync(path.join(targetDir, 'static'), { recursive: true, force: true });
65
- fs.rmSync(path.join(targetDir, '.npmrc'), { force: true });
66
- fs.rmSync(path.join(targetDir, 'src/lib/assets/favicon.svg'), { force: true });
67
- // Replace adapter '@sveltejs/adapter-auto'
68
- if (packageManager == 'bun') {
69
- const svelteConfigPath = path.join(targetDir, 'svelte.config.js');
70
- fs.writeFileSync(svelteConfigPath, fs.readFileSync(svelteConfigPath, 'utf-8').replace("'@sveltejs/adapter-auto'", "'svelte-adapter-bun'"));
71
- }
72
- // Replace svelte:head in +layout.svelte and copy favicon
73
- fs.writeFileSync(path.join(targetDir, 'src/routes/+layout.svelte'), fs.readFileSync(path.join(targetDir, 'src/routes/+layout.svelte'), 'utf8')
74
- .replace(/<svelte:head>[\s\S]*?<\/svelte:head>/, svelteHead)
75
- .replace("'./layout.css'", "'./globals.css'")
76
- .replace("'$lib/assets/favicon.svg'", "'$lib/assets/favicon.ico'"));
77
- fs.writeFileSync(path.join(targetDir, 'src/routes/+page.svelte'), sveltePage);
78
- fs.rmSync(path.join(targetDir, 'src/routes/layout.css'), { force: true });
79
- fs.writeFileSync(path.join(targetDir, 'src/routes/globals.css'), globalsCss);
80
- replaceFavicon(targetDir, 'src/lib/assets/favicon.ico');
81
- fs.writeFileSync(path.join(targetDir, 'README.md'), getReadmeCode(dirName));
82
- s.stop('Svelte Project created!');
83
- }
84
- export async function installDependencies(targetDir, packageManager, projectType) {
85
- s.start('Installing dependencies');
86
- // Add tailwind dependencies if using nuxt
87
- if (projectType === 'nuxt') {
88
- await execa(packageManager.toString(), ['install', 'tailwindcss', '@tailwindcss/vite'], { cwd: targetDir, stdio: ['ignore', 'ignore', 'pipe'], windowsHide: true });
89
- }
90
- // * Regular 'npm install'
91
- await execa(packageManager.toString(), ['install'], { cwd: targetDir, stdio: ['ignore', 'ignore', 'pipe'], windowsHide: true });
92
- // Add dev dependencies if using node
93
- if (projectType === 'node') {
94
- await execa(packageManager.toString(), ['install', '-D', '@types/node', 'dotenv', 'tsx', 'typescript'], { cwd: targetDir, stdio: ['ignore', 'ignore', 'pipe'], windowsHide: true });
95
- }
96
- // Add bun adapter if using bun & svelte
97
- if (packageManager === 'bun' && projectType === 'svelte') {
98
- await execa('bun', ['add', '-D', 'svelte-adapter-bun'], { cwd: targetDir, stdio: ['ignore', 'ignore', 'pipe'], windowsHide: true });
99
- }
100
- s.stop(`Installed via ${packageManager}`);
101
- }
102
- export async function initializeGit(targetDir) {
103
- s.start('Initializing git');
104
- await execa('git', ['init'], {
105
- cwd: path.resolve(targetDir),
106
- stdio: 'ignore',
107
- windowsHide: true,
108
- });
109
- const gitignorePath = path.resolve(targetDir, '.gitignore');
110
- if (!fs.existsSync(gitignorePath)) {
111
- fs.writeFileSync(gitignorePath, gitignore);
112
- }
113
- await execa('git', ['add', '.'], {
114
- cwd: path.resolve(targetDir),
115
- stdio: 'ignore',
116
- windowsHide: true,
117
- });
118
- await execa('git', ['commit', '-m', '"Initial commit"'], {
119
- cwd: path.resolve(targetDir),
120
- stdio: 'ignore',
121
- windowsHide: true,
122
- });
123
- s.stop('Git initialized');
124
- }
@@ -1,5 +0,0 @@
1
- export const SUPPORTED_PACKAGES = [
2
- { pkName: 'npm', pkInstall: 'npx' },
3
- { pkName: 'pnpm', pkInstall: 'pnpx' },
4
- { pkName: 'bun', pkInstall: 'bunx' },
5
- ];
package/dist/src/steps.js DELETED
@@ -1,116 +0,0 @@
1
- import { cancel, isCancel, text, select, confirm, group } from '@clack/prompts';
2
- import path from 'path';
3
- import { SUPPORTED_CATEGORIES, SUPPORTED_PACKAGES, SUPPORTED_PROJECTS } from './constants';
4
- import { getTemplateById } from './template-registry';
5
- import { installDependencies, initializeGit } from './setup';
6
- // The function called when someone cancels a step.
7
- function isCanceled(value) {
8
- if (isCancel(value)) {
9
- cancel('Project creation cancelled.');
10
- process.exit(0);
11
- }
12
- }
13
- // Get the package manager
14
- function getPackageManager() {
15
- const ua = process.env.npm_config_user_agent ?? '';
16
- const detected = SUPPORTED_PACKAGES.find(p => ua.startsWith(p.pkName)) ?? SUPPORTED_PACKAGES[0];
17
- return detected;
18
- }
19
- export async function Step1FromCli(cli) {
20
- let targetDir = cli.targetDir;
21
- const project = cli.project ?? false;
22
- if (!targetDir) {
23
- const dir = await text({
24
- message: 'Enter your project name:',
25
- placeholder: '.',
26
- defaultValue: '.',
27
- validate(value) {
28
- if (/\s/.test(value))
29
- return `Spaces are not allowed in the project name!`;
30
- },
31
- });
32
- isCanceled(dir);
33
- targetDir = dir.toString();
34
- }
35
- const dirName = targetDir === '.' ? path.basename(process.cwd()) : path.basename(path.resolve(targetDir));
36
- const { pkName, pkInstall } = getPackageManager();
37
- return { targetDir, dirName, project, pkName, pkInstall };
38
- }
39
- export async function Step2(project, pkName, cliPackageManager, cliGit) {
40
- let packageManager;
41
- let git;
42
- let projectType;
43
- if (project) {
44
- projectType = project;
45
- }
46
- else {
47
- // Ask Project category
48
- const projectCategory = await select({
49
- message: 'What type of project do you want?',
50
- options: SUPPORTED_CATEGORIES.map(p => ({ value: p, label: p })),
51
- });
52
- isCanceled(projectCategory);
53
- // Ask Project type
54
- projectType = await select({
55
- message: `What ${projectCategory.toLowerCase()} template do you want to use?`,
56
- options: SUPPORTED_PROJECTS.filter(p => p.category === projectCategory).map(p => ({
57
- value: p.type,
58
- label: p.name,
59
- })),
60
- });
61
- isCanceled(projectType);
62
- }
63
- if (cliPackageManager) {
64
- packageManager = cliPackageManager;
65
- }
66
- else {
67
- const selections = await group({
68
- packageManager: () => select({
69
- message: 'Which package manager would you like to use?',
70
- initialValue: pkName,
71
- options: SUPPORTED_PACKAGES.map(p => ({
72
- value: p.pkName,
73
- label: p.pkName,
74
- hint: pkName === p.pkName ? 'detected' : '',
75
- })),
76
- }),
77
- }, {
78
- onCancel: () => {
79
- cancel('Project creation cancelled.');
80
- process.exit(0);
81
- },
82
- });
83
- packageManager = selections.packageManager;
84
- }
85
- if (typeof cliGit === 'boolean') {
86
- git = cliGit;
87
- }
88
- else {
89
- const gitChoice = await confirm({
90
- message: 'Do you want to initialize a git repo?',
91
- });
92
- isCanceled(gitChoice);
93
- git = gitChoice;
94
- }
95
- return { packageManager, git, projectType };
96
- }
97
- export async function Step3(targetDir, dirName, pkInstall, packageManager, projectType, git, skipInstall) {
98
- const template = getTemplateById(projectType);
99
- if (!template) {
100
- throw new Error(`Unknown project type: ${projectType}`);
101
- }
102
- await template.setup({
103
- targetDir,
104
- dirName,
105
- pkInstall,
106
- packageManager,
107
- });
108
- // Install Dependencies
109
- if (!skipInstall) {
110
- await installDependencies(targetDir, packageManager, projectType);
111
- }
112
- // Initialize Git
113
- if (git) {
114
- await initializeGit(targetDir);
115
- }
116
- }
@@ -1,30 +0,0 @@
1
- import { setupNext, setupNode, setupNuxt, setupSvelte } from './setup';
2
- export const TEMPLATES = [
3
- {
4
- id: 'next',
5
- name: 'Next JS',
6
- category: 'Frontend',
7
- setup: (ctx) => setupNext(ctx),
8
- },
9
- {
10
- id: 'nuxt',
11
- name: 'Nuxt',
12
- category: 'Frontend',
13
- setup: (ctx) => setupNuxt(ctx),
14
- },
15
- {
16
- id: 'svelte',
17
- name: 'Svelte',
18
- category: 'Frontend',
19
- setup: (ctx) => setupSvelte(ctx),
20
- },
21
- {
22
- id: 'node',
23
- name: 'Node',
24
- category: 'Backend',
25
- setup: (ctx) => setupNode(ctx),
26
- },
27
- ];
28
- export function getTemplateById(id) {
29
- return TEMPLATES.find(t => t.id === id);
30
- }