Files

118 lines
3.5 KiB
JavaScript
Raw Permalink Normal View History

2026-08-13 21:38:42 +02:00
#!/usr/bin/env node
/**
2026-08-13 23:40:39 +02:00
* Upsert a platform admin with a tenant company (fixes empty-company 400s).
* Loads monorepo-root `.env` only for DATABASE_URL.
2026-08-13 21:38:42 +02:00
* Email/password are CLI flags only — never read from .env.
*
* Usage (from repo root):
* npm run seed:platform-admin -- --email you@example.com --password '…'
* npm run seed:platform-admin -- --email you@example.com --promote-only
2026-08-13 23:40:39 +02:00
* npm run seed:platform-admin -- --email you@example.com --password '…' --company 'Acme Ops'
2026-08-13 21:38:42 +02:00
*/
import { spawnSync } from "node:child_process";
import path from "node:path";
import { detectHostProfile, withGoLowMem } from "./lowmem-env.mjs";
import { loadRootEnv, repoRoot } from "./root-env.mjs";
const env = withGoLowMem(loadRootEnv(process.env), detectHostProfile());
function usage(msg) {
if (msg) console.error(msg);
console.error(`Usage:
npm run seed:platform-admin -- --email you@example.com --password 'strong-password'
npm run seed:platform-admin -- --email you@example.com --promote-only
2026-08-13 23:40:39 +02:00
npm run seed:platform-admin -- --email you@example.com --password '…' --company 'Acme Ops'
2026-08-13 21:38:42 +02:00
Email/password must be passed on the CLI (not stored in .env).
2026-08-13 23:40:39 +02:00
DATABASE_URL comes from the shell or monorepo-root .env.
Creates a company + admin membership + Free plan unless --no-company.`);
2026-08-13 21:38:42 +02:00
process.exit(1);
}
/** Parse `--key value` / `--flag` from argv after npm's `--`. */
function parseArgs(argv) {
2026-08-13 23:40:39 +02:00
const out = {
email: "",
password: "",
name: "",
company: "",
promoteOnly: false,
noCompany: false,
};
2026-08-13 21:38:42 +02:00
for (let i = 0; i < argv.length; i++) {
const a = argv[i];
if (a === "--promote-only") {
out.promoteOnly = true;
continue;
}
2026-08-13 23:40:39 +02:00
if (a === "--no-company") {
out.noCompany = true;
continue;
}
2026-08-13 21:38:42 +02:00
if (a === "--email" || a === "-email") {
out.email = String(argv[++i] || "").trim();
continue;
}
if (a === "--password" || a === "-password") {
out.password = String(argv[++i] || "");
continue;
}
if (a === "--name" || a === "-name") {
out.name = String(argv[++i] || "").trim();
continue;
}
2026-08-13 23:40:39 +02:00
if (a === "--company" || a === "-company") {
2026-08-13 23:43:53 +02:00
// Join remaining tokens until next --flag so unquoted "Admin Company" works.
const parts = [];
while (i + 1 < argv.length && !String(argv[i + 1]).startsWith("-")) {
parts.push(String(argv[++i]));
}
out.company = parts.join(" ").trim();
2026-08-13 23:40:39 +02:00
continue;
}
2026-08-13 21:38:42 +02:00
if (a === "--help" || a === "-h") usage();
usage(`Unknown argument: ${a}`);
}
return out;
}
const opts = parseArgs(process.argv.slice(2));
if (!env.DATABASE_URL) {
usage("DATABASE_URL is required (shell or monorepo-root .env)");
}
if (!opts.email || !opts.email.includes("@")) {
usage("--email is required");
}
if (!opts.promoteOnly && opts.password.length < 8) {
usage("--password is required (min 8 characters), or pass --promote-only");
}
const apiDir = path.join(repoRoot, "apps", "api");
const args = [
"run",
"./cmd/seed-platform-admin",
"-postgres",
env.DATABASE_URL,
"-email",
opts.email,
"-confirm",
];
2026-08-13 23:40:39 +02:00
if (opts.name) args.push("-name", opts.name);
if (opts.company) args.push("-company", opts.company);
if (opts.noCompany) args.push("-no-company");
2026-08-13 21:38:42 +02:00
if (opts.promoteOnly) {
args.push("-promote-only");
} else {
args.push("-password", opts.password);
}
console.log(`==> seed-platform-admin ${opts.email}`);
const r = spawnSync("go", args, {
cwd: apiDir,
env,
stdio: "inherit",
shell: false,
});
process.exit(r.status ?? 1);