@usefillo/cli 0.5.0 → 0.5.1
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/dist/index.js +51 -13
- package/package.json +4 -1
package/dist/index.js
CHANGED
|
@@ -40,10 +40,16 @@ function openBrowser(url) {
|
|
|
40
40
|
if (!/^https?:\/\//i.test(url)) return;
|
|
41
41
|
try {
|
|
42
42
|
if (process.platform === "win32") {
|
|
43
|
-
spawn("cmd", ["/c", "start", "", url], { stdio: "ignore", detached: true })
|
|
43
|
+
const child = spawn("cmd", ["/c", "start", "", url], { stdio: "ignore", detached: true });
|
|
44
|
+
child.on("error", () => {
|
|
45
|
+
});
|
|
46
|
+
child.unref();
|
|
44
47
|
} else {
|
|
45
48
|
const cmd = process.platform === "darwin" ? "open" : "xdg-open";
|
|
46
|
-
spawn(cmd, [url], { stdio: "ignore", detached: true })
|
|
49
|
+
const child = spawn(cmd, [url], { stdio: "ignore", detached: true });
|
|
50
|
+
child.on("error", () => {
|
|
51
|
+
});
|
|
52
|
+
child.unref();
|
|
47
53
|
}
|
|
48
54
|
} catch {
|
|
49
55
|
}
|
|
@@ -59,6 +65,14 @@ async function api(path, init2 = {}) {
|
|
|
59
65
|
}
|
|
60
66
|
});
|
|
61
67
|
}
|
|
68
|
+
async function readJson(res) {
|
|
69
|
+
const text = await res.text();
|
|
70
|
+
try {
|
|
71
|
+
return text ? JSON.parse(text) : {};
|
|
72
|
+
} catch {
|
|
73
|
+
die(`Unexpected non-JSON response from ${API} (${res.status}).`);
|
|
74
|
+
}
|
|
75
|
+
}
|
|
62
76
|
async function login() {
|
|
63
77
|
const res = await api("/device/code", { method: "POST" });
|
|
64
78
|
if (!res.ok) die(`Couldn't start login (${res.status}).`);
|
|
@@ -80,7 +94,7 @@ async function login() {
|
|
|
80
94
|
});
|
|
81
95
|
const body = await r.json();
|
|
82
96
|
if (body.access_token) {
|
|
83
|
-
writeConfig({ token: body.access_token });
|
|
97
|
+
writeConfig({ ...readConfig(), token: body.access_token });
|
|
84
98
|
console.log("\n");
|
|
85
99
|
await whoami();
|
|
86
100
|
console.log(`
|
|
@@ -98,13 +112,13 @@ async function whoami() {
|
|
|
98
112
|
const res = await api("/cli/whoami", { token: requireToken() });
|
|
99
113
|
if (res.status === 401) die("Token invalid \u2014 run `fillo login` again.");
|
|
100
114
|
if (!res.ok) die(`whoami failed (${res.status}).`);
|
|
101
|
-
const me = await res
|
|
115
|
+
const me = await readJson(res);
|
|
102
116
|
console.log(` \x1B[32m\u2713\x1B[0m ${bold(me.email)} ${dim("\xB7")} ${me.workspace}`);
|
|
103
117
|
}
|
|
104
118
|
async function list() {
|
|
105
119
|
const res = await api("/cli/forms", { token: requireToken() });
|
|
106
120
|
if (!res.ok) die(`list failed (${res.status}).`);
|
|
107
|
-
const { forms } = await res
|
|
121
|
+
const { forms } = await readJson(res);
|
|
108
122
|
if (!forms.length) return console.log(" No forms yet.");
|
|
109
123
|
for (const f of forms) {
|
|
110
124
|
console.log(` ${f.status === "published" ? "\x1B[32m\u25CF\x1B[0m" : "\u25CB"} ${f.name} ${dim(f.id)}`);
|
|
@@ -118,9 +132,19 @@ async function loadSchema(file, allowCode) {
|
|
|
118
132
|
);
|
|
119
133
|
}
|
|
120
134
|
try {
|
|
121
|
-
if (abs.endsWith(".json"))
|
|
135
|
+
if (abs.endsWith(".json")) {
|
|
136
|
+
const parsed = JSON.parse(readFileSync(abs, "utf8"));
|
|
137
|
+
if (parsed == null) die(`${file} is empty \u2014 it must contain a form schema.`);
|
|
138
|
+
return parsed;
|
|
139
|
+
}
|
|
122
140
|
const mod = await import(pathToFileURL(abs).href);
|
|
123
|
-
|
|
141
|
+
const schema = mod.default ?? mod.schema ?? mod.form ?? mod.forms ?? mod.MARKETING_FORMS;
|
|
142
|
+
if (schema == null) {
|
|
143
|
+
die(
|
|
144
|
+
`${file} doesn't export a form schema \u2014 default-export it (or export \`schema\`/\`form\`/\`forms\`) and push again.`
|
|
145
|
+
);
|
|
146
|
+
}
|
|
147
|
+
return schema;
|
|
124
148
|
} catch (e) {
|
|
125
149
|
die(`Couldn't read ${file}: ${e.message}`);
|
|
126
150
|
}
|
|
@@ -167,7 +191,7 @@ async function push(file, flags) {
|
|
|
167
191
|
publish: !flags.draft
|
|
168
192
|
})
|
|
169
193
|
});
|
|
170
|
-
const body = await res
|
|
194
|
+
const body = await readJson(res);
|
|
171
195
|
if (!res.ok || !body.formId) die(body.error ?? `push failed (${res.status}).`);
|
|
172
196
|
printPushed(body.formId, body.url, !!body.updated, !!flags.draft);
|
|
173
197
|
}
|
|
@@ -185,7 +209,7 @@ async function push(file, flags) {
|
|
|
185
209
|
theme: item.theme ?? null
|
|
186
210
|
})
|
|
187
211
|
});
|
|
188
|
-
const body = await res
|
|
212
|
+
const body = await readJson(res);
|
|
189
213
|
if (!res.ok || !body.formId) die(body.error ?? `push failed (${res.status}).`);
|
|
190
214
|
printPushed(body.formId, body.slug ? `${API}/f/${body.slug}` : void 0, false, !!body.staged);
|
|
191
215
|
}
|
|
@@ -199,7 +223,7 @@ async function init(flags) {
|
|
|
199
223
|
method: "POST",
|
|
200
224
|
body: JSON.stringify({ email, source: "cli" })
|
|
201
225
|
});
|
|
202
|
-
const body = await res
|
|
226
|
+
const body = await readJson(res);
|
|
203
227
|
if (!res.ok || !body.key) die(body.error ?? `init failed (${res.status}).`);
|
|
204
228
|
writeConfig({ ...readConfig(), pk: body.key, claimUrl: body.claim?.url ?? void 0 });
|
|
205
229
|
console.log(`
|
|
@@ -282,6 +306,14 @@ function agentHelp() {
|
|
|
282
306
|
${dim("--run <id> --token <token> --api <url>")}
|
|
283
307
|
`);
|
|
284
308
|
}
|
|
309
|
+
function printVersion() {
|
|
310
|
+
try {
|
|
311
|
+
const pkg = JSON.parse(readFileSync(new URL("../package.json", import.meta.url), "utf8"));
|
|
312
|
+
console.log(pkg.version);
|
|
313
|
+
} catch {
|
|
314
|
+
console.log("unknown");
|
|
315
|
+
}
|
|
316
|
+
}
|
|
285
317
|
function help() {
|
|
286
318
|
console.log(`
|
|
287
319
|
${bold("fillo")} \u2014 create Fillo forms from your terminal
|
|
@@ -332,6 +364,9 @@ function parseFlags(args) {
|
|
|
332
364
|
async function main() {
|
|
333
365
|
const [cmd, ...rest] = process.argv.slice(2);
|
|
334
366
|
const { positional, flags } = parseFlags(rest);
|
|
367
|
+
if (cmd === "version" || cmd === "--version" || cmd === "-v" || flags.version === true || flags.v === true) {
|
|
368
|
+
return printVersion();
|
|
369
|
+
}
|
|
335
370
|
if (flags.help === true || flags.h === true) {
|
|
336
371
|
return cmd === "agent" ? agentHelp() : help();
|
|
337
372
|
}
|
|
@@ -340,9 +375,11 @@ async function main() {
|
|
|
340
375
|
return init(flags);
|
|
341
376
|
case "login":
|
|
342
377
|
return login();
|
|
343
|
-
case "logout":
|
|
344
|
-
|
|
378
|
+
case "logout": {
|
|
379
|
+
const { token, ...rest2 } = readConfig();
|
|
380
|
+
writeConfig(rest2);
|
|
345
381
|
return console.log(" Logged out.");
|
|
382
|
+
}
|
|
346
383
|
case "whoami":
|
|
347
384
|
return whoami();
|
|
348
385
|
case "push":
|
|
@@ -359,7 +396,8 @@ async function main() {
|
|
|
359
396
|
return help();
|
|
360
397
|
default:
|
|
361
398
|
console.error(`Unknown command: ${cmd}`);
|
|
362
|
-
|
|
399
|
+
help();
|
|
400
|
+
return process.exit(2);
|
|
363
401
|
}
|
|
364
402
|
}
|
|
365
403
|
main().catch((e) => die(e instanceof Error ? e.message : String(e)));
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@usefillo/cli",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.1",
|
|
4
4
|
"description": "Create and publish Fillo forms from your terminal — auth once, then your coding agent does the rest.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"keywords": [
|
|
@@ -10,6 +10,9 @@
|
|
|
10
10
|
],
|
|
11
11
|
"homepage": "https://fillo.so",
|
|
12
12
|
"type": "module",
|
|
13
|
+
"engines": {
|
|
14
|
+
"node": ">=18"
|
|
15
|
+
},
|
|
13
16
|
"bin": {
|
|
14
17
|
"fillo": "./dist/index.js"
|
|
15
18
|
},
|