runlot 0.1.0-rc.21 → 0.1.0-rc.22
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 +48 -186
- package/package.json +4 -4
package/dist/index.js
CHANGED
|
@@ -5609,7 +5609,7 @@ var Client = class {
|
|
|
5609
5609
|
*
|
|
5610
5610
|
* **데이터베이스가 없으면 409 `database_required`** 다 — 가입자 표가
|
|
5611
5611
|
* 프로젝트 DB 안이라 부여만 세우면 워커가 뜨는 순간 표가 없다. 부르는 쪽은
|
|
5612
|
-
* 그 코드를 잡아 `
|
|
5612
|
+
* 그 코드를 잡아 `"database": true` 선언을 안내한다 — 배포는 순서로 이 코드를 안 본다.
|
|
5613
5613
|
*/
|
|
5614
5614
|
grantAuth(org, name) {
|
|
5615
5615
|
return this.json("POST", `${this.projectPath(org, name)}/auth`);
|
|
@@ -6444,30 +6444,6 @@ function saveCredentialsFor(apiUrl, creds) {
|
|
|
6444
6444
|
function projectConfigPath(dir) {
|
|
6445
6445
|
return join2(resolve2(dir), "runlot.json");
|
|
6446
6446
|
}
|
|
6447
|
-
function recordStorageBinding(dir) {
|
|
6448
|
-
const path = projectConfigPath(dir);
|
|
6449
|
-
const cfg = loadProjectConfig(dir);
|
|
6450
|
-
if (cfg.storage === true) return false;
|
|
6451
|
-
cfg.storage = true;
|
|
6452
|
-
writeFileSync(path, JSON.stringify(cfg, null, 2) + "\n");
|
|
6453
|
-
return true;
|
|
6454
|
-
}
|
|
6455
|
-
function recordAuthBinding(dir) {
|
|
6456
|
-
const path = projectConfigPath(dir);
|
|
6457
|
-
const cfg = loadProjectConfig(dir);
|
|
6458
|
-
if (cfg.auth === true) return false;
|
|
6459
|
-
cfg.auth = true;
|
|
6460
|
-
writeFileSync(path, JSON.stringify(cfg, null, 2) + "\n");
|
|
6461
|
-
return true;
|
|
6462
|
-
}
|
|
6463
|
-
function recordDatabaseBinding(dir) {
|
|
6464
|
-
const path = projectConfigPath(dir);
|
|
6465
|
-
const cfg = loadProjectConfig(dir);
|
|
6466
|
-
if (cfg.database === true) return false;
|
|
6467
|
-
cfg.database = true;
|
|
6468
|
-
writeFileSync(path, JSON.stringify(cfg, null, 2) + "\n");
|
|
6469
|
-
return true;
|
|
6470
|
-
}
|
|
6471
6447
|
function loadProjectConfig(dir) {
|
|
6472
6448
|
const path = projectConfigPath(dir);
|
|
6473
6449
|
let raw;
|
|
@@ -7077,17 +7053,6 @@ function formatBytes(n) {
|
|
|
7077
7053
|
}
|
|
7078
7054
|
async function storageCommand(sub, rest, deps) {
|
|
7079
7055
|
switch (sub) {
|
|
7080
|
-
case "create":
|
|
7081
|
-
case "grant": {
|
|
7082
|
-
const dir = rest[0] ?? ".";
|
|
7083
|
-
const { org, project } = deps.target(dir);
|
|
7084
|
-
const st = await deps.client().grantStorage(org, project);
|
|
7085
|
-
if (deps.record(dir)) console.log(`runlot.json \uC5D0 "storage": true \uB97C \uAE30\uB85D\uD588\uC2B5\uB2C8\uB2E4`);
|
|
7086
|
-
console.log(
|
|
7087
|
-
`${org}/${project} \uC758 \uC2A4\uD1A0\uB9AC\uC9C0\uAC00 \uC900\uBE44\uB410\uC2B5\uB2C8\uB2E4. Worker \uC5D0\uC11C\uB294 env.storage \uB85C \uC4F8 \uC218 \uC788\uC2B5\uB2C8\uB2E4 (\uC0C1\uD55C ${formatBytes(st.quotaBytes)}).`
|
|
7088
|
-
);
|
|
7089
|
-
return 0;
|
|
7090
|
-
}
|
|
7091
7056
|
case "status":
|
|
7092
7057
|
case void 0: {
|
|
7093
7058
|
const { org, project } = deps.target(rest[0] ?? ".");
|
|
@@ -7097,7 +7062,9 @@ async function storageCommand(sub, rest, deps) {
|
|
|
7097
7062
|
return 0;
|
|
7098
7063
|
}
|
|
7099
7064
|
if (!st.granted) {
|
|
7100
|
-
console.log(
|
|
7065
|
+
console.log(
|
|
7066
|
+
`${org}/${project} \uC5D0\uB294 \uC2A4\uD1A0\uB9AC\uC9C0\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. runlot.json \uC5D0 "storage": true \uB97C \uC801\uACE0 \uBC30\uD3EC\uD558\uBA74 \uCF1C\uC9D1\uB2C8\uB2E4.`
|
|
7067
|
+
);
|
|
7101
7068
|
return 0;
|
|
7102
7069
|
}
|
|
7103
7070
|
console.log(`${org}/${project} ${formatBytes(st.usedBytes)} / ${formatBytes(st.quotaBytes)} ${st.prefix}`);
|
|
@@ -7413,7 +7380,7 @@ function describeSettings(s) {
|
|
|
7413
7380
|
function describeAuth(org, project, st) {
|
|
7414
7381
|
const out = [org + "/" + project];
|
|
7415
7382
|
if (!st.granted) {
|
|
7416
|
-
out.push(" \uB85C\uADF8\uC778 \uAEBC\uC9D0",
|
|
7383
|
+
out.push(" \uB85C\uADF8\uC778 \uAEBC\uC9D0", ' runlot.json \uC5D0 "auth": true \uB97C \uC801\uACE0 \uBC30\uD3EC\uD558\uBA74 \uCF1C\uC9D1\uB2C8\uB2E4.');
|
|
7417
7384
|
return out;
|
|
7418
7385
|
}
|
|
7419
7386
|
out.push(" \uB85C\uADF8\uC778 \uCF1C\uC9D0");
|
|
@@ -7448,33 +7415,6 @@ function describeAuth(org, project, st) {
|
|
|
7448
7415
|
}
|
|
7449
7416
|
async function authCommand(sub, rest, deps) {
|
|
7450
7417
|
switch (sub) {
|
|
7451
|
-
case "create":
|
|
7452
|
-
case "grant": {
|
|
7453
|
-
const dir = rest[0] ?? ".";
|
|
7454
|
-
const { org, project } = deps.target(dir);
|
|
7455
|
-
let st;
|
|
7456
|
-
try {
|
|
7457
|
-
st = await deps.client().grantAuth(org, project);
|
|
7458
|
-
} catch (err) {
|
|
7459
|
-
if (err instanceof ApiError && err.code === "database_required") {
|
|
7460
|
-
throw new Error(
|
|
7461
|
-
`${org}/${project} \uC5D0\uB294 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uAC00 \uC5C6\uC2B5\uB2C8\uB2E4. \uAC00\uC785\uC790 \uD14C\uC774\uBE14\uC774 \uC774 \uD504\uB85C\uC81D\uD2B8\uC758 \uB370\uC774\uD130\uBCA0\uC774\uC2A4 \uC548\uC5D0 \uC788\uC73C\uBBC0\uB85C \uB85C\uADF8\uC778\uC740 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uAC00 \uC788\uC5B4\uC57C \uCF24 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \`runlot pg create\` \uB97C \uBA3C\uC800 \uC2E4\uD589\uD558\uAC70\uB098 \`runlot add pg auth\` \uB85C \uD55C \uBC88\uC5D0 \uCF1C\uC138\uC694.`
|
|
7462
|
-
);
|
|
7463
|
-
}
|
|
7464
|
-
throw err;
|
|
7465
|
-
}
|
|
7466
|
-
if (deps.record(dir)) console.log(`runlot.json \uC5D0 "auth": true \uB97C \uAE30\uB85D\uD588\uC2B5\uB2C8\uB2E4`);
|
|
7467
|
-
console.log(
|
|
7468
|
-
`${org}/${project} \uC758 \uB85C\uADF8\uC778\uC774 \uC900\uBE44\uB410\uC2B5\uB2C8\uB2E4. Worker \uC5D0\uC11C\uB294 env.auth.user(request) \uB85C \uC77D\uC744 \uC218 \uC788\uC2B5\uB2C8\uB2E4.`
|
|
7469
|
-
);
|
|
7470
|
-
console.log("\uB85C\uADF8\uC778 \uD654\uBA74\uC740 /__runlot/auth/sign-in \uC785\uB2C8\uB2E4.");
|
|
7471
|
-
if (st.providers.length === 0) {
|
|
7472
|
-
console.log(
|
|
7473
|
-
"\uC18C\uC15C \uB85C\uADF8\uC778\uC744 \uC4F0\uB824\uBA74 `runlot auth provider set github --client-id <id>` \uCC98\uB7FC \uB4F1\uB85D\uD558\uC138\uC694."
|
|
7474
|
-
);
|
|
7475
|
-
}
|
|
7476
|
-
return 0;
|
|
7477
|
-
}
|
|
7478
7418
|
case "status":
|
|
7479
7419
|
case void 0: {
|
|
7480
7420
|
const { org, project } = deps.target(rest[0] ?? ".");
|
|
@@ -7511,7 +7451,7 @@ async function authCommand(sub, rest, deps) {
|
|
|
7511
7451
|
}
|
|
7512
7452
|
default:
|
|
7513
7453
|
throw new Error(
|
|
7514
|
-
`\uBAA8\uB974\uB294 auth \uD558\uC704 \uBA85\uB839\uC785\uB2C8\uB2E4: ${sub ?? "(\uC5C6\uC74C)"} \u2014
|
|
7454
|
+
`\uBAA8\uB974\uB294 auth \uD558\uC704 \uBA85\uB839\uC785\uB2C8\uB2E4: ${sub ?? "(\uC5C6\uC74C)"} \u2014 status | provider | set | delete \uC911 \uD558\uB098\uC5EC\uC57C \uD569\uB2C8\uB2E4. \uB2E4\uB978 \uB514\uB809\uD1A0\uB9AC\uB97C \uBCF4\uB824\uBA74 \`runlot auth status <dir>\` \uCC98\uB7FC \uB4A4\uC5D0 \uC801\uC73C\uC138\uC694.`
|
|
7515
7455
|
);
|
|
7516
7456
|
}
|
|
7517
7457
|
}
|
|
@@ -7597,45 +7537,6 @@ async function providerCommand(sub, rest, deps) {
|
|
|
7597
7537
|
}
|
|
7598
7538
|
}
|
|
7599
7539
|
|
|
7600
|
-
// src/add.ts
|
|
7601
|
-
var ADD_NAMES = ["pg", "auth", "storage"];
|
|
7602
|
-
var ORDER = ADD_NAMES;
|
|
7603
|
-
var BINDING = {
|
|
7604
|
-
pg: "env.db",
|
|
7605
|
-
auth: "env.auth",
|
|
7606
|
-
storage: "env.storage"
|
|
7607
|
-
};
|
|
7608
|
-
function parseAdd(args) {
|
|
7609
|
-
const picked = /* @__PURE__ */ new Set();
|
|
7610
|
-
let i = 0;
|
|
7611
|
-
while (i < args.length && ADD_NAMES.includes(args[i])) {
|
|
7612
|
-
picked.add(args[i]);
|
|
7613
|
-
i++;
|
|
7614
|
-
}
|
|
7615
|
-
const rest = args.slice(i);
|
|
7616
|
-
if (picked.size === 0) {
|
|
7617
|
-
if (rest.length === 0) {
|
|
7618
|
-
throw new Error(`\uC0AC\uC6A9\uBC95: runlot add <${ADD_NAMES.join("|")}>... [dir] (\uD558\uB098 \uC774\uC0C1 \uC9C0\uC815\uD569\uB2C8\uB2E4)`);
|
|
7619
|
-
}
|
|
7620
|
-
throw new Error(`\uBAA8\uB974\uB294 \uC774\uB984\uC785\uB2C8\uB2E4: ${rest[0]} \u2014 ${ADD_NAMES.join(" | ")} \uC911\uC5D0\uC11C \uACE0\uB974\uC138\uC694`);
|
|
7621
|
-
}
|
|
7622
|
-
if (rest.length > 1) {
|
|
7623
|
-
throw new Error(`\uBAA8\uB974\uB294 \uC774\uB984\uC785\uB2C8\uB2E4: ${rest[0]} \u2014 ${ADD_NAMES.join(" | ")} \uC911\uC5D0\uC11C \uACE0\uB974\uC138\uC694`);
|
|
7624
|
-
}
|
|
7625
|
-
return { names: ORDER.filter((n) => picked.has(n)), dir: rest[0] ?? "." };
|
|
7626
|
-
}
|
|
7627
|
-
async function addCommand(args, deps) {
|
|
7628
|
-
const { names, dir } = parseAdd(args);
|
|
7629
|
-
const plan = [...names];
|
|
7630
|
-
if (plan.includes("auth") && !plan.includes("pg") && !await deps.hasDatabase(dir)) {
|
|
7631
|
-
plan.unshift("pg");
|
|
7632
|
-
deps.log("\uB85C\uADF8\uC778\uC740 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uAC00 \uC788\uC5B4\uC57C \uCF24 \uC218 \uC788\uC2B5\uB2C8\uB2E4. \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uB3C4 \uD568\uAED8 \uCF2D\uB2C8\uB2E4.");
|
|
7633
|
-
}
|
|
7634
|
-
for (const name of plan) await deps.create(name, dir);
|
|
7635
|
-
deps.log(`${plan.map((n) => BINDING[n]).join(" \xB7 ")} \uB97C \uC4F8 \uC218 \uC788\uC2B5\uB2C8\uB2E4`);
|
|
7636
|
-
return 0;
|
|
7637
|
-
}
|
|
7638
|
-
|
|
7639
7540
|
// src/pg.ts
|
|
7640
7541
|
import { readFileSync as readFileSync4 } from "node:fs";
|
|
7641
7542
|
import { join as join3 } from "node:path";
|
|
@@ -8235,7 +8136,6 @@ var ALL_GROUPS = [
|
|
|
8235
8136
|
"pg",
|
|
8236
8137
|
"storage",
|
|
8237
8138
|
"auth",
|
|
8238
|
-
"add",
|
|
8239
8139
|
"access",
|
|
8240
8140
|
"secret",
|
|
8241
8141
|
"domain",
|
|
@@ -8256,7 +8156,6 @@ var PROJECT_GROUPS = [
|
|
|
8256
8156
|
"pg",
|
|
8257
8157
|
"storage",
|
|
8258
8158
|
"auth",
|
|
8259
|
-
"add",
|
|
8260
8159
|
"access",
|
|
8261
8160
|
"secret",
|
|
8262
8161
|
"domain",
|
|
@@ -8270,7 +8169,7 @@ var PROJECT_GROUPS = [
|
|
|
8270
8169
|
"repo"
|
|
8271
8170
|
];
|
|
8272
8171
|
var USAGE_HEAD = "runlot \u2014 \uC571 \uBC30\uD3EC\uC640 PostgreSQL \uAD00\uB9AC\uB97C \uC704\uD55C CLI";
|
|
8273
|
-
var CLI_VERSION = true ? "0.1.0-rc.
|
|
8172
|
+
var CLI_VERSION = true ? "0.1.0-rc.22 (45e8e51)" : "dev";
|
|
8274
8173
|
var USAGE_BODY = [
|
|
8275
8174
|
{ text: " runlot login \uBE0C\uB77C\uC6B0\uC800\uB85C \uB85C\uADF8\uC778\uD569\uB2C8\uB2E4 (GitHub \uB4F1)" },
|
|
8276
8175
|
{ text: " runlot login <\uC774\uB984> \uB85C\uCEEC \uAC1C\uBC1C\uC6A9 \uB85C\uADF8\uC778 (\uAC1C\uBC1C \uC11C\uBC84\uC5D0\uC11C\uB9CC)" },
|
|
@@ -8279,13 +8178,11 @@ var USAGE_BODY = [
|
|
|
8279
8178
|
{ text: " runlot org list \uCC38\uC5EC \uC911\uC778 \uC870\uC9C1 \uBAA9\uB85D", groups: ["org"] },
|
|
8280
8179
|
{ text: " runlot project create <name> \uD504\uB85C\uC81D\uD2B8\uB97C \uB9CC\uB4ED\uB2C8\uB2E4 (--org \uD544\uC694)", groups: ["project"] },
|
|
8281
8180
|
{ text: " runlot project list \uD504\uB85C\uC81D\uD2B8 \uBAA9\uB85D (--org \uD544\uC694)", groups: ["project"] },
|
|
8282
|
-
{ text: " runlot add <pg|auth|storage>\u2026 [dir] \uD544\uC694\uD55C \uAE30\uB2A5\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4 (\uC5EC\uB7EC \uAC1C\uB97C \uD55C \uBC88\uC5D0)", groups: ["add"] },
|
|
8283
8181
|
{ text: " runlot deploy [dir] \uBC88\uB4E4\uC744 \uB9CC\uB4E4\uC5B4 \uBC30\uD3EC\uD569\uB2C8\uB2E4", groups: ["deploy"] },
|
|
8284
8182
|
{ text: " runlot versions [dir] \uBC30\uD3EC \uC774\uB825", groups: ["versions"] },
|
|
8285
8183
|
{ text: " runlot rollback <version> [dir] \uC774\uC804 \uBC84\uC804\uC73C\uB85C \uB418\uB3CC\uB9BD\uB2C8\uB2E4", groups: ["rollback"] },
|
|
8286
8184
|
{ text: "" },
|
|
8287
|
-
{ text: " runlot pg
|
|
8288
|
-
{ text: " runlot pg bind [dir] runlot.json \uC5D0 \uB370\uC774\uD130\uBCA0\uC774\uC2A4 \uC0AC\uC6A9\uC744 \uAE30\uB85D\uD569\uB2C8\uB2E4", groups: ["pg"] },
|
|
8185
|
+
{ text: " runlot pg connect [dir] \uC811\uC18D \uC815\uBCF4\uB97C \uBCF4\uC5EC \uC90D\uB2C8\uB2E4 (\uBE44\uBC00\uBC88\uD638 \uD3EC\uD568)", groups: ["pg"] },
|
|
8289
8186
|
{ text: " runlot pg execute [dir] SQL \uC744 \uC2E4\uD589\uD569\uB2C8\uB2E4 (-c <sql> \uB610\uB294 -f <\uD30C\uC77C>)", groups: ["pg"] },
|
|
8290
8187
|
{ text: " runlot pg migrate [dir] migrations/NNNN_*.sql \uC744 \uC801\uC6A9\uD569\uB2C8\uB2E4", groups: ["pg"] },
|
|
8291
8188
|
{ text: " runlot pg shell [dir] [-- ...] psql \uB85C \uC811\uC18D\uD569\uB2C8\uB2E4 (-- \uB4A4\uB294 psql \uC5D0 \uADF8\uB300\uB85C \uC804\uB2EC)", groups: ["pg"] },
|
|
@@ -8302,11 +8199,9 @@ var USAGE_BODY = [
|
|
|
8302
8199
|
{ text: " runlot port-forward [dir] \uB85C\uADF8\uC778 \uC138\uC158\uC73C\uB85C \uC778\uC99D\uD558\uACE0 \uB85C\uCEEC \uD3EC\uD2B8\uB97C \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uC5D0 \uC5F0\uACB0\uD569\uB2C8\uB2E4", groups: ["port-forward"] },
|
|
8303
8200
|
{ text: " (--port 15432, --listen 127.0.0.1, Ctrl-C \uB85C \uC885\uB8CC)", groups: ["port-forward"] },
|
|
8304
8201
|
{ text: "" },
|
|
8305
|
-
{ text: " runlot storage create [dir] \uD30C\uC77C \uC800\uC7A5\uC18C\uB97C \uCD94\uAC00\uD569\uB2C8\uB2E4 (\uC6CC\uCEE4\uC5D0\uC11C env.storage\uB85C \uC0AC\uC6A9)", groups: ["storage"] },
|
|
8306
8202
|
{ text: " runlot storage [status] [dir] \uC800\uC7A5 \uC6A9\uB7C9\uACFC \uC0AC\uC6A9 \uD55C\uB3C4 (--json\uC73C\uB85C \uC6D0\uBCF8 \uCD9C\uB825)", groups: ["storage"] },
|
|
8307
8203
|
{ text: " runlot storage delete [dir] \uC2A4\uD1A0\uB9AC\uC9C0\uB97C \uD574\uC81C\uD569\uB2C8\uB2E4 (admin)", groups: ["storage"] },
|
|
8308
8204
|
{ text: "", groups: ["storage"] },
|
|
8309
|
-
{ text: " runlot auth create [dir] \uC571\uC5D0 \uC778\uC99D \uAE30\uB2A5\uC744 \uCD94\uAC00\uD569\uB2C8\uB2E4 (\uC6CC\uCEE4\uC5D0\uC11C env.auth\uB85C \uC0AC\uC6A9)", groups: ["auth"] },
|
|
8310
8205
|
{ text: " runlot auth [status] [dir] \uC124\uC815\xB7\uD504\uB85C\uBC14\uC774\uB354\xB7\uCF5C\uBC31 URL (--json \uC73C\uB85C \uC6D0\uBCF8 \uCD9C\uB825)", groups: ["auth"] },
|
|
8311
8206
|
{ text: " runlot auth provider set <p> \uC18C\uC15C \uB85C\uADF8\uC778\uC744 \uB4F1\uB85D\uD569\uB2C8\uB2E4 (--client-id, --client-secret, admin)", groups: ["auth"] },
|
|
8312
8207
|
{ text: " runlot auth provider rm <p> \uC18C\uC15C \uB85C\uADF8\uC778 \uC81C\uACF5\uC790 \uC124\uC815\uC744 \uC0AD\uC81C\uD569\uB2C8\uB2E4 (admin)", groups: ["auth"] },
|
|
@@ -8427,7 +8322,7 @@ var USAGE2 = [
|
|
|
8427
8322
|
""
|
|
8428
8323
|
].join("\n");
|
|
8429
8324
|
var HELP_GROUPS = new Set(ALL_GROUPS);
|
|
8430
|
-
var GROUPS_NEEDING_SUB = /* @__PURE__ */ new Set(["pg", "secret", "domain", "dns", "domains"
|
|
8325
|
+
var GROUPS_NEEDING_SUB = /* @__PURE__ */ new Set(["pg", "secret", "domain", "dns", "domains"]);
|
|
8431
8326
|
function groupUsage(group) {
|
|
8432
8327
|
const has = (l) => l.groups?.includes(group) === true;
|
|
8433
8328
|
const options = USAGE_OPTIONS.filter(has).map((l) => l.text);
|
|
@@ -8584,37 +8479,44 @@ async function portForwardCommand(rest, flags) {
|
|
|
8584
8479
|
);
|
|
8585
8480
|
return done;
|
|
8586
8481
|
}
|
|
8587
|
-
async function
|
|
8588
|
-
const
|
|
8589
|
-
|
|
8590
|
-
|
|
8591
|
-
|
|
8592
|
-
|
|
8593
|
-
|
|
8482
|
+
async function provision(c, org, project, cfg) {
|
|
8483
|
+
const out = [];
|
|
8484
|
+
if (cfg.database || cfg.auth) {
|
|
8485
|
+
const { db } = await c.getDatabase(org, project);
|
|
8486
|
+
if (!db) {
|
|
8487
|
+
await c.createDatabase(org, project);
|
|
8488
|
+
out.push(
|
|
8489
|
+
cfg.database ? `\uB370\uC774\uD130\uBCA0\uC774\uC2A4\uB97C \uB9CC\uB4E4\uC5C8\uC2B5\uB2C8\uB2E4. \uC6CC\uCEE4\uC5D0\uC11C\uB294 env.db, \uC811\uC18D \uC815\uBCF4\uB294 \`runlot pg connect\` \uC785\uB2C8\uB2E4.` : `\uB85C\uADF8\uC778\uC740 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uAC00 \uC788\uC5B4\uC57C \uD574\uC11C \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uB3C4 \uB9CC\uB4E4\uC5C8\uC2B5\uB2C8\uB2E4 (env.db).`
|
|
8490
|
+
);
|
|
8491
|
+
}
|
|
8492
|
+
}
|
|
8493
|
+
if (cfg.auth) {
|
|
8494
|
+
const st = await c.getAuth(org, project);
|
|
8495
|
+
if (!st.granted) {
|
|
8496
|
+
await c.grantAuth(org, project);
|
|
8497
|
+
out.push("\uB85C\uADF8\uC778\uC744 \uCF30\uC2B5\uB2C8\uB2E4. \uC6CC\uCEE4\uC5D0\uC11C\uB294 env.auth.user(request), \uD654\uBA74\uC740 /__runlot/auth/sign-in \uC785\uB2C8\uB2E4.");
|
|
8498
|
+
}
|
|
8499
|
+
}
|
|
8500
|
+
if (cfg.storage) {
|
|
8501
|
+
const st = await c.getStorage(org, project);
|
|
8502
|
+
if (!st.granted) {
|
|
8503
|
+
await c.grantStorage(org, project);
|
|
8504
|
+
out.push("\uD30C\uC77C \uC800\uC7A5\uC18C\uB97C \uCF30\uC2B5\uB2C8\uB2E4. \uC6CC\uCEE4\uC5D0\uC11C\uB294 env.storage \uC785\uB2C8\uB2E4.");
|
|
8505
|
+
}
|
|
8506
|
+
}
|
|
8507
|
+
return out;
|
|
8594
8508
|
}
|
|
8595
8509
|
async function pgCommand(sub, rest, flags, passthrough) {
|
|
8596
8510
|
const dir = rest[0] ?? ".";
|
|
8597
8511
|
switch (sub) {
|
|
8598
|
-
|
|
8599
|
-
|
|
8600
|
-
|
|
8601
|
-
|
|
8602
|
-
// 고치다 지운 경우가 이 명령의 자리다.
|
|
8603
|
-
case "bind": {
|
|
8604
|
-
const cfg = loadProjectConfig(dir);
|
|
8605
|
-
if (rest.length > 1) {
|
|
8606
|
-
throw new Error(bindRefusal(rest[1]));
|
|
8607
|
-
}
|
|
8608
|
-
if (flags.project !== void 0 && flags.project !== cfg.name) {
|
|
8609
|
-
throw new Error(bindRefusal(flags.project));
|
|
8610
|
-
}
|
|
8512
|
+
// 접속 정보. 만드는 명령은 없다 — `runlot.json` 의 `"database": true` 를
|
|
8513
|
+
// `runlot deploy` 가 읽어 만든다 (docs/provisioning.md). 첫 판의 `pg create`
|
|
8514
|
+
// 가 찍던 접속 문자열을 이 명령이 찍는다.
|
|
8515
|
+
case "connect": {
|
|
8611
8516
|
const { org, project } = targetOf(dir, flags);
|
|
8612
|
-
const
|
|
8613
|
-
|
|
8614
|
-
|
|
8615
|
-
}
|
|
8616
|
-
if (recordDatabaseBinding(dir)) console.log(`runlot.json \uC5D0 "database": true \uB97C \uAE30\uB85D\uD588\uC2B5\uB2C8\uB2E4`);
|
|
8617
|
-
else console.log(`runlot.json \uC5D0 \uC774\uBBF8 \uAE30\uB85D\uB418\uC5B4 \uC788\uC2B5\uB2C8\uB2E4`);
|
|
8517
|
+
const info = await connectInfoOf(client(flags), org, project);
|
|
8518
|
+
console.log(connectionUrl(info));
|
|
8519
|
+
console.log("\uC774 \uC811\uC18D \uBB38\uC790\uC5F4\uC5D0\uB294 \uBE44\uBC00\uBC88\uD638\uAC00 \uB4E4\uC5B4 \uC788\uC2B5\uB2C8\uB2E4. \uACF5\uAC1C\uB41C \uACF3\uC5D0 \uBD99\uC5EC \uB123\uC9C0 \uB9C8\uC138\uC694.");
|
|
8618
8520
|
return 0;
|
|
8619
8521
|
}
|
|
8620
8522
|
case "execute": {
|
|
@@ -8935,9 +8837,6 @@ async function usageCommand(rest, flags) {
|
|
|
8935
8837
|
console.log(formatUsage(usage, storage));
|
|
8936
8838
|
return 0;
|
|
8937
8839
|
}
|
|
8938
|
-
function bindRefusal(target) {
|
|
8939
|
-
return `${target} \uC5D0\uB294 \uC5F0\uACB0\uD560 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \uD55C \uD504\uB85C\uC81D\uD2B8 = \uD55C \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uB77C\uC11C \uB2E4\uB978 \uD504\uB85C\uC81D\uD2B8\uC758 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uB294 \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4. \`runlot pg bind\` \uB294 \uC774 \uB514\uB809\uD1A0\uB9AC\uC758 \uD504\uB85C\uC81D\uD2B8\uC5D0\uB9CC \uAE30\uB85D\uC744 \uB0A8\uAE41\uB2C8\uB2E4.`;
|
|
8940
|
-
}
|
|
8941
8840
|
function authDeps(flags) {
|
|
8942
8841
|
return {
|
|
8943
8842
|
target: (dir) => targetOf(dir, flags),
|
|
@@ -8947,29 +8846,9 @@ function authDeps(flags) {
|
|
|
8947
8846
|
ask: askLine,
|
|
8948
8847
|
interactive: process.stdin.isTTY === true,
|
|
8949
8848
|
clientId: flags.clientId,
|
|
8950
|
-
clientSecret: flags.clientSecret
|
|
8951
|
-
record: recordAuthBinding
|
|
8849
|
+
clientSecret: flags.clientSecret
|
|
8952
8850
|
};
|
|
8953
8851
|
}
|
|
8954
|
-
async function createBinding(name, dir, flags) {
|
|
8955
|
-
switch (name) {
|
|
8956
|
-
case "pg":
|
|
8957
|
-
await createDatabaseAt(dir, flags);
|
|
8958
|
-
return;
|
|
8959
|
-
case "auth":
|
|
8960
|
-
await authCommand("create", [dir], authDeps(flags));
|
|
8961
|
-
return;
|
|
8962
|
-
case "storage":
|
|
8963
|
-
await storageCommand("create", [dir], {
|
|
8964
|
-
target: (dir2) => targetOf(dir2, flags),
|
|
8965
|
-
client: () => client(flags),
|
|
8966
|
-
json: false,
|
|
8967
|
-
confirm: (question) => confirmYes(question, confirmOpts(flags)),
|
|
8968
|
-
record: recordStorageBinding
|
|
8969
|
-
});
|
|
8970
|
-
return;
|
|
8971
|
-
}
|
|
8972
|
-
}
|
|
8973
8852
|
function repoDeps(flags) {
|
|
8974
8853
|
return {
|
|
8975
8854
|
client: () => client(flags),
|
|
@@ -9156,14 +9035,7 @@ async function main(argv) {
|
|
|
9156
9035
|
await createProjectWithHint(c, org, project);
|
|
9157
9036
|
console.log(`\uD504\uB85C\uC81D\uD2B8 ${org}/${project} \uC744(\uB97C) \uB9CC\uB4E4\uC5C8\uC2B5\uB2C8\uB2E4`);
|
|
9158
9037
|
}
|
|
9159
|
-
|
|
9160
|
-
const { db } = await c.getDatabase(org, project);
|
|
9161
|
-
if (!db) {
|
|
9162
|
-
console.error(
|
|
9163
|
-
`\uACBD\uACE0: runlot.json \uC5D0\uB294 \uB370\uC774\uD130\uBCA0\uC774\uC2A4\uB97C \uC4F4\uB2E4\uACE0 \uB418\uC5B4 \uC788\uC9C0\uB9CC ${org}/${project} \uC5D0 \uC5C6\uC2B5\uB2C8\uB2E4. \`runlot pg create\` \uB97C \uC2E4\uD589\uD558\uC138\uC694. \uC774 \uBC30\uD3EC\uC5D0\uC11C\uB294 env.db \uB97C \uC4F8 \uC218 \uC5C6\uC2B5\uB2C8\uB2E4.`
|
|
9164
|
-
);
|
|
9165
|
-
}
|
|
9166
|
-
}
|
|
9038
|
+
for (const line of await provision(c, org, project, cfg)) console.log(line);
|
|
9167
9039
|
console.log(`\uC62C\uB9AC\uB294 \uC911\u2026 (${(built.bundle.length / 1024).toFixed(1)} KiB)`);
|
|
9168
9040
|
const d = await c.deploy(org, project, built.bundle);
|
|
9169
9041
|
console.log("\uBC30\uD3EC\uD558\uB294 \uC911\u2026");
|
|
@@ -9206,8 +9078,7 @@ async function main(argv) {
|
|
|
9206
9078
|
target: (dir) => targetOf(dir, flags),
|
|
9207
9079
|
client: () => client(flags),
|
|
9208
9080
|
json: flags.json === true,
|
|
9209
|
-
confirm: (question) => confirmYes(question, confirmOpts(flags))
|
|
9210
|
-
record: recordStorageBinding
|
|
9081
|
+
confirm: (question) => confirmYes(question, confirmOpts(flags))
|
|
9211
9082
|
});
|
|
9212
9083
|
// 자체 Git 호스팅 (docs/git-hosting.md §12.1, §19). `repo` 는 프로젝트
|
|
9213
9084
|
// 명령이다 — 저장소는 프로젝트의 것이라 대상을 `pg` 와 같은 규칙으로 읽는다.
|
|
@@ -9225,18 +9096,6 @@ async function main(argv) {
|
|
|
9225
9096
|
// (docs/auth.md §1).
|
|
9226
9097
|
case "auth":
|
|
9227
9098
|
return authCommand(rest[0], rest.slice(1), authDeps(flags));
|
|
9228
|
-
// 회차 5 — 랜딩의 `runlot add pg auth storage` 한 줄. 각각의 create 를
|
|
9229
|
-
// 그대로 부른다.
|
|
9230
|
-
case "add":
|
|
9231
|
-
return addCommand(rest, {
|
|
9232
|
-
create: (name, dir) => createBinding(name, dir, flags),
|
|
9233
|
-
hasDatabase: async (dir) => {
|
|
9234
|
-
const { org, project } = targetOf(dir, flags);
|
|
9235
|
-
const { db } = await client(flags).getDatabase(org, project);
|
|
9236
|
-
return db === true;
|
|
9237
|
-
},
|
|
9238
|
-
log: (line) => console.log(line)
|
|
9239
|
-
});
|
|
9240
9099
|
case "logs":
|
|
9241
9100
|
return logsCommand(rest, flags);
|
|
9242
9101
|
case "secret":
|
|
@@ -9303,3 +9162,6 @@ main(process.argv.slice(2)).then(
|
|
|
9303
9162
|
process.exit(1);
|
|
9304
9163
|
}
|
|
9305
9164
|
);
|
|
9165
|
+
export {
|
|
9166
|
+
provision
|
|
9167
|
+
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "runlot",
|
|
3
|
-
"version": "0.1.0-rc.
|
|
3
|
+
"version": "0.1.0-rc.22",
|
|
4
4
|
"description": "runlot CLI — 앱 배포와 PostgreSQL 관리",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -25,9 +25,9 @@
|
|
|
25
25
|
"@types/pg": "^8.23.1",
|
|
26
26
|
"typescript": "^5.7.2",
|
|
27
27
|
"pg": "^8.23.0",
|
|
28
|
-
"@runlot/config": "0.1.0-rc.
|
|
29
|
-
"@runlot/api": "0.1.0-rc.
|
|
30
|
-
"@runlot/pg": "0.1.0-rc.
|
|
28
|
+
"@runlot/config": "0.1.0-rc.22",
|
|
29
|
+
"@runlot/api": "0.1.0-rc.22",
|
|
30
|
+
"@runlot/pg": "0.1.0-rc.22"
|
|
31
31
|
},
|
|
32
32
|
"engines": {
|
|
33
33
|
"node": ">=20"
|