runlot 0.1.0-rc.76 → 0.1.0-rc.78

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.
Files changed (2) hide show
  1. package/dist/index.js +82 -35
  2. package/package.json +4 -4
package/dist/index.js CHANGED
@@ -5551,6 +5551,15 @@ var Client = class {
5551
5551
  `/v1/orgs/${encodeURIComponent(org)}/projects/${encodeURIComponent(name)}/deployments`
5552
5552
  );
5553
5553
  }
5554
+ /**
5555
+ * Scheduled runs: what the live deployment declares, when each fires next, and
5556
+ * the recent history (docs/cron.md §8). `limit` bounds the history rows only —
5557
+ * the schedules and the per-schedule last run are never paged.
5558
+ */
5559
+ getProjectCron(org, name, limit) {
5560
+ const qs = limit ? `?limit=${limit}` : "";
5561
+ return this.json("GET", `${this.projectPath(org, name)}/cron${qs}`);
5562
+ }
5554
5563
  /** The body is the bundle. One digest covers all of the code and the assets. */
5555
5564
  /**
5556
5565
  * Uploads the bundle. `headers` carries the provenance headers
@@ -6233,7 +6242,7 @@ var Client = class {
6233
6242
  };
6234
6243
 
6235
6244
  // src/index.ts
6236
- import { readFileSync as readFileSync6 } from "node:fs";
6245
+ import { existsSync as existsSync3, readFileSync as readFileSync6 } from "node:fs";
6237
6246
  import { spawnSync as spawnSync3 } from "node:child_process";
6238
6247
  import { createInterface } from "node:readline/promises";
6239
6248
  import { join as join6 } from "node:path";
@@ -6638,6 +6647,7 @@ async function buildBundle(dir, cfg, deps = {}) {
6638
6647
  const manifest = {};
6639
6648
  if (cfg.compatibilityDate) manifest.compatibilityDate = cfg.compatibilityDate;
6640
6649
  if (cfg.notFound) manifest.notFound = cfg.notFound;
6650
+ if (cfg.runWorkerFirst !== void 0) manifest.runWorkerFirst = cfg.runWorkerFirst;
6641
6651
  if (cfg.triggers?.crons?.length) manifest.triggers = { crons: cfg.triggers.crons };
6642
6652
  if (cfg.email === true) manifest.email = true;
6643
6653
  if (cfg.ai === true) manifest.ai = true;
@@ -7264,6 +7274,7 @@ var BOOL_FLAGS = {
7264
7274
  "-y": "yes",
7265
7275
  "--json": "json",
7266
7276
  "--no-follow": "noFollow",
7277
+ "--no-migrate": "noMigrate",
7267
7278
  "--new": "new",
7268
7279
  "--revoke": "revoke",
7269
7280
  "--public": "public",
@@ -8285,7 +8296,7 @@ async function reportCrash(err, argv) {
8285
8296
  }
8286
8297
  function envelope(x) {
8287
8298
  const eventId = crypto.randomUUID().replace(/-/g, "");
8288
- const version = true ? "0.1.0-rc.76 (50c023a)" : "dev";
8299
+ const version = true ? "0.1.0-rc.78 (1eca457)" : "dev";
8289
8300
  const event = {
8290
8301
  event_id: eventId,
8291
8302
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
@@ -9541,7 +9552,7 @@ var PROJECT_GROUPS = [
9541
9552
  "repo"
9542
9553
  ];
9543
9554
  var USAGE_HEAD = "runlot \u2014 a CLI for deploying apps and managing PostgreSQL";
9544
- var CLI_VERSION = true ? "0.1.0-rc.76 (50c023a)" : "dev";
9555
+ var CLI_VERSION = true ? "0.1.0-rc.78 (1eca457)" : "dev";
9545
9556
  var USAGE_BODY = [
9546
9557
  { text: " runlot login log in via browser (GitHub, and so on)" },
9547
9558
  { text: " runlot login <name> log in for local development (dev server only)" },
@@ -9942,6 +9953,51 @@ async function provision(c, org, project, cfg, ai) {
9942
9953
  }
9943
9954
  return out;
9944
9955
  }
9956
+ async function applyMigrations(opts) {
9957
+ const migrations = loadMigrations(opts.migrationsDir);
9958
+ const info = await connectInfoOf(client(opts.flags), opts.org, opts.project);
9959
+ const connect = async (fn) => {
9960
+ let lastErr;
9961
+ for (let attempt = 0; attempt < 6; attempt++) {
9962
+ try {
9963
+ return await withConnection(info, tlsChoice(opts.flags), fn);
9964
+ } catch (err) {
9965
+ lastErr = err;
9966
+ if (!/57P03|no record of project|ECONNREFUSED/i.test(errText(err))) throw err;
9967
+ await new Promise((r) => setTimeout(r, 2e3));
9968
+ }
9969
+ }
9970
+ throw lastErr;
9971
+ };
9972
+ return await connect(async (c) => {
9973
+ await c.query(LEDGER_DDL);
9974
+ const ledger = await c.query(
9975
+ `SELECT version, sha256 FROM schema_migrations`
9976
+ );
9977
+ const applied = new Map(ledger.rows.map((r) => [Number(r.version), r.sha256]));
9978
+ reconcile(applied, migrations);
9979
+ let count = 0;
9980
+ for (const m of migrations) {
9981
+ if (applied.has(m.version)) continue;
9982
+ await c.query("BEGIN");
9983
+ try {
9984
+ await c.query(m.sql);
9985
+ await c.query(
9986
+ `INSERT INTO schema_migrations (version, name, sha256) VALUES ($1, $2, $3)`,
9987
+ [m.version, m.name, m.sha256]
9988
+ );
9989
+ await c.query("COMMIT");
9990
+ } catch (err) {
9991
+ await c.query("ROLLBACK").catch(() => {
9992
+ });
9993
+ throw new Error(`Failed to apply ${pad2(m.version)}_${m.name}: ${errText(err)}`);
9994
+ }
9995
+ opts.log(`${pad2(m.version)}_${m.name}`);
9996
+ count++;
9997
+ }
9998
+ return count;
9999
+ });
10000
+ }
9945
10001
  async function pgCommand(sub, rest, flags, passthrough) {
9946
10002
  const dir = rest[0] ?? ".";
9947
10003
  switch (sub) {
@@ -9966,37 +10022,16 @@ async function pgCommand(sub, rest, flags, passthrough) {
9966
10022
  }
9967
10023
  case "migrate": {
9968
10024
  const { org, project } = targetOf(dir, flags);
9969
- const migrations = loadMigrations(flags.migrations ?? join6(dir, "migrations"));
9970
- const info = await connectInfoOf(client(flags), org, project);
9971
- return withConnection(info, tlsChoice(flags), async (c) => {
9972
- await c.query(LEDGER_DDL);
9973
- const ledger = await c.query(
9974
- `SELECT version, sha256 FROM schema_migrations`
9975
- );
9976
- const applied = new Map(ledger.rows.map((r) => [Number(r.version), r.sha256]));
9977
- reconcile(applied, migrations);
9978
- let count = 0;
9979
- for (const m of migrations) {
9980
- if (applied.has(m.version)) continue;
9981
- await c.query("BEGIN");
9982
- try {
9983
- await c.query(m.sql);
9984
- await c.query(
9985
- `INSERT INTO schema_migrations (version, name, sha256) VALUES ($1, $2, $3)`,
9986
- [m.version, m.name, m.sha256]
9987
- );
9988
- await c.query("COMMIT");
9989
- } catch (err) {
9990
- await c.query("ROLLBACK").catch(() => {
9991
- });
9992
- throw new Error(`Failed to apply ${pad2(m.version)}_${m.name}: ${errText(err)}`);
9993
- }
9994
- console.log(`${pad2(m.version)}_${m.name}`);
9995
- count++;
9996
- }
9997
- if (count === 0) console.log("No migrations to apply");
9998
- return 0;
10025
+ const count = await applyMigrations({
10026
+ dir,
10027
+ flags,
10028
+ org,
10029
+ project,
10030
+ migrationsDir: flags.migrations ?? join6(dir, "migrations"),
10031
+ log: (line) => console.log(line)
9999
10032
  });
10033
+ if (count === 0) console.log("No migrations to apply");
10034
+ return 0;
10000
10035
  }
10001
10036
  case "shell": {
10002
10037
  const { org, project } = targetOf(dir, flags);
@@ -10531,6 +10566,18 @@ async function main(argv) {
10531
10566
  const d = await c.deploy(org, project, built.bundle, provenanceHeaders(prov));
10532
10567
  console.log("Deploying\u2026");
10533
10568
  printDeployment(d);
10569
+ const migrationsDir = flags.migrations ?? join6(dir, "migrations");
10570
+ if (!flags.noMigrate && cfg.database && existsSync3(migrationsDir)) {
10571
+ const applied = await applyMigrations({
10572
+ dir,
10573
+ flags,
10574
+ org,
10575
+ project,
10576
+ migrationsDir,
10577
+ log: (line) => console.log(` migrated ${line}`)
10578
+ });
10579
+ if (applied > 0) console.log(`Applied ${applied} migration${applied === 1 ? "" : "s"}.`);
10580
+ }
10534
10581
  const detail = await c.getProject(org, project);
10535
10582
  for (const u of projectUrls(detail)) console.log(` ${u}`);
10536
10583
  return 0;
@@ -10646,9 +10693,9 @@ async function main(argv) {
10646
10693
  log: (line) => console.log(line)
10647
10694
  });
10648
10695
  case "rollback": {
10649
- const version = Number(rest[0]);
10696
+ const version = Number(/^v\d+$/i.test(rest[0] ?? "") ? rest[0].slice(1) : rest[0]);
10650
10697
  if (!Number.isInteger(version) || version < 1) {
10651
- throw new Error("Usage: runlot rollback <version> [dir]");
10698
+ throw new Error("Usage: runlot rollback <version> [dir] (for example: runlot rollback v2)");
10652
10699
  }
10653
10700
  const dir = rest[1] ?? ".";
10654
10701
  const { org, project } = targetOf(dir, flags);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "runlot",
3
- "version": "0.1.0-rc.76",
3
+ "version": "0.1.0-rc.78",
4
4
  "description": "runlot CLI — deploy apps and manage 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.76",
29
- "@runlot/pg": "0.1.0-rc.76",
30
- "@runlot/api": "0.1.0-rc.76"
28
+ "@runlot/config": "0.1.0-rc.78",
29
+ "@runlot/api": "0.1.0-rc.78",
30
+ "@runlot/pg": "0.1.0-rc.78"
31
31
  },
32
32
  "engines": {
33
33
  "node": ">=20"