@1db/cli 0.1.1 → 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/README.md +1 -0
- package/bin/1db.mjs +41 -0
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,7 @@ npx @1db/cli init acme.com # scan + add the site, write DB_* vars to .env.lo
|
|
|
13
13
|
npx @1db/cli send acme.com # send a test lead
|
|
14
14
|
npx @1db/cli leads acme.com # see it arrive
|
|
15
15
|
npx @1db/cli keys acme.com # print the site's endpoint, key and form slug
|
|
16
|
+
npx @1db/cli form acme.com --name "Quote request" # add another form, print its slug
|
|
16
17
|
```
|
|
17
18
|
|
|
18
19
|
Run `npx @1db/cli help` for every command, or `npm i -g @1db/cli` to get a plain `1db` command. Zero dependencies, Node 18+.
|
package/bin/1db.mjs
CHANGED
|
@@ -72,6 +72,31 @@ const commands = {
|
|
|
72
72
|
writeCredentials(result, { ...flags, env: flags["env-file"] ? flags.env : false });
|
|
73
73
|
},
|
|
74
74
|
|
|
75
|
+
async form({ positional, flags }) {
|
|
76
|
+
const website = positional[0];
|
|
77
|
+
if (!website || typeof flags.name !== "string") {
|
|
78
|
+
throw new CliError('Usage: 1db form <website> --name "Quote request" [--fields "email*,name,phone:phone,message:textarea"] [--preset "B2B"] [--slug quote]');
|
|
79
|
+
}
|
|
80
|
+
const result = await api("/v1/agent/forms", {
|
|
81
|
+
method: "POST",
|
|
82
|
+
body: {
|
|
83
|
+
website,
|
|
84
|
+
name: flags.name,
|
|
85
|
+
slug: typeof flags.slug === "string" ? flags.slug : undefined,
|
|
86
|
+
preset: typeof flags.preset === "string" ? flags.preset : undefined,
|
|
87
|
+
fields: typeof flags.fields === "string" ? parseFieldList(flags.fields) : undefined,
|
|
88
|
+
},
|
|
89
|
+
});
|
|
90
|
+
if (flags.json) return json(result);
|
|
91
|
+
const form = result.forms.find((f) => f.slug === result.formSlug);
|
|
92
|
+
print(`${result.created ? green("Created") : "Found"} ${bold(form.name)} on ${result.website.name}`);
|
|
93
|
+
print(dim(`Fields: ${form.fields.map((f) => f.key + (f.required ? "*" : "")).join(", ")}`));
|
|
94
|
+
// Its own env var, so DB_FORM_SLUG keeps pointing at the site's existing form
|
|
95
|
+
print(`\n${result.formEnvVar}=${form.slug}`);
|
|
96
|
+
print(dim(`\nPost its leads to ${result.leadsUrl} with {"formSlug": "${form.slug}", ...} and the site's DB_API_KEY.`));
|
|
97
|
+
print(dim(`Test it: ${CMD} send ${result.website.slug} --form ${form.slug}`));
|
|
98
|
+
},
|
|
99
|
+
|
|
75
100
|
async send({ positional, flags }) {
|
|
76
101
|
const [website, ...pairs] = positional;
|
|
77
102
|
if (!website) throw new CliError("Usage: 1db send <website> [email=jane@acme.com message=\"Hi\" ...] [--form slug]");
|
|
@@ -129,6 +154,9 @@ const commands = {
|
|
|
129
154
|
1db init <domain> Scan + add a website, write its keys to .env.local
|
|
130
155
|
[--name "Acme"] [--env-file .env] [--prefix VITE_|NEXT_PUBLIC_|PUBLIC_] [--no-env]
|
|
131
156
|
1db keys <website> Print a website's endpoint, key and form slug
|
|
157
|
+
1db form <website> --name "Quote request"
|
|
158
|
+
Add another form to a website and print its slug
|
|
159
|
+
[--fields "email*,name,phone:phone,message:textarea"] [--preset "B2B"] [--slug quote]
|
|
132
160
|
1db send <website> [k=v ...] Send a (test) lead through the real ingest endpoint
|
|
133
161
|
1db leads [website] [--limit 20] Most recent leads
|
|
134
162
|
1db mcp [--install] Print (or run) the command that adds 1DB's MCP server to Claude Code
|
|
@@ -162,6 +190,19 @@ function writeCredentials(result, flags) {
|
|
|
162
190
|
print(dim(`Test it: 1db send ${site.slug}`));
|
|
163
191
|
}
|
|
164
192
|
|
|
193
|
+
/** "email*,name,phone:phone" → [{ key: "email", required: true }, { key: "name" }, { key: "phone", type: "phone" }] */
|
|
194
|
+
function parseFieldList(spec) {
|
|
195
|
+
return spec
|
|
196
|
+
.split(",")
|
|
197
|
+
.map((s) => s.trim())
|
|
198
|
+
.filter(Boolean)
|
|
199
|
+
.map((s) => {
|
|
200
|
+
const required = s.endsWith("*");
|
|
201
|
+
const [key, type] = s.replace(/\*$/, "").split(":");
|
|
202
|
+
return { key, ...(type ? { type } : {}), ...(required ? { required } : {}) };
|
|
203
|
+
});
|
|
204
|
+
}
|
|
205
|
+
|
|
165
206
|
// ---------- main ----------
|
|
166
207
|
const [name = "help", ...rest] = process.argv.slice(2);
|
|
167
208
|
const command = commands[name === "--help" || name === "-h" ? "help" : name];
|