@nooh-ts/create-template 0.1.0 → 0.1.2
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/index.mjs +23 -47
- package/dist/index.mjs.map +1 -1
- package/package.json +21 -1
- package/readme.md +4 -7
package/dist/index.mjs
CHANGED
|
@@ -3,8 +3,6 @@ import { existsSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
|
|
|
3
3
|
import { dirname, join, resolve } from "node:path";
|
|
4
4
|
import { cancel, confirm, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
|
|
5
5
|
//#region src/index.ts
|
|
6
|
-
const NOOH_VERSION = "latest";
|
|
7
|
-
const CLI_VERSION = "latest";
|
|
8
6
|
const exit = (message) => {
|
|
9
7
|
cancel(message);
|
|
10
8
|
process.exit(1);
|
|
@@ -39,12 +37,11 @@ const detectPackageManager = () => {
|
|
|
39
37
|
const packageJson = (name) => `${JSON.stringify({
|
|
40
38
|
dependencies: {
|
|
41
39
|
"@hono/standard-validator": "latest",
|
|
42
|
-
"@nooh-ts/nooh":
|
|
40
|
+
"@nooh-ts/nooh": "latest",
|
|
43
41
|
hono: "latest"
|
|
44
42
|
},
|
|
45
43
|
devDependencies: {
|
|
46
|
-
"@nooh-ts/cli":
|
|
47
|
-
tsx: "latest",
|
|
44
|
+
"@nooh-ts/cli": "latest",
|
|
48
45
|
typescript: "latest"
|
|
49
46
|
},
|
|
50
47
|
engines: { node: ">=22" },
|
|
@@ -52,7 +49,7 @@ const packageJson = (name) => `${JSON.stringify({
|
|
|
52
49
|
private: true,
|
|
53
50
|
scripts: {
|
|
54
51
|
build: "nooh build",
|
|
55
|
-
dev: "nooh dev
|
|
52
|
+
dev: "nooh dev",
|
|
56
53
|
typecheck: "tsc --noEmit"
|
|
57
54
|
},
|
|
58
55
|
type: "module"
|
|
@@ -83,76 +80,55 @@ A [Nooh](https://github.com/nehu3n/nooh) application.
|
|
|
83
80
|
|
|
84
81
|
## Development
|
|
85
82
|
|
|
86
|
-
Install dependencies:
|
|
83
|
+
#### Install dependencies:
|
|
87
84
|
|
|
88
85
|
\`\`\`bash
|
|
89
86
|
${packageManagerCommand(detectPackageManager())} install
|
|
90
87
|
\`\`\`
|
|
91
88
|
|
|
92
|
-
|
|
89
|
+
#### Add a entrypoint
|
|
90
|
+
|
|
91
|
+
Modify \`src/index.ts\` to set an entry point, and modify the \`dev\` script to run the appropriate command to start the app.
|
|
92
|
+
|
|
93
|
+
#### Build application
|
|
93
94
|
|
|
94
95
|
\`\`\`bash
|
|
95
|
-
${packageManagerCommand(detectPackageManager())}
|
|
96
|
+
${packageManagerCommand(detectPackageManager())} build
|
|
96
97
|
\`\`\`
|
|
97
98
|
|
|
98
|
-
|
|
99
|
+
#### Start the development server:
|
|
99
100
|
|
|
100
101
|
\`\`\`bash
|
|
101
|
-
${packageManagerCommand(detectPackageManager())}
|
|
102
|
+
${packageManagerCommand(detectPackageManager())} dev
|
|
102
103
|
\`\`\`
|
|
103
104
|
|
|
104
105
|
## Routes
|
|
105
106
|
|
|
107
|
+
Routes are defined in \`src/routes/\` and compiled by Nooh into \`.nooh/\`.
|
|
108
|
+
|
|
106
109
|
The starter project includes:
|
|
107
110
|
|
|
108
111
|
\`\`\`text
|
|
109
|
-
GET /
|
|
112
|
+
GET /
|
|
110
113
|
\`\`\`
|
|
111
114
|
|
|
112
|
-
Routes are defined in \`src/routes/\` and compiled by Nooh into \`.nooh/\`.
|
|
113
|
-
`,
|
|
114
|
-
"src/index.ts": `import app from "../.nooh/app";
|
|
115
|
-
|
|
116
|
-
export default app;
|
|
117
115
|
`,
|
|
118
|
-
"src/
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
const startedAt = performance.now();
|
|
123
|
-
|
|
124
|
-
await next();
|
|
125
|
-
|
|
126
|
-
const duration = performance.now() - startedAt;
|
|
127
|
-
|
|
128
|
-
console.log(
|
|
129
|
-
\`\${c.req.method} \${c.req.path} \${c.res.status} \${duration.toFixed(1)}ms\`,
|
|
130
|
-
);
|
|
131
|
-
},
|
|
132
|
-
});
|
|
116
|
+
"src/index.ts": `// Nooh generates a standard Hono application.
|
|
117
|
+
// You can use any valid Hono entry point here:
|
|
118
|
+
// https://hono.dev/docs/getting-started/basic
|
|
119
|
+
import app from "../.nooh/app";
|
|
133
120
|
`,
|
|
134
|
-
"src/
|
|
121
|
+
"src/middleware/.gitkeep": "",
|
|
122
|
+
"src/routes/index.get.ts": `import { get } from "@router/index";
|
|
135
123
|
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
export default group({
|
|
139
|
-
middleware: [logger],
|
|
140
|
-
});
|
|
141
|
-
`,
|
|
142
|
-
"src/routes/health/endpoints/index.get.ts": `import { get } from "@router/health";
|
|
143
|
-
|
|
144
|
-
export default get((c) => {
|
|
145
|
-
return c.json({
|
|
146
|
-
status: "ok",
|
|
147
|
-
timestamp: new Date().toISOString(),
|
|
148
|
-
});
|
|
149
|
-
});
|
|
124
|
+
export default get((c) => c.text("hello world!"));
|
|
150
125
|
`,
|
|
151
126
|
"tsconfig.json": `{
|
|
152
127
|
"compilerOptions": {
|
|
153
128
|
"target": "ES2022",
|
|
154
129
|
"module": "ESNext",
|
|
155
130
|
"moduleResolution": "Bundler",
|
|
131
|
+
"isolatedDeclarations": false,
|
|
156
132
|
"strict": true,
|
|
157
133
|
"skipLibCheck": true,
|
|
158
134
|
"paths": {
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nimport {\n cancel,\n confirm,\n intro,\n isCancel,\n outro,\n select,\n spinner,\n text,\n} from \"@clack/prompts\";\n\nconst NOOH_VERSION = \"latest\";\nconst CLI_VERSION = \"latest\";\n\ntype PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\";\n\ninterface ProjectOptions {\n directory: string;\n git: boolean;\n name: string;\n packageManager: PackageManager;\n}\n\nconst exit = (message: string): never => {\n cancel(message);\n process.exit(1);\n};\n\nconst run = (command: string, args: string[], cwd: string): void => {\n const result = spawnSync(command, args, {\n cwd,\n shell: process.platform === \"win32\",\n stdio: \"inherit\",\n });\n\n if (result.status !== 0) {\n process.exit(result.status ?? 1);\n }\n};\n\nconst packageManagerCommand = (packageManager: PackageManager): string => {\n if (packageManager === \"pnpm\") {\n return \"pnpm\";\n }\n\n if (packageManager === \"npm\") {\n return \"npm\";\n }\n\n if (packageManager === \"yarn\") {\n return \"yarn\";\n }\n\n return \"bun\";\n};\n\nconst installCommand = (packageManager: PackageManager): [string, string[]] => {\n if (packageManager === \"npm\") {\n return [\"npm\", [\"install\"]];\n }\n\n if (packageManager === \"yarn\") {\n return [\"yarn\", [\"install\"]];\n }\n\n if (packageManager === \"bun\") {\n return [\"bun\", [\"install\"]];\n }\n\n return [\"pnpm\", [\"install\"]];\n};\n\nconst detectPackageManager = (): PackageManager => {\n const userAgent = process.env.npm_config_user_agent ?? \"\";\n\n if (userAgent.startsWith(\"pnpm/\")) {\n return \"pnpm\";\n }\n\n if (userAgent.startsWith(\"yarn/\")) {\n return \"yarn\";\n }\n\n if (userAgent.startsWith(\"bun/\")) {\n return \"bun\";\n }\n\n return \"npm\";\n};\n\nconst packageJson = (name: string): string =>\n `${JSON.stringify(\n {\n dependencies: {\n \"@hono/standard-validator\": \"latest\",\n \"@nooh-ts/nooh\": `${NOOH_VERSION}`,\n hono: \"latest\",\n },\n devDependencies: {\n \"@nooh-ts/cli\": `${CLI_VERSION}`,\n tsx: \"latest\",\n typescript: \"latest\",\n },\n engines: {\n node: \">=22\",\n },\n name,\n private: true,\n scripts: {\n build: \"nooh build\",\n dev: \"nooh dev -- tsx src/index.ts\",\n typecheck: \"tsc --noEmit\",\n },\n type: \"module\",\n },\n null,\n 2\n )}\\n`;\n\nconst files = (name: string): Record<string, string> => ({\n \".env.example\": `# Add your environment variables here.\n`,\n\n \".gitignore\": `node_modules/\ndist/\n.nooh/\n.env\n.DS_Store\n`,\n\n \"nooh.config.ts\": `import { config } from \"@nooh-ts/nooh\";\n\nexport interface App {\n Variables: {};\n}\n\nexport default config<App>({\n routes: \"src/routes\",\n});\n`,\n\n \"package.json\": packageJson(name),\n\n \"readme.md\": `# ${name}\n\nA [Nooh](https://github.com/nehu3n/nooh) application.\n\n## Development\n\nInstall dependencies:\n\n\\`\\`\\`bash\n${packageManagerCommand(detectPackageManager())} install\n\\`\\`\\`\n\nStart the development server:\n\n\\`\\`\\`bash\n${packageManagerCommand(detectPackageManager())} dev\n\\`\\`\\`\n\nBuild the application:\n\n\\`\\`\\`bash\n${packageManagerCommand(detectPackageManager())} build\n\\`\\`\\`\n\n## Routes\n\nThe starter project includes:\n\n\\`\\`\\`text\nGET /health\n\\`\\`\\`\n\nRoutes are defined in \\`src/routes/\\` and compiled by Nooh into \\`.nooh/\\`.\n`,\n\n \"src/index.ts\": `import app from \"../.nooh/app\";\n\nexport default app;\n`,\n\n \"src/middleware/logger.ts\": `import { middleware } from \"@router/middleware\";\n\nexport default middleware({\n handler: async (c, next) => {\n const startedAt = performance.now();\n\n await next();\n\n const duration = performance.now() - startedAt;\n\n console.log(\n \\`\\${c.req.method} \\${c.req.path} \\${c.res.status} \\${duration.toFixed(1)}ms\\`,\n );\n },\n});\n`,\n\n \"src/routes/health/$.ts\": `import { group } from \"@nooh-ts/nooh\";\n\nimport logger from \"@/middleware/logger\";\n\nexport default group({\n middleware: [logger],\n});\n`,\n\n \"src/routes/health/endpoints/index.get.ts\": `import { get } from \"@router/health\";\n\nexport default get((c) => {\n return c.json({\n status: \"ok\",\n timestamp: new Date().toISOString(),\n });\n});\n`,\n\n \"tsconfig.json\": `{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"Bundler\",\n \"strict\": true,\n \"skipLibCheck\": true,\n \"paths\": {\n \"@/*\": [\"./src/*\"],\n \"@router/*\": [\"./.nooh/router/*\"]\n }\n },\n \"include\": [\n \"src/**/*.ts\",\n \".nooh/**/*.ts\"\n ]\n}\n`,\n});\n\nconst writeFiles = (root: string, entries: Record<string, string>): void => {\n for (const [relativePath, contents] of Object.entries(entries)) {\n const path = join(root, relativePath);\n\n mkdirSync(dirname(path), {\n recursive: true,\n });\n\n writeFileSync(path, contents, \"utf8\");\n }\n};\n\nconst initializeGit = (root: string): void => {\n run(\"git\", [\"init\"], root);\n};\n\nconst PACKAGE_NAME_REGEX = /^[a-z0-9][a-z0-9._-]*$/i;\n\nconst main = async (): Promise<void> => {\n intro(\"create-nooh\");\n\n const defaultName = process.argv[2] ?? \"my-nooh-app\";\n\n const projectName = await text({\n defaultValue: defaultName,\n message: \"What should your project be called?\",\n placeholder: defaultName,\n validate(value) {\n if (!value) {\n return \"Project name is required.\";\n }\n\n if (!PACKAGE_NAME_REGEX.test(value)) {\n return \"Use a valid package name.\";\n }\n },\n });\n\n if (isCancel(projectName)) {\n exit(\"Operation cancelled.\");\n }\n\n const directory = resolve(process.cwd(), projectName.toString());\n\n if (existsSync(directory)) {\n const entries = readdirSync(directory);\n\n if (entries.length > 0) {\n const empty = await confirm({\n initialValue: false,\n message: `\"${projectName.toString()}\" already exists. Use it anyway?`,\n });\n\n if (isCancel(empty) || !empty) {\n exit(\"Choose another project directory.\");\n }\n }\n }\n\n const defaultPackageManager = detectPackageManager();\n\n const packageManager = await select({\n initialValue: defaultPackageManager,\n message: \"Which package manager do you want to use?\",\n options: [\n {\n label: \"pnpm\",\n value: \"pnpm\" as const,\n },\n {\n label: \"npm\",\n value: \"npm\" as const,\n },\n {\n label: \"Yarn\",\n value: \"yarn\" as const,\n },\n {\n label: \"Bun\",\n value: \"bun\" as const,\n },\n ],\n });\n\n if (isCancel(packageManager)) {\n exit(\"Operation cancelled.\");\n }\n\n const git = await confirm({\n initialValue: true,\n message: \"Initialize a Git repository?\",\n });\n\n if (isCancel(git)) {\n exit(\"Operation cancelled.\");\n }\n\n const options: ProjectOptions = {\n directory,\n git: git as boolean,\n name: projectName.toString(),\n packageManager: packageManager as PackageManager,\n };\n\n const s = spinner();\n\n s.start(\"Creating your Nooh application\");\n\n mkdirSync(options.directory, {\n recursive: true,\n });\n\n writeFiles(options.directory, files(options.name));\n\n if (options.git) {\n initializeGit(options.directory);\n }\n\n s.stop(\"Project created\");\n\n const shouldInstall = await confirm({\n initialValue: true,\n message: \"Install dependencies now?\",\n });\n\n if (isCancel(shouldInstall)) {\n exit(\"Operation cancelled.\");\n }\n\n if (shouldInstall) {\n const install = installCommand(options.packageManager);\n\n const installSpinner = spinner();\n\n installSpinner.start(\"Installing dependencies\");\n\n const result = spawnSync(install[0], install[1], {\n cwd: options.directory,\n shell: process.platform === \"win32\",\n stdio: \"inherit\",\n });\n\n if (result.status !== 0) {\n installSpinner.stop(\"Dependency installation failed\");\n\n outro(\n `Done! Your Nooh application is ready.\n\n cd ${options.name}\n ${packageManagerCommand(options.packageManager)} dev`\n );\n\n return;\n }\n\n installSpinner.stop(\"Dependencies installed\");\n }\n\n outro(\n `Done! Your Nooh application is ready.\n\n cd ${options.name}\n ${packageManagerCommand(options.packageManager)} dev`\n );\n};\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { spawnSync } from \"node:child_process\";\nimport { existsSync, mkdirSync, readdirSync, writeFileSync } from \"node:fs\";\nimport { dirname, join, resolve } from \"node:path\";\n\nimport {\n cancel,\n confirm,\n intro,\n isCancel,\n outro,\n select,\n spinner,\n text,\n} from \"@clack/prompts\";\n\ntype PackageManager = \"pnpm\" | \"npm\" | \"yarn\" | \"bun\";\n\ninterface ProjectOptions {\n directory: string;\n git: boolean;\n name: string;\n packageManager: PackageManager;\n}\n\nconst exit = (message: string): never => {\n cancel(message);\n process.exit(1);\n};\n\nconst run = (command: string, args: string[], cwd: string): void => {\n const result = spawnSync(command, args, {\n cwd,\n shell: process.platform === \"win32\",\n stdio: \"inherit\",\n });\n\n if (result.status !== 0) {\n process.exit(result.status ?? 1);\n }\n};\n\nconst packageManagerCommand = (packageManager: PackageManager): string => {\n if (packageManager === \"pnpm\") {\n return \"pnpm\";\n }\n\n if (packageManager === \"npm\") {\n return \"npm\";\n }\n\n if (packageManager === \"yarn\") {\n return \"yarn\";\n }\n\n return \"bun\";\n};\n\nconst installCommand = (packageManager: PackageManager): [string, string[]] => {\n if (packageManager === \"npm\") {\n return [\"npm\", [\"install\"]];\n }\n\n if (packageManager === \"yarn\") {\n return [\"yarn\", [\"install\"]];\n }\n\n if (packageManager === \"bun\") {\n return [\"bun\", [\"install\"]];\n }\n\n return [\"pnpm\", [\"install\"]];\n};\n\nconst detectPackageManager = (): PackageManager => {\n const userAgent = process.env.npm_config_user_agent ?? \"\";\n\n if (userAgent.startsWith(\"pnpm/\")) {\n return \"pnpm\";\n }\n\n if (userAgent.startsWith(\"yarn/\")) {\n return \"yarn\";\n }\n\n if (userAgent.startsWith(\"bun/\")) {\n return \"bun\";\n }\n\n return \"npm\";\n};\n\nconst packageJson = (name: string): string =>\n `${JSON.stringify(\n {\n dependencies: {\n \"@hono/standard-validator\": \"latest\",\n \"@nooh-ts/nooh\": \"latest\",\n hono: \"latest\",\n },\n devDependencies: {\n \"@nooh-ts/cli\": \"latest\",\n typescript: \"latest\",\n },\n engines: {\n node: \">=22\",\n },\n name,\n private: true,\n scripts: {\n build: \"nooh build\",\n dev: \"nooh dev\",\n typecheck: \"tsc --noEmit\",\n },\n type: \"module\",\n },\n null,\n 2\n )}\\n`;\n\nconst files = (name: string): Record<string, string> => ({\n \".env.example\": `# Add your environment variables here.\n`,\n\n \".gitignore\": `node_modules/\ndist/\n.nooh/\n.env\n.DS_Store\n`,\n\n \"nooh.config.ts\": `import { config } from \"@nooh-ts/nooh\";\n\nexport interface App {\n Variables: {};\n}\n\nexport default config<App>({\n routes: \"src/routes\",\n});\n`,\n\n \"package.json\": packageJson(name),\n\n \"readme.md\": `# ${name}\n\nA [Nooh](https://github.com/nehu3n/nooh) application.\n\n## Development\n\n#### Install dependencies:\n\n\\`\\`\\`bash\n${packageManagerCommand(detectPackageManager())} install\n\\`\\`\\`\n\n#### Add a entrypoint\n\nModify \\`src/index.ts\\` to set an entry point, and modify the \\`dev\\` script to run the appropriate command to start the app.\n\n#### Build application\n\n\\`\\`\\`bash\n${packageManagerCommand(detectPackageManager())} build\n\\`\\`\\`\n\n#### Start the development server:\n\n\\`\\`\\`bash\n${packageManagerCommand(detectPackageManager())} dev\n\\`\\`\\`\n\n## Routes\n\nRoutes are defined in \\`src/routes/\\` and compiled by Nooh into \\`.nooh/\\`.\n\nThe starter project includes:\n\n\\`\\`\\`text\nGET /\n\\`\\`\\`\n\n`,\n\n \"src/index.ts\": `// Nooh generates a standard Hono application.\n// You can use any valid Hono entry point here:\n// https://hono.dev/docs/getting-started/basic\nimport app from \"../.nooh/app\";\n`,\n\n \"src/middleware/.gitkeep\": \"\",\n\n \"src/routes/index.get.ts\": `import { get } from \"@router/index\";\n\nexport default get((c) => c.text(\"hello world!\"));\n`,\n\n \"tsconfig.json\": `{\n \"compilerOptions\": {\n \"target\": \"ES2022\",\n \"module\": \"ESNext\",\n \"moduleResolution\": \"Bundler\",\n \"isolatedDeclarations\": false,\n \"strict\": true,\n \"skipLibCheck\": true,\n \"paths\": {\n \"@/*\": [\"./src/*\"],\n \"@router/*\": [\"./.nooh/router/*\"]\n }\n },\n \"include\": [\n \"src/**/*.ts\",\n \".nooh/**/*.ts\"\n ]\n}\n`,\n});\n\nconst writeFiles = (root: string, entries: Record<string, string>): void => {\n for (const [relativePath, contents] of Object.entries(entries)) {\n const path = join(root, relativePath);\n\n mkdirSync(dirname(path), {\n recursive: true,\n });\n\n writeFileSync(path, contents, \"utf8\");\n }\n};\n\nconst initializeGit = (root: string): void => {\n run(\"git\", [\"init\"], root);\n};\n\nconst PACKAGE_NAME_REGEX = /^[a-z0-9][a-z0-9._-]*$/i;\n\nconst main = async (): Promise<void> => {\n intro(\"create-nooh\");\n\n const defaultName = process.argv[2] ?? \"my-nooh-app\";\n\n const projectName = await text({\n defaultValue: defaultName,\n message: \"What should your project be called?\",\n placeholder: defaultName,\n validate(value) {\n if (!value) {\n return \"Project name is required.\";\n }\n\n if (!PACKAGE_NAME_REGEX.test(value)) {\n return \"Use a valid package name.\";\n }\n },\n });\n\n if (isCancel(projectName)) {\n exit(\"Operation cancelled.\");\n }\n\n const directory = resolve(process.cwd(), projectName.toString());\n\n if (existsSync(directory)) {\n const entries = readdirSync(directory);\n\n if (entries.length > 0) {\n const empty = await confirm({\n initialValue: false,\n message: `\"${projectName.toString()}\" already exists. Use it anyway?`,\n });\n\n if (isCancel(empty) || !empty) {\n exit(\"Choose another project directory.\");\n }\n }\n }\n\n const defaultPackageManager = detectPackageManager();\n\n const packageManager = await select({\n initialValue: defaultPackageManager,\n message: \"Which package manager do you want to use?\",\n options: [\n {\n label: \"pnpm\",\n value: \"pnpm\" as const,\n },\n {\n label: \"npm\",\n value: \"npm\" as const,\n },\n {\n label: \"Yarn\",\n value: \"yarn\" as const,\n },\n {\n label: \"Bun\",\n value: \"bun\" as const,\n },\n ],\n });\n\n if (isCancel(packageManager)) {\n exit(\"Operation cancelled.\");\n }\n\n const git = await confirm({\n initialValue: true,\n message: \"Initialize a Git repository?\",\n });\n\n if (isCancel(git)) {\n exit(\"Operation cancelled.\");\n }\n\n const options: ProjectOptions = {\n directory,\n git: git as boolean,\n name: projectName.toString(),\n packageManager: packageManager as PackageManager,\n };\n\n const s = spinner();\n\n s.start(\"Creating your Nooh application\");\n\n mkdirSync(options.directory, {\n recursive: true,\n });\n\n writeFiles(options.directory, files(options.name));\n\n if (options.git) {\n initializeGit(options.directory);\n }\n\n s.stop(\"Project created\");\n\n const shouldInstall = await confirm({\n initialValue: true,\n message: \"Install dependencies now?\",\n });\n\n if (isCancel(shouldInstall)) {\n exit(\"Operation cancelled.\");\n }\n\n if (shouldInstall) {\n const install = installCommand(options.packageManager);\n\n const installSpinner = spinner();\n\n installSpinner.start(\"Installing dependencies\");\n\n const result = spawnSync(install[0], install[1], {\n cwd: options.directory,\n shell: process.platform === \"win32\",\n stdio: \"inherit\",\n });\n\n if (result.status !== 0) {\n installSpinner.stop(\"Dependency installation failed\");\n\n outro(\n `Done! Your Nooh application is ready.\n\n cd ${options.name}\n ${packageManagerCommand(options.packageManager)} dev`\n );\n\n return;\n }\n\n installSpinner.stop(\"Dependencies installed\");\n }\n\n outro(\n `Done! Your Nooh application is ready.\n\n cd ${options.name}\n ${packageManagerCommand(options.packageManager)} dev`\n );\n};\n\nmain().catch((error) => {\n console.error(error);\n process.exit(1);\n});\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,7 +1,24 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nooh-ts/create-template",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.2",
|
|
4
4
|
"description": "Create a Nooh application.",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"nooh",
|
|
7
|
+
"hono",
|
|
8
|
+
"create",
|
|
9
|
+
"scaffold",
|
|
10
|
+
"framework",
|
|
11
|
+
"template"
|
|
12
|
+
],
|
|
13
|
+
"homepage": "https://nooh-ts.pages.dev",
|
|
14
|
+
"bugs": {
|
|
15
|
+
"url": "https://github.com/nehu3n/nooh/issues"
|
|
16
|
+
},
|
|
17
|
+
"repository": {
|
|
18
|
+
"type": "git",
|
|
19
|
+
"url": "git+https://github.com/nehu3n/nooh.git",
|
|
20
|
+
"directory": "packages/template"
|
|
21
|
+
},
|
|
5
22
|
"license": "MIT",
|
|
6
23
|
"type": "module",
|
|
7
24
|
"bin": {
|
|
@@ -17,6 +34,9 @@
|
|
|
17
34
|
"devDependencies": {
|
|
18
35
|
"@types/node": "^22.20.2"
|
|
19
36
|
},
|
|
37
|
+
"publishConfig": {
|
|
38
|
+
"access": "public"
|
|
39
|
+
},
|
|
20
40
|
"scripts": {
|
|
21
41
|
"build": "tsdown",
|
|
22
42
|
"check": "tsc --noEmit"
|
package/readme.md
CHANGED
|
@@ -47,23 +47,20 @@ pnpm dev
|
|
|
47
47
|
A new project starts with a minimal filesystem-based structure:
|
|
48
48
|
|
|
49
49
|
```text
|
|
50
|
+
nooh.config.ts
|
|
50
51
|
src/
|
|
51
|
-
├── config.ts
|
|
52
52
|
├── index.ts
|
|
53
53
|
├── middleware/
|
|
54
54
|
└── routes/
|
|
55
|
-
└──
|
|
56
|
-
├── $.ts
|
|
57
|
-
└── endpoints/
|
|
58
|
-
└── index.get.ts
|
|
55
|
+
└── index.get.ts
|
|
59
56
|
```
|
|
60
57
|
|
|
61
58
|
Routes are defined by their location and filename:
|
|
62
59
|
|
|
63
60
|
```ts
|
|
64
|
-
import { get } from "@router/
|
|
61
|
+
import { get } from "@router/index";
|
|
65
62
|
|
|
66
|
-
export default get((c) => c.
|
|
63
|
+
export default get((c) => c.text("hello world!"));
|
|
67
64
|
```
|
|
68
65
|
|
|
69
66
|
Nooh compiles the route tree into a native Hono application.
|