@feeef.dev/cli 0.2.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/LICENSE +6 -0
- package/README.md +94 -0
- package/dist/bin.js +2752 -0
- package/dist/bin.js.map +1 -0
- package/dist/index.d.ts +6 -0
- package/dist/index.js +2730 -0
- package/dist/index.js.map +1 -0
- package/package.json +67 -0
- package/scaffolds/blank/.cursor/rules/feeef-theme.mdc +34 -0
- package/scaffolds/blank/.cursor/rules/filterator.mdc +13 -0
- package/scaffolds/blank/.cursor/rules/order-form.mdc +17 -0
- package/scaffolds/blank/.cursor/rules/theme-source.mdc +32 -0
- package/scaffolds/blank/.cursor/skills/feeef-filterator/SKILL.md +15 -0
- package/scaffolds/blank/.cursor/skills/feeef-theme/SKILL.md +56 -0
- package/scaffolds/blank/.cursor/skills/feeef-theme/reference.md +73 -0
- package/scaffolds/blank/.vscode/extensions.json +3 -0
- package/scaffolds/blank/.vscode/settings.json +13 -0
- package/scaffolds/blank/AGENTS.md +104 -0
- package/scaffolds/blank/README.md +21 -0
- package/scaffolds/blank/docs/00-INDEX.md +33 -0
- package/scaffolds/blank/docs/03-CUSTOM-COMPONENTS.md +116 -0
- package/scaffolds/blank/docs/04-WORKFLOW.md +129 -0
- package/scaffolds/blank/docs/05-ANTI-PATTERNS.md +80 -0
- package/scaffolds/blank/docs/07-SHARED-COMPONENTS.md +144 -0
- package/scaffolds/blank/docs/08-ORDER-FORM.md +376 -0
- package/scaffolds/blank/docs/09-THEME-PORTING.md +211 -0
- package/scaffolds/blank/docs/10-SCHEMA-LIBRARY.md +127 -0
- package/scaffolds/blank/docs/11-PAGES-CHECKOUT-THANKS-PRODUCT.md +81 -0
- package/scaffolds/blank/docs/12-DARK-LIGHT-THEME.md +164 -0
- package/scaffolds/blank/docs/13-TEMPLATE-I18N.md +320 -0
- package/scaffolds/blank/docs/14-FILTERATOR.md +433 -0
- package/scaffolds/blank/docs/16-AUTHORING-TS-IMPORTS.md +73 -0
- package/scaffolds/blank/feeef.template.json +7 -0
- package/scaffolds/blank/locales/README.md +4 -0
- package/scaffolds/blank/locales/ar.json +10 -0
- package/scaffolds/blank/locales/en.json +10 -0
- package/scaffolds/blank/package-lock.json +1975 -0
- package/scaffolds/blank/package.json +23 -0
- package/scaffolds/blank/pages/home/components/hero.tsx +34 -0
- package/scaffolds/blank/pages/home/page.json +3 -0
- package/scaffolds/blank/props.json +6 -0
- package/scaffolds/blank/schema.ts +49 -0
- package/scaffolds/blank/tsconfig.json +24 -0
- package/scaffolds/blank/types/feeef-live-scope.d.ts +162 -0
- package/scaffolds/blank/types/feeef-template-schema.d.ts +84 -0
- package/vendor/template-kit/README.md +64 -0
- package/vendor/template-kit/bin/dev.mjs +61 -0
- package/vendor/template-kit/bin/feeef-template.mjs +212 -0
- package/vendor/template-kit/data/lithium-schema.json +4733 -0
- package/vendor/template-kit/lib/build.mjs +377 -0
- package/vendor/template-kit/lib/compile-component.mjs +188 -0
- package/vendor/template-kit/lib/component-meta.mjs +481 -0
- package/vendor/template-kit/lib/library.mjs +168 -0
- package/vendor/template-kit/lib/locales.mjs +68 -0
- package/vendor/template-kit/lib/paths.mjs +84 -0
- package/vendor/template-kit/lib/shared.mjs +268 -0
- package/vendor/template-kit/lib/theme-schema.mjs +300 -0
- package/vendor/template-kit/lib/unpack.mjs +324 -0
- package/vendor/template-kit/lib/validate.mjs +207 -0
- package/vendor/template-kit/schemas/component.schema.json +55 -0
- package/vendor/template-kit/schemas/template.schema.json +18 -0
|
@@ -0,0 +1,212 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
/**
|
|
3
|
+
* Feeef Template Kit CLI
|
|
4
|
+
*
|
|
5
|
+
* node template-kit/bin/feeef-template.mjs unpack <data.json> -o <dir> [--force]
|
|
6
|
+
* node template-kit/bin/feeef-template.mjs build <srcDir> [-o dist/data.json]
|
|
7
|
+
* node template-kit/bin/feeef-template.mjs check <srcDir>
|
|
8
|
+
* node template-kit/bin/feeef-template.mjs watch <srcDir> [-o dist/data.json]
|
|
9
|
+
*/
|
|
10
|
+
|
|
11
|
+
import fs from "node:fs";
|
|
12
|
+
import path from "node:path";
|
|
13
|
+
import { fileURLToPath } from "node:url";
|
|
14
|
+
import { unpackTemplate } from "../lib/unpack.mjs";
|
|
15
|
+
import { buildTemplate } from "../lib/build.mjs";
|
|
16
|
+
import { resolveFromCwd, rel } from "../lib/paths.mjs";
|
|
17
|
+
|
|
18
|
+
const __dirname = path.dirname(fileURLToPath(import.meta.url));
|
|
19
|
+
|
|
20
|
+
function printHelp() {
|
|
21
|
+
console.log(`
|
|
22
|
+
Feeef Template Kit — author templates as a folder tree, compile to data.json
|
|
23
|
+
|
|
24
|
+
Usage:
|
|
25
|
+
feeef-template unpack <data.json> -o <outDir> [--force]
|
|
26
|
+
feeef-template build <srcDir> [-o <data.json>]
|
|
27
|
+
feeef-template check <srcDir>
|
|
28
|
+
feeef-template watch <srcDir> [-o <data.json>]
|
|
29
|
+
|
|
30
|
+
Examples (from storefront/):
|
|
31
|
+
npm run template:unpack
|
|
32
|
+
npm run template:build
|
|
33
|
+
npm run template:dev
|
|
34
|
+
`);
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/**
|
|
38
|
+
* @param {string[]} argv
|
|
39
|
+
*/
|
|
40
|
+
function parseArgs(argv) {
|
|
41
|
+
const args = argv.slice(2);
|
|
42
|
+
const cmd = args[0];
|
|
43
|
+
/** @type {Record<string, string | boolean>} */
|
|
44
|
+
const flags = {};
|
|
45
|
+
/** @type {string[]} */
|
|
46
|
+
const positional = [];
|
|
47
|
+
|
|
48
|
+
for (let i = 1; i < args.length; i++) {
|
|
49
|
+
const a = args[i];
|
|
50
|
+
if (a === "--force") {
|
|
51
|
+
flags.force = true;
|
|
52
|
+
} else if (a === "-o" || a === "--out") {
|
|
53
|
+
flags.out = args[++i];
|
|
54
|
+
} else if (a === "-h" || a === "--help") {
|
|
55
|
+
flags.help = true;
|
|
56
|
+
} else if (a.startsWith("-")) {
|
|
57
|
+
throw new Error(`Unknown flag: ${a}`);
|
|
58
|
+
} else {
|
|
59
|
+
positional.push(a);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
return { cmd, flags, positional };
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
function runBuild(srcDir, outPath, { write }) {
|
|
67
|
+
const result = buildTemplate({
|
|
68
|
+
srcDir,
|
|
69
|
+
outPath,
|
|
70
|
+
write,
|
|
71
|
+
});
|
|
72
|
+
for (const w of result.warnings) {
|
|
73
|
+
console.warn(`warning: [${w.path}] ${w.message}`);
|
|
74
|
+
}
|
|
75
|
+
if (write) {
|
|
76
|
+
console.log(
|
|
77
|
+
`✓ built ${result.pageCount} pages / ${result.componentCount} components` +
|
|
78
|
+
(result.sharedCount
|
|
79
|
+
? ` (${result.sharedCount} shared, ${result.sharedPlacementCount} placements)`
|
|
80
|
+
: "") +
|
|
81
|
+
(result.libraryCount
|
|
82
|
+
? ` / ${result.libraryCount} library`
|
|
83
|
+
: "") +
|
|
84
|
+
(result.localeCount ? ` / ${result.localeCount} locales` : "") +
|
|
85
|
+
` → ${rel(result.outPath)}`,
|
|
86
|
+
);
|
|
87
|
+
if (result.libraryOutPath) {
|
|
88
|
+
console.log(` library → ${rel(result.libraryOutPath)}`);
|
|
89
|
+
}
|
|
90
|
+
if (result.localeCount) {
|
|
91
|
+
console.log(` locales → ${rel(path.dirname(result.outPath) + "/locales")}`);
|
|
92
|
+
}
|
|
93
|
+
} else {
|
|
94
|
+
console.log(
|
|
95
|
+
`✓ check ok — ${result.pageCount} pages / ${result.componentCount} components` +
|
|
96
|
+
(result.sharedCount ? ` / ${result.sharedCount} shared` : "") +
|
|
97
|
+
(result.libraryCount ? ` / ${result.libraryCount} library` : ""),
|
|
98
|
+
);
|
|
99
|
+
}
|
|
100
|
+
return result;
|
|
101
|
+
}
|
|
102
|
+
|
|
103
|
+
async function main() {
|
|
104
|
+
let parsed;
|
|
105
|
+
try {
|
|
106
|
+
parsed = parseArgs(process.argv);
|
|
107
|
+
} catch (e) {
|
|
108
|
+
console.error(String(e.message || e));
|
|
109
|
+
process.exit(1);
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
const { cmd, flags, positional } = parsed;
|
|
113
|
+
|
|
114
|
+
if (!cmd || flags.help || cmd === "help") {
|
|
115
|
+
printHelp();
|
|
116
|
+
process.exit(cmd && !flags.help ? 1 : 0);
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
try {
|
|
120
|
+
if (cmd === "unpack") {
|
|
121
|
+
const input = positional[0];
|
|
122
|
+
if (!input || !flags.out) {
|
|
123
|
+
console.error("Usage: unpack <data.json> -o <outDir> [--force]");
|
|
124
|
+
process.exit(1);
|
|
125
|
+
}
|
|
126
|
+
const stats = unpackTemplate({
|
|
127
|
+
inputPath: resolveFromCwd(input),
|
|
128
|
+
outDir: resolveFromCwd(String(flags.out)),
|
|
129
|
+
force: Boolean(flags.force),
|
|
130
|
+
});
|
|
131
|
+
console.log(
|
|
132
|
+
`✓ unpacked ${stats.pages} pages / ${stats.components} root components (${stats.files} files) → ${flags.out}`,
|
|
133
|
+
);
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (cmd === "build" || cmd === "check") {
|
|
138
|
+
const src = positional[0];
|
|
139
|
+
if (!src) {
|
|
140
|
+
console.error(`Usage: ${cmd} <srcDir> [-o data.json]`);
|
|
141
|
+
process.exit(1);
|
|
142
|
+
}
|
|
143
|
+
const srcDir = resolveFromCwd(src);
|
|
144
|
+
const outPath = flags.out
|
|
145
|
+
? resolveFromCwd(String(flags.out))
|
|
146
|
+
: path.join(srcDir, "dist", "data.json");
|
|
147
|
+
runBuild(srcDir, outPath, { write: cmd === "build" });
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
if (cmd === "watch") {
|
|
152
|
+
const src = positional[0];
|
|
153
|
+
if (!src) {
|
|
154
|
+
console.error("Usage: watch <srcDir> [-o data.json]");
|
|
155
|
+
process.exit(1);
|
|
156
|
+
}
|
|
157
|
+
const srcDir = resolveFromCwd(src);
|
|
158
|
+
const outPath = flags.out
|
|
159
|
+
? resolveFromCwd(String(flags.out))
|
|
160
|
+
: path.join(srcDir, "dist", "data.json");
|
|
161
|
+
|
|
162
|
+
const rebuild = () => {
|
|
163
|
+
try {
|
|
164
|
+
runBuild(srcDir, outPath, { write: true });
|
|
165
|
+
} catch (e) {
|
|
166
|
+
console.error(`build failed: ${e.message || e}`);
|
|
167
|
+
}
|
|
168
|
+
};
|
|
169
|
+
|
|
170
|
+
rebuild();
|
|
171
|
+
console.log(`watching ${rel(srcDir)} …`);
|
|
172
|
+
|
|
173
|
+
/** @type {ReturnType<typeof setTimeout> | null} */
|
|
174
|
+
let timer = null;
|
|
175
|
+
const schedule = () => {
|
|
176
|
+
if (timer) clearTimeout(timer);
|
|
177
|
+
timer = setTimeout(rebuild, 120);
|
|
178
|
+
};
|
|
179
|
+
|
|
180
|
+
// Recursive watch is supported on macOS / Windows; Linux may need polling.
|
|
181
|
+
try {
|
|
182
|
+
fs.watch(srcDir, { recursive: true }, (_event, filename) => {
|
|
183
|
+
if (!filename) {
|
|
184
|
+
schedule();
|
|
185
|
+
return;
|
|
186
|
+
}
|
|
187
|
+
const norm = filename.replace(/\\/g, "/");
|
|
188
|
+
if (norm.startsWith("dist/") || norm.includes("/dist/")) return;
|
|
189
|
+
schedule();
|
|
190
|
+
});
|
|
191
|
+
} catch (e) {
|
|
192
|
+
console.error(
|
|
193
|
+
`fs.watch(recursive) failed (${e.message}). Rebuild manually with template:build.`,
|
|
194
|
+
);
|
|
195
|
+
process.exit(1);
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
// Keep process alive.
|
|
199
|
+
await new Promise(() => {});
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
|
|
203
|
+
console.error(`Unknown command: ${cmd}`);
|
|
204
|
+
printHelp();
|
|
205
|
+
process.exit(1);
|
|
206
|
+
} catch (e) {
|
|
207
|
+
console.error(e.message || e);
|
|
208
|
+
process.exit(1);
|
|
209
|
+
}
|
|
210
|
+
}
|
|
211
|
+
|
|
212
|
+
main();
|