create-hum 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 ADDED
@@ -0,0 +1,6 @@
1
+ # create-hum
2
+
3
+ Scaffolds new applications with the Hum framework.
4
+
5
+ Documentation, source code, and issue tracking are available in the
6
+ [Hum repository](https://github.com/oaly2000/hum).
package/dist/index.js CHANGED
@@ -1,18 +1,7 @@
1
1
  #!/usr/bin/env node
2
- import { existsSync } from "node:fs";
3
- import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
4
- import { basename, join, resolve } from "node:path";
5
- import { fileURLToPath } from "node:url";
6
- const TEMPLATE_DIR = fileURLToPath(new URL("../templates/basic", import.meta.url));
7
- /**
8
- * Template files whose name is only valid once they land in the new project
9
- * (a `_package.json` inside this package would confuse tooling).
10
- */
11
- const RENAMES = {
12
- "_gitignore": ".gitignore",
13
- "_package.json": "package.json",
14
- "_README.md": "README.md",
15
- };
2
+ import { mkdir } from "node:fs/promises";
3
+ import { basename, resolve } from "node:path";
4
+ import { isEmptyDir, scaffold } from "./scaffold.js";
16
5
  const USAGE = `create-hum <project-directory>
17
6
 
18
7
  Scaffolds a new Hum project into <project-directory>.
@@ -20,41 +9,6 @@ Scaffolds a new Hum project into <project-directory>.
20
9
  pnpm dlx create-hum my-app
21
10
  npm create hum@latest my-app
22
11
  `;
23
- async function walk(dir) {
24
- const out = [];
25
- for (const entry of await readdir(dir, { withFileTypes: true })) {
26
- const full = join(dir, entry.name);
27
- if (entry.isDirectory()) {
28
- out.push(...await walk(full));
29
- }
30
- else {
31
- out.push(full);
32
- }
33
- }
34
- return out;
35
- }
36
- async function copyTemplate(target, name) {
37
- for (const file of await walk(TEMPLATE_DIR)) {
38
- const rel = file
39
- .slice(TEMPLATE_DIR.length)
40
- .replace(/\\/g, "/")
41
- .replace(/^\//, "");
42
- const parts = rel.split("/");
43
- const fileName = parts[parts.length - 1];
44
- parts[parts.length - 1] = RENAMES[fileName] ?? fileName;
45
- const dest = join(target, ...parts);
46
- await mkdir(join(dest, ".."), { recursive: true });
47
- // `replaceAll` is a no-op for the files that do not use the placeholder,
48
- // so every file can be treated the same way.
49
- const raw = await readFile(file, "utf8");
50
- await writeFile(dest, raw.replaceAll("{{name}}", name), "utf8");
51
- }
52
- }
53
- async function isEmptyDir(dir) {
54
- if (!existsSync(dir))
55
- return true;
56
- return (await readdir(dir)).length === 0;
57
- }
58
12
  const arg = process.argv[2];
59
13
  if (arg === undefined || arg === "--help" || arg === "-h") {
60
14
  console.log(USAGE);
@@ -67,7 +21,7 @@ if (!await isEmptyDir(target)) {
67
21
  }
68
22
  const name = basename(target);
69
23
  await mkdir(target, { recursive: true });
70
- await copyTemplate(target, name);
24
+ await scaffold(target, name);
71
25
  console.log(`\nCreated "${name}" in ${target}\n`);
72
26
  console.log("Next steps:");
73
27
  console.log(` cd ${arg}`);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AACA,OAAO,EAAE,KAAK,EAAE,MAAM,kBAAkB,CAAC;AACzC,OAAO,EAAE,QAAQ,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAE9C,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,eAAe,CAAC;AAErD,MAAM,KAAK,GAAG;;;;;;CAMb,CAAC;AAEF,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAE5B,IAAI,GAAG,KAAK,SAAS,IAAI,GAAG,KAAK,QAAQ,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC;IAC1D,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC;IACnB,OAAO,CAAC,IAAI,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC1C,CAAC;AAED,MAAM,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,GAAG,CAAC,CAAC;AAE3C,IAAI,CAAC,MAAM,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;IAC9B,OAAO,CAAC,KAAK,CAAC,gBAAgB,GAAG,oCAAoC,CAAC,CAAC;IACvE,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAClB,CAAC;AAED,MAAM,IAAI,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC;AAC9B,MAAM,KAAK,CAAC,MAAM,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACzC,MAAM,QAAQ,CAAC,MAAM,EAAE,IAAI,CAAC,CAAC;AAE7B,OAAO,CAAC,GAAG,CAAC,cAAc,IAAI,QAAQ,MAAM,IAAI,CAAC,CAAC;AAClD,OAAO,CAAC,GAAG,CAAC,aAAa,CAAC,CAAC;AAC3B,OAAO,CAAC,GAAG,CAAC,QAAQ,GAAG,EAAE,CAAC,CAAC;AAC3B,OAAO,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;AAC7B,OAAO,CAAC,GAAG,CAAC,iBAAiB,CAAC,CAAC"}
@@ -0,0 +1,10 @@
1
+ export declare const TEMPLATE_DIR: string;
2
+ export declare function isEmptyDir(dir: string): Promise<boolean>;
3
+ /**
4
+ * Copies every template file into `target`, renaming the files that cannot
5
+ * live under their final name in this package and substituting the project
6
+ * name for the placeholder. `NAME_PLACEHOLDER` matches nothing in the files
7
+ * that do not use it, so every file can be treated the same way.
8
+ */
9
+ export declare function scaffold(target: string, name: string, templateDir?: string): Promise<void>;
10
+ //# sourceMappingURL=scaffold.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.d.ts","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAKA,eAAO,MAAM,YAAY,QAExB,CAAC;AA4BF,wBAAsB,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAG9D;AAED;;;;;GAKG;AACH,wBAAsB,QAAQ,CAC5B,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,WAAW,GAAE,MAAqB,GACjC,OAAO,CAAC,IAAI,CAAC,CAgBf"}
@@ -0,0 +1,56 @@
1
+ import { existsSync } from "node:fs";
2
+ import { mkdir, readdir, readFile, writeFile } from "node:fs/promises";
3
+ import { join } from "node:path";
4
+ import { fileURLToPath } from "node:url";
5
+ export const TEMPLATE_DIR = fileURLToPath(new URL("../templates/basic", import.meta.url));
6
+ /**
7
+ * Template files whose name is only valid once they land in the new project
8
+ * (a `_package.json` inside this package would confuse tooling).
9
+ */
10
+ const RENAMES = {
11
+ "_gitignore": ".gitignore",
12
+ "_package.json": "package.json",
13
+ "_README.md": "README.md",
14
+ };
15
+ /** Project name placeholder, written as `{{name}}` or `{{ name }}`. */
16
+ const NAME_PLACEHOLDER = /\{\{\s*name\s*\}\}/g;
17
+ async function walk(dir) {
18
+ const out = [];
19
+ for (const entry of await readdir(dir, { withFileTypes: true })) {
20
+ const full = join(dir, entry.name);
21
+ if (entry.isDirectory()) {
22
+ out.push(...await walk(full));
23
+ }
24
+ else {
25
+ out.push(full);
26
+ }
27
+ }
28
+ return out;
29
+ }
30
+ export async function isEmptyDir(dir) {
31
+ if (!existsSync(dir))
32
+ return true;
33
+ return (await readdir(dir)).length === 0;
34
+ }
35
+ /**
36
+ * Copies every template file into `target`, renaming the files that cannot
37
+ * live under their final name in this package and substituting the project
38
+ * name for the placeholder. `NAME_PLACEHOLDER` matches nothing in the files
39
+ * that do not use it, so every file can be treated the same way.
40
+ */
41
+ export async function scaffold(target, name, templateDir = TEMPLATE_DIR) {
42
+ for (const file of await walk(templateDir)) {
43
+ const rel = file
44
+ .slice(templateDir.length)
45
+ .replace(/\\/g, "/")
46
+ .replace(/^\//, "");
47
+ const parts = rel.split("/");
48
+ const fileName = parts[parts.length - 1];
49
+ parts[parts.length - 1] = RENAMES[fileName] ?? fileName;
50
+ const dest = join(target, ...parts);
51
+ await mkdir(join(dest, ".."), { recursive: true });
52
+ const raw = await readFile(file, "utf8");
53
+ await writeFile(dest, raw.replaceAll(NAME_PLACEHOLDER, name), "utf8");
54
+ }
55
+ }
56
+ //# sourceMappingURL=scaffold.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scaffold.js","sourceRoot":"","sources":["../src/scaffold.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAC;AACrC,OAAO,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AACvE,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,UAAU,CAAC;AAEzC,MAAM,CAAC,MAAM,YAAY,GAAG,aAAa,CACvC,IAAI,GAAG,CAAC,oBAAoB,EAAE,OAAO,IAAI,CAAC,GAAG,CAAC,CAC/C,CAAC;AAEF;;;GAGG;AACH,MAAM,OAAO,GAA2B;IACtC,YAAY,EAAE,YAAY;IAC1B,eAAe,EAAE,cAAc;IAC/B,YAAY,EAAE,WAAW;CAC1B,CAAC;AAEF,uEAAuE;AACvE,MAAM,gBAAgB,GAAG,qBAAqB,CAAC;AAE/C,KAAK,UAAU,IAAI,CAAC,GAAW;IAC7B,MAAM,GAAG,GAAa,EAAE,CAAC;IACzB,KAAK,MAAM,KAAK,IAAI,MAAM,OAAO,CAAC,GAAG,EAAE,EAAE,aAAa,EAAE,IAAI,EAAE,CAAC,EAAE,CAAC;QAChE,MAAM,IAAI,GAAG,IAAI,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC;QACnC,IAAI,KAAK,CAAC,WAAW,EAAE,EAAE,CAAC;YACxB,GAAG,CAAC,IAAI,CAAC,GAAG,MAAM,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;QAChC,CAAC;aAAM,CAAC;YACN,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACjB,CAAC;IACH,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,UAAU,CAAC,GAAW;IAC1C,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC;QAAE,OAAO,IAAI,CAAC;IAClC,OAAO,CAAC,MAAM,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC;AAC3C,CAAC;AAED;;;;;GAKG;AACH,MAAM,CAAC,KAAK,UAAU,QAAQ,CAC5B,MAAc,EACd,IAAY,EACZ,WAAW,GAAW,YAAY;IAElC,KAAK,MAAM,IAAI,IAAI,MAAM,IAAI,CAAC,WAAW,CAAC,EAAE,CAAC;QAC3C,MAAM,GAAG,GAAG,IAAI;aACb,KAAK,CAAC,WAAW,CAAC,MAAM,CAAC;aACzB,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC;aACnB,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC;QACtB,MAAM,KAAK,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC7B,MAAM,QAAQ,GAAG,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;QACzC,KAAK,CAAC,KAAK,CAAC,MAAM,GAAG,CAAC,CAAC,GAAG,OAAO,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC;QAExD,MAAM,IAAI,GAAG,IAAI,CAAC,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC;QACpC,MAAM,KAAK,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnD,MAAM,GAAG,GAAG,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACzC,MAAM,SAAS,CAAC,IAAI,EAAE,GAAG,CAAC,UAAU,CAAC,gBAAgB,EAAE,IAAI,CAAC,EAAE,MAAM,CAAC,CAAC;IACxE,CAAC;AACH,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "create-hum",
3
- "version": "0.0.1",
3
+ "version": "0.0.3",
4
4
  "type": "module",
5
5
  "description": "Scaffolds a new Hum project",
6
6
  "repository": {
@@ -13,7 +13,8 @@
13
13
  },
14
14
  "files": [
15
15
  "dist",
16
- "templates"
16
+ "templates",
17
+ "README.md"
17
18
  ],
18
19
  "devDependencies": {
19
20
  "@types/node": "^26.6.5"
@@ -10,8 +10,8 @@
10
10
  },
11
11
  "dependencies": {
12
12
  "@hono/node-server": "^2.1.4",
13
- "@humjs/core": "^0.0.1",
14
- "@humjs/vite-plugin": "^0.0.1",
13
+ "@humjs/core": "^0.0.2",
14
+ "@humjs/vite-plugin": "^0.0.2",
15
15
  "@preact/signals": "^2.11.3",
16
16
  "hono": "^4.13.13",
17
17
  "preact": "^11.0.1"
@@ -1,3 +1,3 @@
1
- import "./style.css";
2
-
3
- export {};
1
+ import "./style.css";
2
+
3
+ export {};
@@ -1 +1 @@
1
- @import "tailwindcss";
1
+ @import "tailwindcss";
@@ -1 +1 @@
1
- /// <reference types="vite/client" />
1
+ /// <reference types="vite/client" />
@@ -5,7 +5,7 @@ import { define } from "@humjs/core";
5
5
  export const head = define.head(
6
6
  <>
7
7
  <meta name="viewport" content="width=device-width, initial-scale=1" />
8
- <title>{{ name }}</title>
8
+ <title>{{name}}</title>
9
9
  </>,
10
10
  );
11
11
 
@@ -1,12 +1,12 @@
1
1
  import { define } from "@humjs/core";
2
2
  import Counter from "../islands/Counter.js";
3
3
 
4
- export const head = define.head(<title>{{ name }}</title>);
4
+ export const head = define.head(<title>{{name}}</title>);
5
5
 
6
6
  export default function Home() {
7
7
  return (
8
8
  <section class="mx-auto max-w-3xl space-y-6 p-8">
9
- <h1 class="text-3xl font-bold">{{ name }}</h1>
9
+ <h1 class="text-3xl font-bold">{{name}}</h1>
10
10
  {/* Only this island ships JavaScript; the rest stays static HTML. */}
11
11
  <Counter start={0} />
12
12
  </section>