@kematjaya/crud-ui-generator 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/README.md +80 -0
- package/dist/cli.js +106 -0
- package/dist/naming.js +47 -0
- package/dist/spec.js +47 -0
- package/dist/templates/apiShapes.js +45 -0
- package/dist/templates/bffRoutes.js +175 -0
- package/dist/templates/csvLib.js +30 -0
- package/dist/templates/form.js +172 -0
- package/dist/templates/pages.js +38 -0
- package/dist/templates/queryLib.js +77 -0
- package/dist/templates/schemas.js +36 -0
- package/dist/templates/sharedComponents.js +415 -0
- package/dist/templates/table.js +499 -0
- package/dist/templates/typesApi.js +45 -0
- package/dist/templates/useExport.js +121 -0
- package/dist/write.js +70 -0
- package/package.json +26 -0
package/dist/write.js
ADDED
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
|
|
2
|
+
import { dirname } from 'node:path';
|
|
3
|
+
export function newLog() {
|
|
4
|
+
return { created: [], skipped: [], appended: [] };
|
|
5
|
+
}
|
|
6
|
+
/** Writes a file, creating parent directories as needed. Refuses to clobber an existing file. */
|
|
7
|
+
export function writeNewFile(path, contents, log) {
|
|
8
|
+
if (existsSync(path)) {
|
|
9
|
+
log.skipped.push(path);
|
|
10
|
+
return;
|
|
11
|
+
}
|
|
12
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
13
|
+
writeFileSync(path, contents, 'utf8');
|
|
14
|
+
log.created.push(path);
|
|
15
|
+
}
|
|
16
|
+
/** Writes a file only if it doesn't exist yet — for shared, entity-agnostic components. */
|
|
17
|
+
export function writeIfMissing(path, contents, log) {
|
|
18
|
+
if (existsSync(path)) {
|
|
19
|
+
log.skipped.push(path);
|
|
20
|
+
return;
|
|
21
|
+
}
|
|
22
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
23
|
+
writeFileSync(path, contents, 'utf8');
|
|
24
|
+
log.created.push(path);
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Appends a generated block to a shared, multi-entity file (created fresh if missing), keyed by
|
|
28
|
+
* `marker` so re-running the generator for the same entity is a no-op instead of duplicating the
|
|
29
|
+
* block. Used for lib/api-shapes.ts, lib/schemas.ts, and types/api.ts, which accumulate one block
|
|
30
|
+
* per entity across generator runs.
|
|
31
|
+
*/
|
|
32
|
+
export function appendBlock(path, header, marker, block, log) {
|
|
33
|
+
if (!existsSync(path)) {
|
|
34
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
35
|
+
writeFileSync(path, header + block, 'utf8');
|
|
36
|
+
log.created.push(path);
|
|
37
|
+
return;
|
|
38
|
+
}
|
|
39
|
+
const current = readFileSync(path, 'utf8');
|
|
40
|
+
if (current.includes(marker)) {
|
|
41
|
+
log.skipped.push(path);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
writeFileSync(path, current.replace(/\s*$/, '\n') + block, 'utf8');
|
|
45
|
+
log.appended.push(path);
|
|
46
|
+
}
|
|
47
|
+
/**
|
|
48
|
+
* Like {@link appendBlock}, but for files where each entity's block also needs an `import`
|
|
49
|
+
* line — keeping those at the top of the file (after the last existing import) instead of
|
|
50
|
+
* scattered mid-file, which `appendBlock` alone would produce.
|
|
51
|
+
*/
|
|
52
|
+
export function appendBlockWithImport(path, header, importLine, marker, block, log) {
|
|
53
|
+
if (!existsSync(path)) {
|
|
54
|
+
mkdirSync(dirname(path), { recursive: true });
|
|
55
|
+
writeFileSync(path, header + importLine + block, 'utf8');
|
|
56
|
+
log.created.push(path);
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
const current = readFileSync(path, 'utf8');
|
|
60
|
+
if (current.includes(marker)) {
|
|
61
|
+
log.skipped.push(path);
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
const importLines = [...current.matchAll(/^import .*$/gm)];
|
|
65
|
+
const lastImport = importLines.at(-1);
|
|
66
|
+
const insertAt = lastImport ? lastImport.index + lastImport[0].length : 0;
|
|
67
|
+
const withImport = current.slice(0, insertAt) + '\n' + importLine.trimEnd() + current.slice(insertAt);
|
|
68
|
+
writeFileSync(path, withImport.replace(/\s*$/, '\n') + block, 'utf8');
|
|
69
|
+
log.appended.push(path);
|
|
70
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@kematjaya/crud-ui-generator",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Next.js CRUD frontend generator that reads crud-specs/{Entity}.json sidecars written by kematjaya/crud-maker-bundle's make:kmj-api-crud and generates pages, components, and BFF routes matching the boilerplate's hand-written Notes feature.",
|
|
5
|
+
"type": "module",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"author": "Nur Hidayatullah <kematjaya0@gmail.com>",
|
|
8
|
+
"bin": {
|
|
9
|
+
"crud-ui-generate": "dist/cli.js"
|
|
10
|
+
},
|
|
11
|
+
"files": [
|
|
12
|
+
"dist"
|
|
13
|
+
],
|
|
14
|
+
"engines": {
|
|
15
|
+
"node": ">=18"
|
|
16
|
+
},
|
|
17
|
+
"scripts": {
|
|
18
|
+
"build": "tsc -p tsconfig.json && chmod +x dist/cli.js",
|
|
19
|
+
"prepublishOnly": "npm run build",
|
|
20
|
+
"test": "node --test --experimental-strip-types src/**/*.test.ts"
|
|
21
|
+
},
|
|
22
|
+
"devDependencies": {
|
|
23
|
+
"@types/node": "^22.0.0",
|
|
24
|
+
"typescript": "^5.6.0"
|
|
25
|
+
}
|
|
26
|
+
}
|