@middag-io/react 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.
@@ -0,0 +1,250 @@
1
+ #!/usr/bin/env node
2
+ /* global console, process */
3
+
4
+ /**
5
+ * @middag-io/react CLI
6
+ *
7
+ * Run from inside ui/ (where @middag-io/react is installed).
8
+ *
9
+ * Commands:
10
+ * doctor — Validate project setup
11
+ * dev — Start mock dev server
12
+ * add-block — Scaffold a new block type
13
+ * upgrade — Check for updates and run codemods
14
+ *
15
+ * For bootstrapping a new project, use: npx create-middag-ui
16
+ */
17
+
18
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
19
+ import { join } from "node:path";
20
+ import { execSync } from "node:child_process";
21
+
22
+ // ── Helpers ────────────────────────────────────────────────────────────────
23
+
24
+ function log(msg) { console.log(`\x1b[36m@middag-io/react\x1b[0m ${msg}`); }
25
+ function success(msg) { console.log(` \x1b[32m✓\x1b[0m ${msg}`); }
26
+ function warn(msg) { console.log(` \x1b[33m⚠\x1b[0m ${msg}`); }
27
+ function fail(msg) { console.log(` \x1b[31m✗\x1b[0m ${msg}`); }
28
+
29
+ function run(cmd, opts = {}) {
30
+ return execSync(cmd, { stdio: "inherit", ...opts });
31
+ }
32
+
33
+ // ── Commands ───────────────────────────────────────────────────────────────
34
+
35
+ function cmdDoctor(cwd) {
36
+ log("Checking project setup...\n");
37
+ let pass = 0, warns = 0, fails = 0;
38
+
39
+ // Node version
40
+ const nodeVer = process.version;
41
+ const nodeMajor = parseInt(nodeVer.slice(1), 10);
42
+ if (nodeMajor >= 20) { success(`Node ${nodeVer}`); pass++; }
43
+ else { warn(`Node ${nodeVer} (recommended: >= 20)`); warns++; }
44
+
45
+ // @middag-io/react installed
46
+ const libPath = join(cwd, "node_modules", "@middag-io", "react");
47
+ if (existsSync(libPath)) { success("@middag-io/react installed"); pass++; }
48
+ else { fail("@middag-io/react not found — run: npm install"); fails++; }
49
+
50
+ // Registry config (GitHub Packages uses ~/.npmrc global, npm public needs nothing)
51
+ const globalNpmrc = join(process.env.HOME || process.env.USERPROFILE || "", ".npmrc");
52
+ const localNpmrc = join(cwd, ".npmrc");
53
+ if (existsSync(globalNpmrc) && readFileSync(globalNpmrc, "utf8").includes("@middag-io:registry")) {
54
+ success("GitHub Packages registry configured (global ~/.npmrc)");
55
+ pass++;
56
+ } else if (existsSync(localNpmrc) && readFileSync(localNpmrc, "utf8").includes("@middag-io:registry")) {
57
+ success("Registry configured (local .npmrc)");
58
+ warn("Consider moving token to ~/.npmrc (global) for security");
59
+ pass++; warns++;
60
+ } else {
61
+ success("Using npm public registry (no auth needed)");
62
+ pass++;
63
+ }
64
+
65
+ // Peer dependencies
66
+ for (const dep of ["react", "react-dom", "@inertiajs/react"]) {
67
+ const depPath = join(cwd, "node_modules", dep);
68
+ if (existsSync(depPath)) { success(`Peer dep: ${dep}`); pass++; }
69
+ else { fail(`Peer dep missing: ${dep}`); fails++; }
70
+ }
71
+
72
+ // TypeScript
73
+ const tsconfigPath = join(cwd, "tsconfig.json");
74
+ if (existsSync(tsconfigPath)) { success("tsconfig.json"); pass++; }
75
+ else { warn("tsconfig.json missing"); warns++; }
76
+
77
+ // Vite config
78
+ const viteConfig = join(cwd, "vite.mock.config.ts");
79
+ if (existsSync(viteConfig)) { success("vite.mock.config.ts"); pass++; }
80
+ else { warn("vite.mock.config.ts missing"); warns++; }
81
+
82
+ // Summary
83
+ console.log(`\n ${pass} passed, ${warns} warnings, ${fails} failures`);
84
+ if (fails > 0) {
85
+ console.log("\n Fix failures before proceeding.");
86
+ console.log(" Docs: https://docs.middag.io/getting-started\n");
87
+ process.exit(1);
88
+ }
89
+ if (warns > 0) console.log("\n Warnings are non-blocking but worth fixing.\n");
90
+ else console.log("\n Environment OK.\n");
91
+ }
92
+
93
+ function cmdDev(cwd) {
94
+ if (!existsSync(join(cwd, "package.json"))) {
95
+ fail("package.json not found. Are you inside ui/?");
96
+ process.exit(1);
97
+ }
98
+ log("Starting mock dev server...\n");
99
+ run("npm run dev:mock", { cwd });
100
+ }
101
+
102
+ function cmdAddBlock(cwd, blockType) {
103
+ if (!blockType) {
104
+ fail("Usage: npx @middag-io/react add-block <type_key>");
105
+ console.log(" Example: npx @middag-io/react add-block chart_panel");
106
+ process.exit(1);
107
+ }
108
+
109
+ const pascalName = blockType
110
+ .split("_")
111
+ .map((w) => w.charAt(0).toUpperCase() + w.slice(1))
112
+ .join("") + "Block";
113
+
114
+ const blockDir = join(cwd, "src", "blocks");
115
+ mkdirSync(blockDir, { recursive: true });
116
+
117
+ const blockPath = join(blockDir, `${pascalName}.tsx`);
118
+ if (existsSync(blockPath)) {
119
+ warn(`${blockPath} already exists`);
120
+ return;
121
+ }
122
+
123
+ writeFileSync(blockPath, `import type { BlockProps } from "@middag-io/react";
124
+
125
+ interface ${pascalName}Data {
126
+ title: string;
127
+ // Add your block data fields here
128
+ }
129
+
130
+ export function ${pascalName}({ block }: BlockProps<${pascalName}Data>) {
131
+ return (
132
+ <div className="rounded-md border p-4">
133
+ <h3 className="text-sm font-medium text-foreground">
134
+ {block.data.title}
135
+ </h3>
136
+ {/* Implement your block UI here */}
137
+ </div>
138
+ );
139
+ }
140
+ `);
141
+ success(`Created ${blockPath}`);
142
+
143
+ // Create mock data factory
144
+ const mockDataDir = join(cwd, "mock", "data");
145
+ mkdirSync(mockDataDir, { recursive: true });
146
+
147
+ const factoryPath = join(mockDataDir, `${blockType}.ts`);
148
+ if (!existsSync(factoryPath)) {
149
+ writeFileSync(factoryPath, `import type { BlockDescriptor } from "@middag-io/react";
150
+
151
+ export function create${pascalName.replace("Block", "")}Block(
152
+ t: (key: string) => string,
153
+ ): BlockDescriptor {
154
+ return {
155
+ key: "${blockType}_1",
156
+ type: "${blockType}",
157
+ data: {
158
+ title: t("${blockType}.title"),
159
+ },
160
+ };
161
+ }
162
+ `);
163
+ success(`Created ${factoryPath}`);
164
+ }
165
+
166
+ console.log(`\n Next steps:`);
167
+ console.log(` 1. Register the block: registerBlock("${blockType}", ${pascalName})`);
168
+ console.log(` 2. Add i18n keys for "${blockType}.*" in EN and PT-BR`);
169
+ console.log(` 3. Use in a PageContract: { key: "${blockType}_1", type: "${blockType}", data: {...} }`);
170
+ console.log(`\n Docs: https://docs.middag.io/guides/custom-blocks\n`);
171
+ }
172
+
173
+ function cmdUpgrade(cwd) {
174
+ log("Checking for updates...\n");
175
+ const pkgPath = join(cwd, "package.json");
176
+
177
+ if (!existsSync(pkgPath)) {
178
+ fail("package.json not found. Are you inside ui/?");
179
+ process.exit(1);
180
+ }
181
+
182
+ try {
183
+ const result = execSync("npm view @middag-io/react version 2>/dev/null", { encoding: "utf8" }).trim();
184
+ const currentPkg = JSON.parse(readFileSync(pkgPath, "utf8"));
185
+ const current = currentPkg.dependencies?.["@middag-io/react"] || "unknown";
186
+
187
+ console.log(` Current: ${current}`);
188
+ console.log(` Latest: ${result}`);
189
+
190
+ if (current.includes(result)) {
191
+ success("Already up to date");
192
+ } else {
193
+ log("Updating...");
194
+ run("npm install @middag-io/react@latest", { cwd });
195
+ success(`Updated to ${result}`);
196
+ }
197
+ } catch {
198
+ warn("Could not check latest version (network or auth issue)");
199
+ console.log(" Try: npm install @middag-io/react@latest\n");
200
+ }
201
+ }
202
+
203
+ // ── Main ───────────────────────────────────────────────────────────────────
204
+
205
+ const [,, command, ...args] = process.argv;
206
+ const cwd = process.cwd();
207
+
208
+ switch (command) {
209
+ case "init":
210
+ log("The init command has moved to a separate package.");
211
+ console.log(" Run: npx create-middag-ui\n");
212
+ console.log(" This works without GitHub Packages auth.");
213
+ console.log(" Docs: https://docs.middag.io/cli\n");
214
+ break;
215
+ case "doctor":
216
+ cmdDoctor(cwd);
217
+ break;
218
+ case "dev":
219
+ cmdDev(cwd);
220
+ break;
221
+ case "add-block":
222
+ cmdAddBlock(cwd, args[0]);
223
+ break;
224
+ case "upgrade":
225
+ cmdUpgrade(cwd);
226
+ break;
227
+ default:
228
+ console.log(`
229
+ @middag-io/react CLI (run from ui/)
230
+
231
+ Commands:
232
+ doctor Validate project setup
233
+ dev Start mock dev server
234
+ add-block <type> Scaffold a new block type
235
+ upgrade Check for updates and run codemods
236
+
237
+ Bootstrap a new project:
238
+ npx create-middag-ui
239
+
240
+ Examples:
241
+ npx @middag-io/react doctor
242
+ npx @middag-io/react add-block chart_panel
243
+
244
+ Docs: https://docs.middag.io
245
+ `);
246
+ if (command) {
247
+ fail(`Unknown command: ${command}`);
248
+ process.exit(1);
249
+ }
250
+ }