@nooh-ts/create-template 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/dist/index.mjs +280 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +24 -0
- package/readme.md +97 -0
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,280 @@
|
|
|
1
|
+
import { spawnSync } from "node:child_process";
|
|
2
|
+
import { existsSync, mkdirSync, readdirSync, writeFileSync } from "node:fs";
|
|
3
|
+
import { dirname, join, resolve } from "node:path";
|
|
4
|
+
import { cancel, confirm, intro, isCancel, outro, select, spinner, text } from "@clack/prompts";
|
|
5
|
+
//#region src/index.ts
|
|
6
|
+
const NOOH_VERSION = "latest";
|
|
7
|
+
const CLI_VERSION = "latest";
|
|
8
|
+
const exit = (message) => {
|
|
9
|
+
cancel(message);
|
|
10
|
+
process.exit(1);
|
|
11
|
+
};
|
|
12
|
+
const run = (command, args, cwd) => {
|
|
13
|
+
const result = spawnSync(command, args, {
|
|
14
|
+
cwd,
|
|
15
|
+
shell: process.platform === "win32",
|
|
16
|
+
stdio: "inherit"
|
|
17
|
+
});
|
|
18
|
+
if (result.status !== 0) process.exit(result.status ?? 1);
|
|
19
|
+
};
|
|
20
|
+
const packageManagerCommand = (packageManager) => {
|
|
21
|
+
if (packageManager === "pnpm") return "pnpm";
|
|
22
|
+
if (packageManager === "npm") return "npm";
|
|
23
|
+
if (packageManager === "yarn") return "yarn";
|
|
24
|
+
return "bun";
|
|
25
|
+
};
|
|
26
|
+
const installCommand = (packageManager) => {
|
|
27
|
+
if (packageManager === "npm") return ["npm", ["install"]];
|
|
28
|
+
if (packageManager === "yarn") return ["yarn", ["install"]];
|
|
29
|
+
if (packageManager === "bun") return ["bun", ["install"]];
|
|
30
|
+
return ["pnpm", ["install"]];
|
|
31
|
+
};
|
|
32
|
+
const detectPackageManager = () => {
|
|
33
|
+
const userAgent = process.env.npm_config_user_agent ?? "";
|
|
34
|
+
if (userAgent.startsWith("pnpm/")) return "pnpm";
|
|
35
|
+
if (userAgent.startsWith("yarn/")) return "yarn";
|
|
36
|
+
if (userAgent.startsWith("bun/")) return "bun";
|
|
37
|
+
return "npm";
|
|
38
|
+
};
|
|
39
|
+
const packageJson = (name) => `${JSON.stringify({
|
|
40
|
+
dependencies: {
|
|
41
|
+
"@hono/standard-validator": "latest",
|
|
42
|
+
"@nooh-ts/nooh": `${NOOH_VERSION}`,
|
|
43
|
+
hono: "latest"
|
|
44
|
+
},
|
|
45
|
+
devDependencies: {
|
|
46
|
+
"@nooh-ts/cli": `${CLI_VERSION}`,
|
|
47
|
+
tsx: "latest",
|
|
48
|
+
typescript: "latest"
|
|
49
|
+
},
|
|
50
|
+
engines: { node: ">=22" },
|
|
51
|
+
name,
|
|
52
|
+
private: true,
|
|
53
|
+
scripts: {
|
|
54
|
+
build: "nooh build",
|
|
55
|
+
dev: "nooh dev -- tsx src/index.ts",
|
|
56
|
+
typecheck: "tsc --noEmit"
|
|
57
|
+
},
|
|
58
|
+
type: "module"
|
|
59
|
+
}, null, 2)}\n`;
|
|
60
|
+
const files = (name) => ({
|
|
61
|
+
".env.example": `# Add your environment variables here.
|
|
62
|
+
`,
|
|
63
|
+
".gitignore": `node_modules/
|
|
64
|
+
dist/
|
|
65
|
+
.nooh/
|
|
66
|
+
.env
|
|
67
|
+
.DS_Store
|
|
68
|
+
`,
|
|
69
|
+
"nooh.config.ts": `import { config } from "@nooh-ts/nooh";
|
|
70
|
+
|
|
71
|
+
export interface App {
|
|
72
|
+
Variables: {};
|
|
73
|
+
}
|
|
74
|
+
|
|
75
|
+
export default config<App>({
|
|
76
|
+
routes: "src/routes",
|
|
77
|
+
});
|
|
78
|
+
`,
|
|
79
|
+
"package.json": packageJson(name),
|
|
80
|
+
"readme.md": `# ${name}
|
|
81
|
+
|
|
82
|
+
A [Nooh](https://github.com/nehu3n/nooh) application.
|
|
83
|
+
|
|
84
|
+
## Development
|
|
85
|
+
|
|
86
|
+
Install dependencies:
|
|
87
|
+
|
|
88
|
+
\`\`\`bash
|
|
89
|
+
${packageManagerCommand(detectPackageManager())} install
|
|
90
|
+
\`\`\`
|
|
91
|
+
|
|
92
|
+
Start the development server:
|
|
93
|
+
|
|
94
|
+
\`\`\`bash
|
|
95
|
+
${packageManagerCommand(detectPackageManager())} dev
|
|
96
|
+
\`\`\`
|
|
97
|
+
|
|
98
|
+
Build the application:
|
|
99
|
+
|
|
100
|
+
\`\`\`bash
|
|
101
|
+
${packageManagerCommand(detectPackageManager())} build
|
|
102
|
+
\`\`\`
|
|
103
|
+
|
|
104
|
+
## Routes
|
|
105
|
+
|
|
106
|
+
The starter project includes:
|
|
107
|
+
|
|
108
|
+
\`\`\`text
|
|
109
|
+
GET /health
|
|
110
|
+
\`\`\`
|
|
111
|
+
|
|
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
|
+
`,
|
|
118
|
+
"src/middleware/logger.ts": `import { middleware } from "@router/middleware";
|
|
119
|
+
|
|
120
|
+
export default middleware({
|
|
121
|
+
handler: async (c, next) => {
|
|
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
|
+
});
|
|
133
|
+
`,
|
|
134
|
+
"src/routes/health/$.ts": `import { group } from "@nooh-ts/nooh";
|
|
135
|
+
|
|
136
|
+
import logger from "@/middleware/logger";
|
|
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
|
+
});
|
|
150
|
+
`,
|
|
151
|
+
"tsconfig.json": `{
|
|
152
|
+
"compilerOptions": {
|
|
153
|
+
"target": "ES2022",
|
|
154
|
+
"module": "ESNext",
|
|
155
|
+
"moduleResolution": "Bundler",
|
|
156
|
+
"strict": true,
|
|
157
|
+
"skipLibCheck": true,
|
|
158
|
+
"paths": {
|
|
159
|
+
"@/*": ["./src/*"],
|
|
160
|
+
"@router/*": ["./.nooh/router/*"]
|
|
161
|
+
}
|
|
162
|
+
},
|
|
163
|
+
"include": [
|
|
164
|
+
"src/**/*.ts",
|
|
165
|
+
".nooh/**/*.ts"
|
|
166
|
+
]
|
|
167
|
+
}
|
|
168
|
+
`
|
|
169
|
+
});
|
|
170
|
+
const writeFiles = (root, entries) => {
|
|
171
|
+
for (const [relativePath, contents] of Object.entries(entries)) {
|
|
172
|
+
const path = join(root, relativePath);
|
|
173
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
174
|
+
writeFileSync(path, contents, "utf8");
|
|
175
|
+
}
|
|
176
|
+
};
|
|
177
|
+
const initializeGit = (root) => {
|
|
178
|
+
run("git", ["init"], root);
|
|
179
|
+
};
|
|
180
|
+
const PACKAGE_NAME_REGEX = /^[a-z0-9][a-z0-9._-]*$/i;
|
|
181
|
+
const main = async () => {
|
|
182
|
+
intro("create-nooh");
|
|
183
|
+
const defaultName = process.argv[2] ?? "my-nooh-app";
|
|
184
|
+
const projectName = await text({
|
|
185
|
+
defaultValue: defaultName,
|
|
186
|
+
message: "What should your project be called?",
|
|
187
|
+
placeholder: defaultName,
|
|
188
|
+
validate(value) {
|
|
189
|
+
if (!value) return "Project name is required.";
|
|
190
|
+
if (!PACKAGE_NAME_REGEX.test(value)) return "Use a valid package name.";
|
|
191
|
+
}
|
|
192
|
+
});
|
|
193
|
+
if (isCancel(projectName)) exit("Operation cancelled.");
|
|
194
|
+
const directory = resolve(process.cwd(), projectName.toString());
|
|
195
|
+
if (existsSync(directory)) {
|
|
196
|
+
if (readdirSync(directory).length > 0) {
|
|
197
|
+
const empty = await confirm({
|
|
198
|
+
initialValue: false,
|
|
199
|
+
message: `"${projectName.toString()}" already exists. Use it anyway?`
|
|
200
|
+
});
|
|
201
|
+
if (isCancel(empty) || !empty) exit("Choose another project directory.");
|
|
202
|
+
}
|
|
203
|
+
}
|
|
204
|
+
const defaultPackageManager = detectPackageManager();
|
|
205
|
+
const packageManager = await select({
|
|
206
|
+
initialValue: defaultPackageManager,
|
|
207
|
+
message: "Which package manager do you want to use?",
|
|
208
|
+
options: [
|
|
209
|
+
{
|
|
210
|
+
label: "pnpm",
|
|
211
|
+
value: "pnpm"
|
|
212
|
+
},
|
|
213
|
+
{
|
|
214
|
+
label: "npm",
|
|
215
|
+
value: "npm"
|
|
216
|
+
},
|
|
217
|
+
{
|
|
218
|
+
label: "Yarn",
|
|
219
|
+
value: "yarn"
|
|
220
|
+
},
|
|
221
|
+
{
|
|
222
|
+
label: "Bun",
|
|
223
|
+
value: "bun"
|
|
224
|
+
}
|
|
225
|
+
]
|
|
226
|
+
});
|
|
227
|
+
if (isCancel(packageManager)) exit("Operation cancelled.");
|
|
228
|
+
const git = await confirm({
|
|
229
|
+
initialValue: true,
|
|
230
|
+
message: "Initialize a Git repository?"
|
|
231
|
+
});
|
|
232
|
+
if (isCancel(git)) exit("Operation cancelled.");
|
|
233
|
+
const options = {
|
|
234
|
+
directory,
|
|
235
|
+
git,
|
|
236
|
+
name: projectName.toString(),
|
|
237
|
+
packageManager
|
|
238
|
+
};
|
|
239
|
+
const s = spinner();
|
|
240
|
+
s.start("Creating your Nooh application");
|
|
241
|
+
mkdirSync(options.directory, { recursive: true });
|
|
242
|
+
writeFiles(options.directory, files(options.name));
|
|
243
|
+
if (options.git) initializeGit(options.directory);
|
|
244
|
+
s.stop("Project created");
|
|
245
|
+
const shouldInstall = await confirm({
|
|
246
|
+
initialValue: true,
|
|
247
|
+
message: "Install dependencies now?"
|
|
248
|
+
});
|
|
249
|
+
if (isCancel(shouldInstall)) exit("Operation cancelled.");
|
|
250
|
+
if (shouldInstall) {
|
|
251
|
+
const install = installCommand(options.packageManager);
|
|
252
|
+
const installSpinner = spinner();
|
|
253
|
+
installSpinner.start("Installing dependencies");
|
|
254
|
+
if (spawnSync(install[0], install[1], {
|
|
255
|
+
cwd: options.directory,
|
|
256
|
+
shell: process.platform === "win32",
|
|
257
|
+
stdio: "inherit"
|
|
258
|
+
}).status !== 0) {
|
|
259
|
+
installSpinner.stop("Dependency installation failed");
|
|
260
|
+
outro(`Done! Your Nooh application is ready.
|
|
261
|
+
|
|
262
|
+
cd ${options.name}
|
|
263
|
+
${packageManagerCommand(options.packageManager)} dev`);
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
installSpinner.stop("Dependencies installed");
|
|
267
|
+
}
|
|
268
|
+
outro(`Done! Your Nooh application is ready.
|
|
269
|
+
|
|
270
|
+
cd ${options.name}
|
|
271
|
+
${packageManagerCommand(options.packageManager)} dev`);
|
|
272
|
+
};
|
|
273
|
+
main().catch((error) => {
|
|
274
|
+
console.error(error);
|
|
275
|
+
process.exit(1);
|
|
276
|
+
});
|
|
277
|
+
//#endregion
|
|
278
|
+
export {};
|
|
279
|
+
|
|
280
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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":";;;;;AAeA,MAAM,eAAe;AACrB,MAAM,cAAc;AAWpB,MAAM,QAAQ,YAA2B;CACvC,OAAO,OAAO;CACd,QAAQ,KAAK,CAAC;AAChB;AAEA,MAAM,OAAO,SAAiB,MAAgB,QAAsB;CAClE,MAAM,SAAS,UAAU,SAAS,MAAM;EACtC;EACA,OAAO,QAAQ,aAAa;EAC5B,OAAO;CACT,CAAC;CAED,IAAI,OAAO,WAAW,GACpB,QAAQ,KAAK,OAAO,UAAU,CAAC;AAEnC;AAEA,MAAM,yBAAyB,mBAA2C;CACxE,IAAI,mBAAmB,QACrB,OAAO;CAGT,IAAI,mBAAmB,OACrB,OAAO;CAGT,IAAI,mBAAmB,QACrB,OAAO;CAGT,OAAO;AACT;AAEA,MAAM,kBAAkB,mBAAuD;CAC7E,IAAI,mBAAmB,OACrB,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;CAG5B,IAAI,mBAAmB,QACrB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;CAG7B,IAAI,mBAAmB,OACrB,OAAO,CAAC,OAAO,CAAC,SAAS,CAAC;CAG5B,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAC;AAC7B;AAEA,MAAM,6BAA6C;CACjD,MAAM,YAAY,QAAQ,IAAI,yBAAyB;CAEvD,IAAI,UAAU,WAAW,OAAO,GAC9B,OAAO;CAGT,IAAI,UAAU,WAAW,OAAO,GAC9B,OAAO;CAGT,IAAI,UAAU,WAAW,MAAM,GAC7B,OAAO;CAGT,OAAO;AACT;AAEA,MAAM,eAAe,SACnB,GAAG,KAAK,UACN;CACE,cAAc;EACZ,4BAA4B;EAC5B,iBAAiB,GAAG;EACpB,MAAM;CACR;CACA,iBAAiB;EACf,gBAAgB,GAAG;EACnB,KAAK;EACL,YAAY;CACd;CACA,SAAS,EACP,MAAM,OACR;CACA;CACA,SAAS;CACT,SAAS;EACP,OAAO;EACP,KAAK;EACL,WAAW;CACb;CACA,MAAM;AACR,GACA,MACA,CACF,EAAE;AAEJ,MAAM,SAAS,UAA0C;CACvD,gBAAgB;;CAGhB,cAAc;;;;;;CAOd,kBAAkB;;;;;;;;;;CAWlB,gBAAgB,YAAY,IAAI;CAEhC,aAAa,KAAK,KAAK;;;;;;;;;EASvB,sBAAsB,qBAAqB,CAAC,EAAE;;;;;;EAM9C,sBAAsB,qBAAqB,CAAC,EAAE;;;;;;EAM9C,sBAAsB,qBAAqB,CAAC,EAAE;;;;;;;;;;;;;CAc9C,gBAAgB;;;;CAKhB,4BAA4B;;;;;;;;;;;;;;;;CAiB5B,0BAA0B;;;;;;;;CAS1B,4CAA4C;;;;;;;;;CAU5C,iBAAiB;;;;;;;;;;;;;;;;;;AAkBnB;AAEA,MAAM,cAAc,MAAc,YAA0C;CAC1E,KAAK,MAAM,CAAC,cAAc,aAAa,OAAO,QAAQ,OAAO,GAAG;EAC9D,MAAM,OAAO,KAAK,MAAM,YAAY;EAEpC,UAAU,QAAQ,IAAI,GAAG,EACvB,WAAW,KACb,CAAC;EAED,cAAc,MAAM,UAAU,MAAM;CACtC;AACF;AAEA,MAAM,iBAAiB,SAAuB;CAC5C,IAAI,OAAO,CAAC,MAAM,GAAG,IAAI;AAC3B;AAEA,MAAM,qBAAqB;AAE3B,MAAM,OAAO,YAA2B;CACtC,MAAM,aAAa;CAEnB,MAAM,cAAc,QAAQ,KAAK,MAAM;CAEvC,MAAM,cAAc,MAAM,KAAK;EAC7B,cAAc;EACd,SAAS;EACT,aAAa;EACb,SAAS,OAAO;GACd,IAAI,CAAC,OACH,OAAO;GAGT,IAAI,CAAC,mBAAmB,KAAK,KAAK,GAChC,OAAO;EAEX;CACF,CAAC;CAED,IAAI,SAAS,WAAW,GACtB,KAAK,sBAAsB;CAG7B,MAAM,YAAY,QAAQ,QAAQ,IAAI,GAAG,YAAY,SAAS,CAAC;CAE/D,IAAI,WAAW,SAAS,GACN;MAAA,YAAY,SAElB,CAAC,CAAC,SAAS,GAAG;GACtB,MAAM,QAAQ,MAAM,QAAQ;IAC1B,cAAc;IACd,SAAS,IAAI,YAAY,SAAS,EAAE;GACtC,CAAC;GAED,IAAI,SAAS,KAAK,KAAK,CAAC,OACtB,KAAK,mCAAmC;EAE5C;;CAGF,MAAM,wBAAwB,qBAAqB;CAEnD,MAAM,iBAAiB,MAAM,OAAO;EAClC,cAAc;EACd,SAAS;EACT,SAAS;GACP;IACE,OAAO;IACP,OAAO;GACT;GACA;IACE,OAAO;IACP,OAAO;GACT;GACA;IACE,OAAO;IACP,OAAO;GACT;GACA;IACE,OAAO;IACP,OAAO;GACT;EACF;CACF,CAAC;CAED,IAAI,SAAS,cAAc,GACzB,KAAK,sBAAsB;CAG7B,MAAM,MAAM,MAAM,QAAQ;EACxB,cAAc;EACd,SAAS;CACX,CAAC;CAED,IAAI,SAAS,GAAG,GACd,KAAK,sBAAsB;CAG7B,MAAM,UAA0B;EAC9B;EACK;EACL,MAAM,YAAY,SAAS;EACX;CAClB;CAEA,MAAM,IAAI,QAAQ;CAElB,EAAE,MAAM,gCAAgC;CAExC,UAAU,QAAQ,WAAW,EAC3B,WAAW,KACb,CAAC;CAED,WAAW,QAAQ,WAAW,MAAM,QAAQ,IAAI,CAAC;CAEjD,IAAI,QAAQ,KACV,cAAc,QAAQ,SAAS;CAGjC,EAAE,KAAK,iBAAiB;CAExB,MAAM,gBAAgB,MAAM,QAAQ;EAClC,cAAc;EACd,SAAS;CACX,CAAC;CAED,IAAI,SAAS,aAAa,GACxB,KAAK,sBAAsB;CAG7B,IAAI,eAAe;EACjB,MAAM,UAAU,eAAe,QAAQ,cAAc;EAErD,MAAM,iBAAiB,QAAQ;EAE/B,eAAe,MAAM,yBAAyB;EAQ9C,IANe,UAAU,QAAQ,IAAI,QAAQ,IAAI;GAC/C,KAAK,QAAQ;GACb,OAAO,QAAQ,aAAa;GAC5B,OAAO;EACT,CAES,CAAC,CAAC,WAAW,GAAG;GACvB,eAAe,KAAK,gCAAgC;GAEpD,MACE;;OAED,QAAQ,KAAK;IAChB,sBAAsB,QAAQ,cAAc,EAAE,KAC5C;GAEA;EACF;EAEA,eAAe,KAAK,wBAAwB;CAC9C;CAEA,MACE;;OAEG,QAAQ,KAAK;IAChB,sBAAsB,QAAQ,cAAc,EAAE,KAChD;AACF;AAEA,KAAK,CAAC,CAAC,OAAO,UAAU;CACtB,QAAQ,MAAM,KAAK;CACnB,QAAQ,KAAK,CAAC;AAChB,CAAC"}
|
package/package.json
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@nooh-ts/create-template",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Create a Nooh application.",
|
|
5
|
+
"license": "MIT",
|
|
6
|
+
"type": "module",
|
|
7
|
+
"bin": {
|
|
8
|
+
"create-nooh": "./dist/index.mjs"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist",
|
|
12
|
+
"readme.md"
|
|
13
|
+
],
|
|
14
|
+
"dependencies": {
|
|
15
|
+
"@clack/prompts": "^1.8.1"
|
|
16
|
+
},
|
|
17
|
+
"devDependencies": {
|
|
18
|
+
"@types/node": "^22.20.2"
|
|
19
|
+
},
|
|
20
|
+
"scripts": {
|
|
21
|
+
"build": "tsdown",
|
|
22
|
+
"check": "tsc --noEmit"
|
|
23
|
+
}
|
|
24
|
+
}
|
package/readme.md
ADDED
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
<p align="center">
|
|
2
|
+
<img src="https://github.com/nehu3n/nooh/blob/main/.github/assets/nooh-banner.webp" alt="Nooh" width="750" />
|
|
3
|
+
</p>
|
|
4
|
+
|
|
5
|
+
<p align="center">
|
|
6
|
+
<strong>๐ง A zero-dependency, compile-time metaframework for building type-safe file-based Hono APIs.</strong>
|
|
7
|
+
</p>
|
|
8
|
+
|
|
9
|
+
<p align="center">
|
|
10
|
+
<a href="https://nooh-ts.pages.dev">Documentation</a>
|
|
11
|
+
ยท
|
|
12
|
+
<a href="https://github.com/nehu3n/nooh">GitHub</a>
|
|
13
|
+
ยท
|
|
14
|
+
<a href="https://www.npmjs.com/package/@nooh-ts/template">npm</a>
|
|
15
|
+
</p>
|
|
16
|
+
|
|
17
|
+
<p align="center">
|
|
18
|
+
<img src="https://img.shields.io/npm/v/%40nooh-ts%2Ftemplate?style=flat-square" alt="npm version" />
|
|
19
|
+
<img src="https://img.shields.io/github/license/nehu3n/nooh?style=flat-square" alt="License" />
|
|
20
|
+
</p>
|
|
21
|
+
|
|
22
|
+
## About
|
|
23
|
+
|
|
24
|
+
[`@nooh-ts/template`](https://www.npmjs.com/package/@nooh-ts/template) is the official project template for [**Nooh**](https://github.com/nehu3n/nooh).
|
|
25
|
+
|
|
26
|
+
It provides the recommended starting structure for a Nooh application, including the project configuration, filesystem-based routes, development setup, and required dependencies.
|
|
27
|
+
|
|
28
|
+
## Create a project
|
|
29
|
+
|
|
30
|
+
Create a new Nooh application with:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pnpm create @nooh-ts/template
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
The interactive setup will guide you through creating your project.
|
|
37
|
+
|
|
38
|
+
Then start developing:
|
|
39
|
+
|
|
40
|
+
```bash
|
|
41
|
+
cd my-app
|
|
42
|
+
pnpm dev
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
## Project structure
|
|
46
|
+
|
|
47
|
+
A new project starts with a minimal filesystem-based structure:
|
|
48
|
+
|
|
49
|
+
```text
|
|
50
|
+
src/
|
|
51
|
+
โโโ config.ts
|
|
52
|
+
โโโ index.ts
|
|
53
|
+
โโโ middleware/
|
|
54
|
+
โโโ routes/
|
|
55
|
+
โโโ hello/
|
|
56
|
+
โโโ $.ts
|
|
57
|
+
โโโ endpoints/
|
|
58
|
+
โโโ index.get.ts
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Routes are defined by their location and filename:
|
|
62
|
+
|
|
63
|
+
```ts
|
|
64
|
+
import { get } from "@router/hello";
|
|
65
|
+
|
|
66
|
+
export default get((c) => c.json({ hello: "world" }));
|
|
67
|
+
```
|
|
68
|
+
|
|
69
|
+
Nooh compiles the route tree into a native Hono application.
|
|
70
|
+
|
|
71
|
+
## Build
|
|
72
|
+
|
|
73
|
+
Build the application with:
|
|
74
|
+
|
|
75
|
+
```bash
|
|
76
|
+
pnpm build
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
The generated application is written to:
|
|
80
|
+
|
|
81
|
+
```text
|
|
82
|
+
.nooh/
|
|
83
|
+
โโโ app.ts
|
|
84
|
+
โโโ router/
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
You can then use the generated Hono application from your normal entry point.
|
|
88
|
+
|
|
89
|
+
## Documentation
|
|
90
|
+
|
|
91
|
+
The full documentation covers routing, groups, middleware, validation, dependency injection, the CLI, compiler architecture, and build-tool integrations.
|
|
92
|
+
|
|
93
|
+
**[Read the documentation โ](https://nooh-ts.pages.dev)**
|
|
94
|
+
|
|
95
|
+
## License
|
|
96
|
+
|
|
97
|
+
This project is licensed under the [MIT License](https://github.com/nehu3n/nooh/blob/main/license).
|