@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.
Files changed (61) hide show
  1. package/LICENSE +6 -0
  2. package/README.md +94 -0
  3. package/dist/bin.js +2752 -0
  4. package/dist/bin.js.map +1 -0
  5. package/dist/index.d.ts +6 -0
  6. package/dist/index.js +2730 -0
  7. package/dist/index.js.map +1 -0
  8. package/package.json +67 -0
  9. package/scaffolds/blank/.cursor/rules/feeef-theme.mdc +34 -0
  10. package/scaffolds/blank/.cursor/rules/filterator.mdc +13 -0
  11. package/scaffolds/blank/.cursor/rules/order-form.mdc +17 -0
  12. package/scaffolds/blank/.cursor/rules/theme-source.mdc +32 -0
  13. package/scaffolds/blank/.cursor/skills/feeef-filterator/SKILL.md +15 -0
  14. package/scaffolds/blank/.cursor/skills/feeef-theme/SKILL.md +56 -0
  15. package/scaffolds/blank/.cursor/skills/feeef-theme/reference.md +73 -0
  16. package/scaffolds/blank/.vscode/extensions.json +3 -0
  17. package/scaffolds/blank/.vscode/settings.json +13 -0
  18. package/scaffolds/blank/AGENTS.md +104 -0
  19. package/scaffolds/blank/README.md +21 -0
  20. package/scaffolds/blank/docs/00-INDEX.md +33 -0
  21. package/scaffolds/blank/docs/03-CUSTOM-COMPONENTS.md +116 -0
  22. package/scaffolds/blank/docs/04-WORKFLOW.md +129 -0
  23. package/scaffolds/blank/docs/05-ANTI-PATTERNS.md +80 -0
  24. package/scaffolds/blank/docs/07-SHARED-COMPONENTS.md +144 -0
  25. package/scaffolds/blank/docs/08-ORDER-FORM.md +376 -0
  26. package/scaffolds/blank/docs/09-THEME-PORTING.md +211 -0
  27. package/scaffolds/blank/docs/10-SCHEMA-LIBRARY.md +127 -0
  28. package/scaffolds/blank/docs/11-PAGES-CHECKOUT-THANKS-PRODUCT.md +81 -0
  29. package/scaffolds/blank/docs/12-DARK-LIGHT-THEME.md +164 -0
  30. package/scaffolds/blank/docs/13-TEMPLATE-I18N.md +320 -0
  31. package/scaffolds/blank/docs/14-FILTERATOR.md +433 -0
  32. package/scaffolds/blank/docs/16-AUTHORING-TS-IMPORTS.md +73 -0
  33. package/scaffolds/blank/feeef.template.json +7 -0
  34. package/scaffolds/blank/locales/README.md +4 -0
  35. package/scaffolds/blank/locales/ar.json +10 -0
  36. package/scaffolds/blank/locales/en.json +10 -0
  37. package/scaffolds/blank/package-lock.json +1975 -0
  38. package/scaffolds/blank/package.json +23 -0
  39. package/scaffolds/blank/pages/home/components/hero.tsx +34 -0
  40. package/scaffolds/blank/pages/home/page.json +3 -0
  41. package/scaffolds/blank/props.json +6 -0
  42. package/scaffolds/blank/schema.ts +49 -0
  43. package/scaffolds/blank/tsconfig.json +24 -0
  44. package/scaffolds/blank/types/feeef-live-scope.d.ts +162 -0
  45. package/scaffolds/blank/types/feeef-template-schema.d.ts +84 -0
  46. package/vendor/template-kit/README.md +64 -0
  47. package/vendor/template-kit/bin/dev.mjs +61 -0
  48. package/vendor/template-kit/bin/feeef-template.mjs +212 -0
  49. package/vendor/template-kit/data/lithium-schema.json +4733 -0
  50. package/vendor/template-kit/lib/build.mjs +377 -0
  51. package/vendor/template-kit/lib/compile-component.mjs +188 -0
  52. package/vendor/template-kit/lib/component-meta.mjs +481 -0
  53. package/vendor/template-kit/lib/library.mjs +168 -0
  54. package/vendor/template-kit/lib/locales.mjs +68 -0
  55. package/vendor/template-kit/lib/paths.mjs +84 -0
  56. package/vendor/template-kit/lib/shared.mjs +268 -0
  57. package/vendor/template-kit/lib/theme-schema.mjs +300 -0
  58. package/vendor/template-kit/lib/unpack.mjs +324 -0
  59. package/vendor/template-kit/lib/validate.mjs +207 -0
  60. package/vendor/template-kit/schemas/component.schema.json +55 -0
  61. 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();