create-fratm 0.0.0-stage → 0.12.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.
Files changed (3) hide show
  1. package/README.md +20 -2
  2. package/index.js +92 -0
  3. package/package.json +33 -4
package/README.md CHANGED
@@ -1,3 +1,21 @@
1
- # Temporary Holding Version
1
+ # create-fratm
2
2
 
3
- This version is a temporary placeholder for this package. An operational version to replace this has been submitted for review and is awaiting a staged release.
3
+ Creates a [FratmScript](https://github.com/kkratterf/fratmscript) project without installing the `fratm` CLI:
4
+
5
+ ```bash
6
+ npm create fratm@latest pizzeria
7
+ cd pizzeria
8
+ npm install
9
+ npm run dev
10
+ ```
11
+
12
+ The default project is a React app built with Vite, written in `.fratm` files with JSX.
13
+
14
+ | Option | What you get |
15
+ | --- | --- |
16
+ | `--completa` | React plus a Hono API and a SQLite database (Node 22.13+) |
17
+ | `--senza-react` | the same Vite setup with plain DOM code |
18
+ | `--semplice` | only a `main.fratm` |
19
+ | `--tailwind` | adds Tailwind CSS to the React app |
20
+
21
+ The templates are the ones of `fratm nuovo`: they come from the compiler itself (the `fratmscript` package), so the two never drift apart.
package/index.js ADDED
@@ -0,0 +1,92 @@
1
+ #!/usr/bin/env node
2
+ // `npm create fratm@latest mia-app`: writes a new FratmScript project with
3
+ // the same templates as `fratm nuovo`, using the compiler from npm, so the
4
+ // CLI does not have to be installed.
5
+ import { mkdir, readdir, writeFile } from 'node:fs/promises';
6
+ import { dirname, resolve } from 'node:path';
7
+ import { createInterface } from 'node:readline/promises';
8
+ import { scaffold, version } from 'fratmscript';
9
+
10
+ const TEMPLATES = {
11
+ '--completa': 'completa',
12
+ '--senza-react': 'senza-react',
13
+ '--semplice': 'semplice',
14
+ };
15
+
16
+ const HELP = `npm create fratm@latest <cartella> [opzioni]
17
+
18
+ --completa React + API Hono + database SQLite (Node 22.13+)
19
+ --senza-react Vite senza React, codice DOM normale
20
+ --semplice sulo nu main.fratm pe 'fratm lancia'
21
+ --tailwind azzecca Tailwind CSS (cu React)
22
+ -h, --help stammo ccà
23
+ `;
24
+
25
+ /** Parses argv: the folder, the template and whether Tailwind is wanted. */
26
+ export function parseArgs(argv) {
27
+ const args = argv.filter((arg) => arg !== '');
28
+ if (args.includes('-h') || args.includes('--help')) return { help: true };
29
+ let template = 'react';
30
+ let tailwind = false;
31
+ const rest = [];
32
+ for (const arg of args) {
33
+ if (arg === '--tailwind') tailwind = true;
34
+ else if (TEMPLATES[arg]) template = TEMPLATES[arg];
35
+ else if (arg.startsWith('-')) return { error: `Nun capisco l'opzione ${arg}` };
36
+ else rest.push(arg);
37
+ }
38
+ if (rest.length > 1) return { error: 'Na cartella sola, pe piacere' };
39
+ if (tailwind && template !== 'react' && template !== 'completa')
40
+ return { error: '--tailwind va cu React (sulo, o cu --completa)' };
41
+ return { dir: rest[0], template, tailwind };
42
+ }
43
+
44
+ async function ask() {
45
+ const rl = createInterface({ input: process.stdin, output: process.stdout });
46
+ const answer = await rl.question("Comme se chiamma 'a cartella? (pizzeria) ");
47
+ rl.close();
48
+ return answer.trim() || 'pizzeria';
49
+ }
50
+
51
+ async function main(argv) {
52
+ const options = parseArgs(argv);
53
+ if (options.help) {
54
+ process.stdout.write(HELP);
55
+ return;
56
+ }
57
+ if (options.error) {
58
+ process.stderr.write(`✗ ${options.error}\n\n${HELP}`);
59
+ process.exitCode = 1;
60
+ return;
61
+ }
62
+ const name = options.dir ?? (await ask());
63
+ const dir = resolve(process.cwd(), name);
64
+ const existing = await readdir(dir).catch((e) => (e.code === 'ENOENT' ? [] : Promise.reject(e)));
65
+ if (existing.length > 0) {
66
+ process.stderr.write(`✗ 'a cartella ${name} esiste già e nun è vacante\n`);
67
+ process.exitCode = 1;
68
+ return;
69
+ }
70
+ const files = scaffold({ template: options.template, name, tailwind: options.tailwind });
71
+ for (const file of files) {
72
+ const target = resolve(dir, file.path);
73
+ await mkdir(dirname(target), { recursive: true });
74
+ await writeFile(target, file.contents);
75
+ process.stdout.write(` + ${file.path}\n`);
76
+ }
77
+ // The simple template has no package.json: it needs the CLI, or the
78
+ // compiler installed by hand to run the file with Node
79
+ const start =
80
+ options.template === 'semplice'
81
+ ? "fratm lancia main.fratm\n\nSenza 'a CLI: npm i fratmscript && node --import fratmscript/node main.fratm"
82
+ : 'npm install\n npm run dev';
83
+ process.stdout.write(`\n🤌 Progetto pronto cu FratmScript ${version()}: ${name}\n\n cd ${name}\n ${start}\n`);
84
+ }
85
+
86
+ // Not when imported by the tests
87
+ if (process.argv[1] && import.meta.url === `file://${process.argv[1]}`) {
88
+ main(process.argv.slice(2)).catch((error) => {
89
+ process.stderr.write(`✗ ${error.message}\n`);
90
+ process.exitCode = 1;
91
+ });
92
+ }
package/package.json CHANGED
@@ -1,6 +1,35 @@
1
1
  {
2
2
  "name": "create-fratm",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.12.0",
4
+ "description": "Create a FratmScript app: npm create fratm@latest mia-app",
5
+ "license": "MIT",
6
+ "type": "module",
7
+ "repository": {
8
+ "type": "git",
9
+ "url": "git+https://github.com/kkratterf/fratmscript.git",
10
+ "directory": "packages/create-fratm"
11
+ },
12
+ "homepage": "https://github.com/kkratterf/fratmscript/tree/main/packages/create-fratm#readme",
13
+ "keywords": [
14
+ "fratmscript",
15
+ "napoletano",
16
+ "create",
17
+ "scaffold",
18
+ "template"
19
+ ],
20
+ "bin": {
21
+ "create-fratm": "index.js"
22
+ },
23
+ "files": [
24
+ "index.js"
25
+ ],
26
+ "engines": {
27
+ "node": ">=18"
28
+ },
29
+ "dependencies": {
30
+ "fratmscript": "^0.12.0"
31
+ },
32
+ "scripts": {
33
+ "test": "node --test test/*.test.js"
34
+ }
35
+ }