@hogsend/cli 0.20.0 → 0.21.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/dist/bin.js CHANGED
@@ -61,13 +61,13 @@ async function request(baseUrl, key, missingKeyMessage, method, path, opts) {
61
61
  const msg = cause instanceof Error ? cause.message : String(cause);
62
62
  throw makeHttpError(`cannot reach ${baseUrl} (${msg})`, 0, void 0);
63
63
  }
64
- const text3 = await res.text();
64
+ const text4 = await res.text();
65
65
  let parsed;
66
- if (text3.length > 0) {
66
+ if (text4.length > 0) {
67
67
  try {
68
- parsed = JSON.parse(text3);
68
+ parsed = JSON.parse(text4);
69
69
  } catch {
70
- parsed = text3;
70
+ parsed = text4;
71
71
  }
72
72
  }
73
73
  if (!res.ok) {
@@ -149,7 +149,7 @@ function renderTable(rows, columns) {
149
149
  const widths = cols.map(
150
150
  (c) => Math.max(c.length, ...rows.map((r) => cell(r[c]).length))
151
151
  );
152
- const pad = (text3, width) => text3 + " ".repeat(width - text3.length);
152
+ const pad = (text4, width) => text4 + " ".repeat(width - text4.length);
153
153
  const header = cols.map((c, i) => color.bold(pad(c, widths[i] ?? 0))).join(" ");
154
154
  const sep4 = cols.map((_, i) => "-".repeat(widths[i] ?? 0)).join(" ");
155
155
  const body = rows.map((r) => cols.map((c, i) => pad(cell(r[c]), widths[i] ?? 0)).join(" ")).join("\n");
@@ -472,7 +472,7 @@ var campaignsCommand = {
472
472
 
473
473
  // src/commands/connect.ts
474
474
  import { parseArgs as parseArgs2 } from "util";
475
- import { confirm } from "@clack/prompts";
475
+ import { confirm, select, text } from "@clack/prompts";
476
476
 
477
477
  // src/lib/browser.ts
478
478
  import { spawn } from "child_process";
@@ -497,7 +497,7 @@ import { createServer } from "http";
497
497
  // src/lib/oauth.ts
498
498
  import { createHash, randomBytes } from "crypto";
499
499
  var POSTHOG_CLIENT_ID = "https://hogsend.com/.well-known/hogsend-posthog-client.json";
500
- var POSTHOG_SCOPES = "person:read person:write project:read hog_function:write";
500
+ var POSTHOG_SCOPES = "person:read person:write project:read organization:read hog_function:read hog_function:write feature_flag:read cohort:read cohort:write query:read insight:read event_definition:read property_definition:read";
501
501
  var LOOPBACK_PORTS = [8423, 8424, 8425];
502
502
  var CALLBACK_PATH = "/callback";
503
503
  var CALLBACK_TIMEOUT_MS = 3e5;
@@ -584,10 +584,10 @@ async function exchangeCode(opts) {
584
584
  })
585
585
  });
586
586
  if (!res.ok) {
587
- const text3 = await res.text().catch(() => "");
588
- let detail = text3;
587
+ const text4 = await res.text().catch(() => "");
588
+ let detail = text4;
589
589
  try {
590
- const parsed = JSON.parse(text3);
590
+ const parsed = JSON.parse(text4);
591
591
  if (typeof parsed === "object" && parsed !== null && typeof parsed.error === "string") {
592
592
  detail = parsed.error;
593
593
  }
@@ -776,7 +776,10 @@ var ConnectError = class extends Error {
776
776
  this.hint = hint;
777
777
  }
778
778
  };
779
- var HINT_NOT_CONFIGURED = "Set POSTHOG_API_KEY (and POSTHOG_HOST for EU/self-hosted) on the instance, redeploy, then re-run. The server's PostHog config tells the CLI which region to authorize against.";
779
+ var HINT_NOT_CONFIGURED = "Pass --posthog-host https://eu.posthog.com (or https://us.posthog.com, or your self-hosted app URL) to pick the region to authorize against. Alternatively set POSTHOG_HOST on the instance, redeploy, then re-run.";
780
+ var POSTHOG_EU_HOST = "https://eu.posthog.com";
781
+ var POSTHOG_US_HOST = "https://us.posthog.com";
782
+ var normalizeHost = (host) => host.replace(/\/+$/, "");
780
783
  var hintOauthUnsupported = (privateHost) => `${privateHost} doesn't advertise an OAuth server (discovery returned 404).
781
784
  Self-hosted PostHog builds may not ship OAuth. Use a personal API key instead:
782
785
 
@@ -804,12 +807,6 @@ skipped (a destination pointing at localhost would be unreachable).
804
807
  Once deployed, wire the loop against the real instance:
805
808
 
806
809
  hogsend connect posthog --provision-only --url https://your-instance`;
807
- var WEBHOOK_SECRET_NOTE = `Credential stored \u2014 but the PostHog -> Hogsend event loop needs a shared
808
- webhook secret, and this instance doesn't have one yet. Finish the loop:
809
-
810
- 1. Generate a secret: openssl rand -hex 32
811
- 2. Set it on the instance: POSTHOG_WEBHOOK_SECRET=<secret> (api AND worker)
812
- 3. Redeploy, then run: hogsend connect posthog --provision-only`;
813
810
  var errMsg = (err) => err instanceof Error ? err.message : String(err);
814
811
  var httpErrorBody = (err) => {
815
812
  if (!isHttpError(err)) return void 0;
@@ -843,13 +840,6 @@ function fromLoopbackError(err) {
843
840
  }
844
841
  }
845
842
  async function runProvisionOnly(deps, info, base) {
846
- if (info.webhookSecretConfigured === false) {
847
- deps.out.note(WEBHOOK_SECRET_NOTE, "Webhook secret missing");
848
- throw new ConnectError(
849
- "webhook_secret_missing",
850
- "POSTHOG_WEBHOOK_SECRET is not set on the instance \u2014 nothing to provision against"
851
- );
852
- }
853
843
  if (isLoopbackUrl(info.apiPublicUrl)) {
854
844
  deps.out.note(LOOPBACK_URL_NOTE, "Instance not publicly reachable");
855
845
  throw new ConnectError(
@@ -902,24 +892,39 @@ function printProvisioned(out, result) {
902
892
  ].join("\n")
903
893
  );
904
894
  }
895
+ async function resolvePrivateHost(deps, info, opts) {
896
+ if (info.privateHost !== null) {
897
+ return info.privateHost;
898
+ }
899
+ if (opts.posthogHost) {
900
+ return normalizeHost(opts.posthogHost);
901
+ }
902
+ if (deps.interactive) {
903
+ if (deps.selectRegion) {
904
+ return normalizeHost(await deps.selectRegion());
905
+ }
906
+ const useUs = await deps.confirm(
907
+ `Use PostHog US Cloud (${POSTHOG_US_HOST})? (No selects PostHog EU Cloud, ${POSTHOG_EU_HOST})`
908
+ );
909
+ return useUs ? POSTHOG_US_HOST : POSTHOG_EU_HOST;
910
+ }
911
+ throw new ConnectError(
912
+ "not_configured",
913
+ "this instance has no PostHog configuration",
914
+ HINT_NOT_CONFIGURED
915
+ );
916
+ }
905
917
  async function runConnectPosthog(deps, opts) {
906
918
  const base = deps.http.cfg.baseUrl;
907
919
  const info = await deps.out.step(
908
920
  `GET ${base}/v1/admin/analytics/connect-info`,
909
921
  () => deps.http.get("/v1/admin/analytics/connect-info")
910
922
  );
911
- const privateHost = info.privateHost;
912
- if (privateHost === null) {
913
- throw new ConnectError(
914
- "not_configured",
915
- "this instance has no PostHog configuration",
916
- HINT_NOT_CONFIGURED
917
- );
918
- }
919
923
  if (opts.provisionOnly) {
920
924
  return runProvisionOnly(deps, info, base);
921
925
  }
922
- if (info.hostExplicit === false) {
926
+ const privateHost = await resolvePrivateHost(deps, info, opts);
927
+ if (info.privateHost !== null && info.hostExplicit === false) {
923
928
  if (deps.interactive) {
924
929
  const proceed = await deps.confirm(
925
930
  `No POSTHOG_HOST set on the instance \u2014 assume PostHog US Cloud (${privateHost})?`
@@ -1068,6 +1073,13 @@ async function runConnectPosthog(deps, opts) {
1068
1073
  },
1069
1074
  credential: { stored: true, expiresAt }
1070
1075
  };
1076
+ const requestedScopes = POSTHOG_SCOPES.split(" ");
1077
+ const missingScopes = requestedScopes.filter((s) => !scopes.includes(s));
1078
+ if (missingScopes.length > 0) {
1079
+ deps.out.log(
1080
+ `note: PostHog granted ${scopes.length}/${requestedScopes.length} requested scope(s); missing: ${missingScopes.join(", ")}. Re-run \`hogsend connect posthog\` to grant the full set.`
1081
+ );
1082
+ }
1071
1083
  if (opts.noProvision) {
1072
1084
  return {
1073
1085
  verdict: "connected_no_provision",
@@ -1075,14 +1087,6 @@ async function runConnectPosthog(deps, opts) {
1075
1087
  provision: { attempted: false, skipped: "no_provision_flag" }
1076
1088
  };
1077
1089
  }
1078
- if (info.webhookSecretConfigured === false) {
1079
- deps.out.note(WEBHOOK_SECRET_NOTE, "Webhook secret missing");
1080
- return {
1081
- verdict: "connected_no_provision",
1082
- ...stored,
1083
- provision: { attempted: false, skipped: "webhook_secret_missing" }
1084
- };
1085
- }
1086
1090
  if (isLoopbackUrl(info.apiPublicUrl)) {
1087
1091
  deps.out.note(LOOPBACK_URL_NOTE, "Instance not publicly reachable");
1088
1092
  return {
@@ -1135,7 +1139,7 @@ function bail(value) {
1135
1139
  }
1136
1140
 
1137
1141
  // src/commands/connect.ts
1138
- var usage2 = `hogsend connect <provider> [--provision-only] [--no-provision] [--no-browser] [--json]
1142
+ var usage2 = `hogsend connect <provider> [--posthog-host <url>] [--provision-only] [--no-provision] [--no-browser] [--json]
1139
1143
 
1140
1144
  Connect this Hogsend instance to an analytics provider via OAuth. Providers:
1141
1145
 
@@ -1149,6 +1153,10 @@ The browser consent must happen on THIS machine (the OAuth callback lands on
1149
1153
  this command from your laptop, not from an SSH session on the server.
1150
1154
 
1151
1155
  Options:
1156
+ --posthog-host PostHog app/private host to authorize against, e.g.
1157
+ https://eu.posthog.com or https://us.posthog.com (NOT the
1158
+ i. ingestion host). Required when the instance has no
1159
+ PostHog config and you're running non-interactively.
1152
1160
  --provision-only Skip OAuth; (re-)provision the event loop using the
1153
1161
  already-stored credential.
1154
1162
  --no-provision Stop after storing the credential.
@@ -1163,6 +1171,7 @@ async function run2(ctx) {
1163
1171
  allowPositionals: true,
1164
1172
  strict: false,
1165
1173
  options: {
1174
+ "posthog-host": { type: "string" },
1166
1175
  "provision-only": { type: "boolean", default: false },
1167
1176
  "no-provision": { type: "boolean", default: false },
1168
1177
  "no-browser": { type: "boolean", default: false },
@@ -1204,13 +1213,33 @@ async function run2(ctx) {
1204
1213
  exchangeCode,
1205
1214
  openBrowser,
1206
1215
  confirm: async (message) => bail(await confirm({ message })),
1216
+ selectRegion: async () => {
1217
+ const choice = bail(
1218
+ await select({
1219
+ message: "Which PostHog region should Hogsend authorize against?",
1220
+ options: [
1221
+ { value: "https://eu.posthog.com", label: "PostHog EU Cloud" },
1222
+ { value: "https://us.posthog.com", label: "PostHog US Cloud" },
1223
+ { value: "custom", label: "Custom / self-hosted" }
1224
+ ]
1225
+ })
1226
+ );
1227
+ if (choice !== "custom") return choice;
1228
+ return bail(
1229
+ await text({
1230
+ message: "PostHog app/private host URL (e.g. https://posthog.example.com)",
1231
+ placeholder: "https://posthog.example.com"
1232
+ })
1233
+ );
1234
+ },
1207
1235
  now: () => /* @__PURE__ */ new Date()
1208
1236
  };
1209
1237
  try {
1210
1238
  const result = await runConnectPosthog(deps, {
1211
1239
  provisionOnly: Boolean(values2["provision-only"]),
1212
1240
  noProvision: Boolean(values2["no-provision"]),
1213
- noBrowser: Boolean(values2["no-browser"])
1241
+ noBrowser: Boolean(values2["no-browser"]),
1242
+ posthogHost: typeof values2["posthog-host"] === "string" ? values2["posthog-host"] : void 0
1214
1243
  });
1215
1244
  if (ctx.json) {
1216
1245
  ctx.out.json({ ok: true, ...result });
@@ -4928,7 +4957,7 @@ import { parseArgs as parseArgs18 } from "util";
4928
4957
 
4929
4958
  // src/commands/studio-admin.ts
4930
4959
  import { parseArgs as parseArgs17 } from "util";
4931
- import { password as passwordPrompt, text as text2 } from "@clack/prompts";
4960
+ import { password as passwordPrompt, text as text3 } from "@clack/prompts";
4932
4961
 
4933
4962
  // ../../node_modules/.pnpm/postgres@3.4.9/node_modules/postgres/src/index.js
4934
4963
  import os from "os";
@@ -5234,7 +5263,7 @@ function values(first, rest, parameters, types2, options) {
5234
5263
  const columns = rest.length ? rest.flat() : Object.keys(multi ? first[0] : first);
5235
5264
  return valuesBuilder(multi ? first : [first], parameters, types2, columns, options);
5236
5265
  }
5237
- function select(first, rest, parameters, types2, options) {
5266
+ function select2(first, rest, parameters, types2, options) {
5238
5267
  typeof first === "string" && (first = [first].concat(rest));
5239
5268
  if (Array.isArray(first))
5240
5269
  return escapeIdentifiers(first, options);
@@ -5251,10 +5280,10 @@ var builders = Object.entries({
5251
5280
  const x = values(...xs);
5252
5281
  return x === "()" ? "(null)" : x;
5253
5282
  },
5254
- select,
5255
- as: select,
5256
- returning: select,
5257
- "\\(": select,
5283
+ select: select2,
5284
+ as: select2,
5285
+ returning: select2,
5286
+ "\\(": select2,
5258
5287
  update(first, rest, parameters, types2, options) {
5259
5288
  return (rest.length ? rest.flat() : Object.keys(first)).map(
5260
5289
  (x) => escapeIdentifier(options.transform.column.to ? options.transform.column.to(x) : x) + "=" + stringifyValue("values", first[x], parameters, types2, options)
@@ -9602,7 +9631,7 @@ var PgText = class extends PgColumn {
9602
9631
  return "text";
9603
9632
  }
9604
9633
  };
9605
- function text(a, b2 = {}) {
9634
+ function text2(a, b2 = {}) {
9606
9635
  const { name, config } = getColumnNameAndConfig(a, b2);
9607
9636
  return new PgTextBuilder(name, config);
9608
9637
  }
@@ -9924,7 +9953,7 @@ function getPgColumnBuilders() {
9924
9953
  serial,
9925
9954
  smallint,
9926
9955
  smallserial,
9927
- text,
9956
+ text: text2,
9928
9957
  time,
9929
9958
  timestamp,
9930
9959
  uuid,
@@ -10933,14 +10962,14 @@ var PgDialect = class {
10933
10962
  const offsetSql = offset ? sql` offset ${offset}` : void 0;
10934
10963
  return sql`${leftChunk}${operatorChunk}${rightChunk}${orderBySql}${limitSql}${offsetSql}`;
10935
10964
  }
10936
- buildInsertQuery({ table, values: valuesOrSelect, onConflict, returning, withList, select: select2, overridingSystemValue_ }) {
10965
+ buildInsertQuery({ table, values: valuesOrSelect, onConflict, returning, withList, select: select3, overridingSystemValue_ }) {
10937
10966
  const valuesSqlList = [];
10938
10967
  const columns = table[Table.Symbol.Columns];
10939
10968
  const colEntries = Object.entries(columns).filter(([_, col]) => !col.shouldDisableInsert());
10940
10969
  const insertOrder = colEntries.map(
10941
10970
  ([, column]) => sql.identifier(this.casing.getColumnCasing(column))
10942
10971
  );
10943
- if (select2) {
10972
+ if (select3) {
10944
10973
  const select22 = valuesOrSelect;
10945
10974
  if (is(select22, SQL)) {
10946
10975
  valuesSqlList.push(select22);
@@ -12513,10 +12542,10 @@ var PgSelectBase = class extends PgSelectQueryBuilderBase {
12513
12542
  applyMixins(PgSelectBase, [QueryPromise]);
12514
12543
  function createSetOperator(type, isAll) {
12515
12544
  return (leftSelect, rightSelect, ...restSelects) => {
12516
- const setOperators = [rightSelect, ...restSelects].map((select2) => ({
12545
+ const setOperators = [rightSelect, ...restSelects].map((select3) => ({
12517
12546
  type,
12518
12547
  isAll,
12519
- rightSelect: select2
12548
+ rightSelect: select3
12520
12549
  }));
12521
12550
  for (const setOperator of setOperators) {
12522
12551
  if (!haveSameKeys(leftSelect.getSelectedFields(), setOperator.rightSelect.getSelectedFields())) {
@@ -12572,7 +12601,7 @@ var QueryBuilder = class {
12572
12601
  };
12573
12602
  with(...queries) {
12574
12603
  const self = this;
12575
- function select2(fields) {
12604
+ function select3(fields) {
12576
12605
  return new PgSelectBuilder({
12577
12606
  fields: fields ?? void 0,
12578
12607
  session: void 0,
@@ -12596,7 +12625,7 @@ var QueryBuilder = class {
12596
12625
  distinct: { on }
12597
12626
  });
12598
12627
  }
12599
- return { select: select2, selectDistinct, selectDistinctOn };
12628
+ return { select: select3, selectDistinct, selectDistinctOn };
12600
12629
  }
12601
12630
  select(fields) {
12602
12631
  return new PgSelectBuilder({
@@ -12785,21 +12814,21 @@ var PgInsertBuilder = class {
12785
12814
  ).setToken(this.authToken);
12786
12815
  }
12787
12816
  select(selectQuery) {
12788
- const select2 = typeof selectQuery === "function" ? selectQuery(new QueryBuilder()) : selectQuery;
12789
- if (!is(select2, SQL) && !haveSameKeys(this.table[Columns], select2._.selectedFields)) {
12817
+ const select3 = typeof selectQuery === "function" ? selectQuery(new QueryBuilder()) : selectQuery;
12818
+ if (!is(select3, SQL) && !haveSameKeys(this.table[Columns], select3._.selectedFields)) {
12790
12819
  throw new Error(
12791
12820
  "Insert select error: selected fields are not the same or are in a different order compared to the table definition"
12792
12821
  );
12793
12822
  }
12794
- return new PgInsertBase(this.table, select2, this.session, this.dialect, this.withList, true);
12823
+ return new PgInsertBase(this.table, select3, this.session, this.dialect, this.withList, true);
12795
12824
  }
12796
12825
  };
12797
12826
  var PgInsertBase = class extends QueryPromise {
12798
- constructor(table, values2, session2, dialect, withList, select2, overridingSystemValue_) {
12827
+ constructor(table, values2, session2, dialect, withList, select3, overridingSystemValue_) {
12799
12828
  super();
12800
12829
  this.session = session2;
12801
12830
  this.dialect = dialect;
12802
- this.config = { table, values: values2, withList, select: select2, overridingSystemValue_ };
12831
+ this.config = { table, values: values2, withList, select: select3, overridingSystemValue_ };
12803
12832
  }
12804
12833
  static [entityKind] = "PgInsert";
12805
12834
  config;
@@ -13502,7 +13531,7 @@ var PgDatabase = class {
13502
13531
  */
13503
13532
  with(...queries) {
13504
13533
  const self = this;
13505
- function select2(fields) {
13534
+ function select3(fields) {
13506
13535
  return new PgSelectBuilder({
13507
13536
  fields: fields ?? void 0,
13508
13537
  session: self.session,
@@ -13537,7 +13566,7 @@ var PgDatabase = class {
13537
13566
  function delete_(table) {
13538
13567
  return new PgDeleteBase(table, self.session, self.dialect, queries);
13539
13568
  }
13540
- return { select: select2, selectDistinct, selectDistinctOn, update, insert, delete: delete_ };
13569
+ return { select: select3, selectDistinct, selectDistinctOn, update, insert, delete: delete_ };
13541
13570
  }
13542
13571
  select(fields) {
13543
13572
  return new PgSelectBuilder({
@@ -14201,7 +14230,7 @@ var alertRules = pgTable(
14201
14230
  "alert_rules",
14202
14231
  {
14203
14232
  id: uuid("id").defaultRandom().primaryKey(),
14204
- name: text("name").notNull(),
14233
+ name: text2("name").notNull(),
14205
14234
  type: alertRuleTypeEnum("type").notNull(),
14206
14235
  threshold: jsonb("threshold").$type().notNull(),
14207
14236
  channel: alertChannelEnum("channel").notNull(),
@@ -14226,8 +14255,8 @@ var alertHistory = pgTable(
14226
14255
  id: uuid("id").defaultRandom().primaryKey(),
14227
14256
  alertRuleId: uuid("alert_rule_id").notNull().references(() => alertRules.id),
14228
14257
  payload: jsonb("payload").$type(),
14229
- deliveryStatus: text("delivery_status").notNull(),
14230
- error: text("error"),
14258
+ deliveryStatus: text2("delivery_status").notNull(),
14259
+ error: text2("error"),
14231
14260
  ...timestamps
14232
14261
  },
14233
14262
  (table) => [
@@ -14241,12 +14270,12 @@ var apiKeys = pgTable(
14241
14270
  "api_keys",
14242
14271
  {
14243
14272
  id: uuid("id").defaultRandom().primaryKey(),
14244
- organizationId: text("organization_id"),
14245
- name: text("name").notNull(),
14246
- keyPrefix: text("key_prefix").notNull(),
14247
- keyHash: text("key_hash").notNull().unique(),
14273
+ organizationId: text2("organization_id"),
14274
+ name: text2("name").notNull(),
14275
+ keyPrefix: text2("key_prefix").notNull(),
14276
+ keyHash: text2("key_hash").notNull().unique(),
14248
14277
  scopes: jsonb("scopes").$type().notNull().default(["read"]),
14249
- createdBy: text("created_by"),
14278
+ createdBy: text2("created_by"),
14250
14279
  lastUsedAt: timestamp("last_used_at", { withTimezone: true }),
14251
14280
  revokedAt: timestamp("revoked_at", { withTimezone: true }),
14252
14281
  expiresAt: timestamp("expires_at", { withTimezone: true }),
@@ -14263,13 +14292,13 @@ var auditLogs = pgTable(
14263
14292
  "audit_logs",
14264
14293
  {
14265
14294
  id: uuid("id").defaultRandom().primaryKey(),
14266
- actor: text("actor").notNull(),
14295
+ actor: text2("actor").notNull(),
14267
14296
  actorKeyId: uuid("actor_key_id"),
14268
- action: text("action").notNull(),
14269
- resource: text("resource").notNull(),
14270
- resourceId: text("resource_id"),
14297
+ action: text2("action").notNull(),
14298
+ resource: text2("resource").notNull(),
14299
+ resourceId: text2("resource_id"),
14271
14300
  detail: jsonb("detail").$type(),
14272
- ipAddress: text("ip_address"),
14301
+ ipAddress: text2("ip_address"),
14273
14302
  ...timestamps
14274
14303
  },
14275
14304
  (table) => [
@@ -14281,71 +14310,71 @@ var auditLogs = pgTable(
14281
14310
 
14282
14311
  // ../db/src/schema/auth.ts
14283
14312
  var user = pgTable("user", {
14284
- id: text("id").primaryKey(),
14285
- name: text("name").notNull(),
14286
- email: text("email").notNull().unique(),
14313
+ id: text2("id").primaryKey(),
14314
+ name: text2("name").notNull(),
14315
+ email: text2("email").notNull().unique(),
14287
14316
  emailVerified: boolean("email_verified").notNull().default(false),
14288
- image: text("image"),
14317
+ image: text2("image"),
14289
14318
  ...timestamps
14290
14319
  });
14291
14320
  var session = pgTable("session", {
14292
- id: text("id").primaryKey(),
14321
+ id: text2("id").primaryKey(),
14293
14322
  expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
14294
- token: text("token").notNull().unique(),
14295
- ipAddress: text("ip_address"),
14296
- userAgent: text("user_agent"),
14297
- userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
14298
- activeOrganizationId: text("active_organization_id"),
14323
+ token: text2("token").notNull().unique(),
14324
+ ipAddress: text2("ip_address"),
14325
+ userAgent: text2("user_agent"),
14326
+ userId: text2("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
14327
+ activeOrganizationId: text2("active_organization_id"),
14299
14328
  ...timestamps
14300
14329
  });
14301
14330
  var account = pgTable("account", {
14302
- id: text("id").primaryKey(),
14303
- accountId: text("account_id").notNull(),
14304
- providerId: text("provider_id").notNull(),
14305
- userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
14306
- accessToken: text("access_token"),
14307
- refreshToken: text("refresh_token"),
14308
- idToken: text("id_token"),
14331
+ id: text2("id").primaryKey(),
14332
+ accountId: text2("account_id").notNull(),
14333
+ providerId: text2("provider_id").notNull(),
14334
+ userId: text2("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
14335
+ accessToken: text2("access_token"),
14336
+ refreshToken: text2("refresh_token"),
14337
+ idToken: text2("id_token"),
14309
14338
  accessTokenExpiresAt: timestamp("access_token_expires_at", {
14310
14339
  withTimezone: true
14311
14340
  }),
14312
14341
  refreshTokenExpiresAt: timestamp("refresh_token_expires_at", {
14313
14342
  withTimezone: true
14314
14343
  }),
14315
- scope: text("scope"),
14316
- password: text("password"),
14344
+ scope: text2("scope"),
14345
+ password: text2("password"),
14317
14346
  ...timestamps
14318
14347
  });
14319
14348
  var verification = pgTable("verification", {
14320
- id: text("id").primaryKey(),
14321
- identifier: text("identifier").notNull(),
14322
- value: text("value").notNull(),
14349
+ id: text2("id").primaryKey(),
14350
+ identifier: text2("identifier").notNull(),
14351
+ value: text2("value").notNull(),
14323
14352
  expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
14324
14353
  ...timestamps
14325
14354
  });
14326
14355
  var organization = pgTable("organization", {
14327
- id: text("id").primaryKey(),
14328
- name: text("name").notNull(),
14329
- slug: text("slug").unique(),
14330
- logo: text("logo"),
14331
- metadata: text("metadata"),
14356
+ id: text2("id").primaryKey(),
14357
+ name: text2("name").notNull(),
14358
+ slug: text2("slug").unique(),
14359
+ logo: text2("logo"),
14360
+ metadata: text2("metadata"),
14332
14361
  ...timestamps
14333
14362
  });
14334
14363
  var member = pgTable("member", {
14335
- id: text("id").primaryKey(),
14336
- organizationId: text("organization_id").notNull().references(() => organization.id, { onDelete: "cascade" }),
14337
- userId: text("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
14338
- role: text("role").notNull().default("member"),
14364
+ id: text2("id").primaryKey(),
14365
+ organizationId: text2("organization_id").notNull().references(() => organization.id, { onDelete: "cascade" }),
14366
+ userId: text2("user_id").notNull().references(() => user.id, { onDelete: "cascade" }),
14367
+ role: text2("role").notNull().default("member"),
14339
14368
  ...timestamps
14340
14369
  });
14341
14370
  var invitation = pgTable("invitation", {
14342
- id: text("id").primaryKey(),
14343
- organizationId: text("organization_id").notNull().references(() => organization.id, { onDelete: "cascade" }),
14344
- email: text("email").notNull(),
14345
- role: text("role"),
14346
- status: text("status").notNull().default("pending"),
14371
+ id: text2("id").primaryKey(),
14372
+ organizationId: text2("organization_id").notNull().references(() => organization.id, { onDelete: "cascade" }),
14373
+ email: text2("email").notNull(),
14374
+ role: text2("role"),
14375
+ status: text2("status").notNull().default("pending"),
14347
14376
  expiresAt: timestamp("expires_at", { withTimezone: true }).notNull(),
14348
- inviterId: text("inviter_id").notNull().references(() => user.id, { onDelete: "cascade" }),
14377
+ inviterId: text2("inviter_id").notNull().references(() => user.id, { onDelete: "cascade" }),
14349
14378
  ...timestamps
14350
14379
  });
14351
14380
 
@@ -14354,12 +14383,12 @@ var bucketConfigs = pgTable(
14354
14383
  "bucket_configs",
14355
14384
  {
14356
14385
  id: uuid("id").defaultRandom().primaryKey(),
14357
- bucketId: text("bucket_id").notNull(),
14386
+ bucketId: text2("bucket_id").notNull(),
14358
14387
  enabled: boolean("enabled").notNull().default(true),
14359
14388
  // Stable hash of the normalized ConditionEval, written at boot. Diffed on the
14360
14389
  // next boot to detect a CRITERIA CHANGE and enqueue the re-evaluation job
14361
14390
  // (Section 6.6 B). Nullable until the first registration.
14362
- criteriaHash: text("criteria_hash"),
14391
+ criteriaHash: text2("criteria_hash"),
14363
14392
  ...timestamps
14364
14393
  },
14365
14394
  (table) => [uniqueIndex("bucket_configs_bucket_id_idx").on(table.bucketId)]
@@ -14371,13 +14400,13 @@ var bucketMemberships = pgTable(
14371
14400
  {
14372
14401
  id: uuid("id").defaultRandom().primaryKey(),
14373
14402
  // multi-tenant insurance (nullable today, NOT in the unique key — see note)
14374
- organizationId: text("organization_id"),
14403
+ organizationId: text2("organization_id"),
14375
14404
  // logical join to contacts.externalId — NO FK (matches userEvents /
14376
14405
  // journeyStates; membership rows can predate a contacts row).
14377
- userId: text("user_id").notNull(),
14378
- userEmail: text("user_email"),
14406
+ userId: text2("user_id").notNull(),
14407
+ userEmail: text2("user_email"),
14379
14408
  // denormalized so emitted events carry it
14380
- bucketId: text("bucket_id").notNull(),
14409
+ bucketId: text2("bucket_id").notNull(),
14381
14410
  status: bucketMembershipStatusEnum("status").notNull().default("active"),
14382
14411
  enteredAt: timestamp("entered_at", { withTimezone: true }).defaultNow().notNull(),
14383
14412
  leftAt: timestamp("left_at", { withTimezone: true }),
@@ -14390,7 +14419,7 @@ var bucketMemberships = pgTable(
14390
14419
  maxDwellAt: timestamp("max_dwell_at", { withTimezone: true }),
14391
14420
  lastEvaluatedAt: timestamp("last_evaluated_at", { withTimezone: true }),
14392
14421
  entryCount: integer("entry_count").notNull().default(1),
14393
- source: text("source"),
14422
+ source: text2("source"),
14394
14423
  // "event" | "reconcile" | "backfill" | "manual"
14395
14424
  context: jsonb("context").$type().default({}),
14396
14425
  // Per-membership dwell bookkeeping. JSON map keyed by dwellLabel → ISO of
@@ -14458,18 +14487,18 @@ var campaigns = pgTable(
14458
14487
  "campaigns",
14459
14488
  {
14460
14489
  id: uuid("id").defaultRandom().primaryKey(),
14461
- organizationId: text("organization_id"),
14462
- name: text("name").notNull(),
14490
+ organizationId: text2("organization_id"),
14491
+ name: text2("name").notNull(),
14463
14492
  // queued | sending | sent | failed
14464
- status: text("status").notNull().default("queued"),
14493
+ status: text2("status").notNull().default("queued"),
14465
14494
  // "list" | "bucket"
14466
- audienceKind: text("audience_kind").notNull(),
14495
+ audienceKind: text2("audience_kind").notNull(),
14467
14496
  // the list id (ListRegistry) or bucket id (BucketRegistry)
14468
- audienceId: text("audience_id").notNull(),
14469
- templateKey: text("template_key").notNull(),
14497
+ audienceId: text2("audience_id").notNull(),
14498
+ templateKey: text2("template_key").notNull(),
14470
14499
  props: jsonb("props").$type().default({}),
14471
- fromEmail: text("from_email"),
14472
- subject: text("subject"),
14500
+ fromEmail: text2("from_email"),
14501
+ subject: text2("subject"),
14473
14502
  /**
14474
14503
  * Optional client-supplied idempotency key (POST /v1/campaigns
14475
14504
  * `Idempotency-Key` header / body field). A retried create with the same key
@@ -14478,7 +14507,7 @@ var campaigns = pgTable(
14478
14507
  * idempotency key, double-sending the blast). Uniqueness is enforced by the
14479
14508
  * partial-unique index below (NULL keys are unconstrained).
14480
14509
  */
14481
- idempotencyKey: text("idempotency_key"),
14510
+ idempotencyKey: text2("idempotency_key"),
14482
14511
  totalRecipients: integer("total_recipients").notNull().default(0),
14483
14512
  sentCount: integer("sent_count").notNull().default(0),
14484
14513
  skippedCount: integer("skipped_count").notNull().default(0),
@@ -14502,7 +14531,7 @@ var contacts = pgTable(
14502
14531
  "contacts",
14503
14532
  {
14504
14533
  id: uuid("id").defaultRandom().primaryKey(),
14505
- organizationId: text("organization_id"),
14534
+ organizationId: text2("organization_id"),
14506
14535
  /**
14507
14536
  * Stable external/distinct id (= the `user_id` text key joined by every
14508
14537
  * contact-referencing table). NULLABLE since D1: contacts can be email-only
@@ -14511,21 +14540,21 @@ var contacts = pgTable(
14511
14540
  * — a soft-deleted loser row must be able to keep its stale external_id
14512
14541
  * until a merge re-points it.
14513
14542
  */
14514
- externalId: text("external_id"),
14515
- email: text("email"),
14543
+ externalId: text2("external_id"),
14544
+ email: text2("email"),
14516
14545
  /**
14517
14546
  * Stable anonymous/distinct id for the future anonymous→identified path.
14518
14547
  * NULLABLE. Like external_id, uniqueness is enforced by a partial-unique
14519
14548
  * index scoped to live, non-deleted rows.
14520
14549
  */
14521
- anonymousId: text("anonymous_id"),
14550
+ anonymousId: text2("anonymous_id"),
14522
14551
  /**
14523
14552
  * Opportunistic IANA-timezone cache (e.g. "America/New_York"). Populated
14524
14553
  * best-effort when a tz is resolved from PostHog person props. PostHog and
14525
14554
  * `properties` jsonb remain authoritative sources — this column sits below
14526
14555
  * them in the resolution precedence, so nothing is blocked on it.
14527
14556
  */
14528
- timezone: text("timezone"),
14557
+ timezone: text2("timezone"),
14529
14558
  properties: jsonb("properties").$type().default({}),
14530
14559
  firstSeenAt: timestamp("first_seen_at", { withTimezone: true }).defaultNow().notNull(),
14531
14560
  lastSeenAt: timestamp("last_seen_at", { withTimezone: true }).defaultNow().notNull(),
@@ -14556,15 +14585,15 @@ var contactAliases = pgTable(
14556
14585
  // The SURVIVOR a stale key resolves TO.
14557
14586
  contactId: uuid("contact_id").notNull().references(() => contacts.id, { onDelete: "cascade" }),
14558
14587
  // 'email' | 'external' | 'anonymous'
14559
- aliasKind: text("alias_kind").notNull(),
14588
+ aliasKind: text2("alias_kind").notNull(),
14560
14589
  // The stale key value (the loser's old external_id / normalized email /
14561
14590
  // anonymous_id).
14562
- aliasValue: text("alias_value").notNull(),
14591
+ aliasValue: text2("alias_value").notNull(),
14563
14592
  // Provenance: the loser contact id this alias came from (nullable — a
14564
14593
  // 'promote' alias may have no distinct loser row).
14565
14594
  fromContactId: uuid("from_contact_id"),
14566
14595
  // 'merge' | 'promote'
14567
- reason: text("reason").notNull(),
14596
+ reason: text2("reason").notNull(),
14568
14597
  ...timestamps
14569
14598
  },
14570
14599
  (table) => [
@@ -14582,10 +14611,10 @@ var deadLetterQueue = pgTable(
14582
14611
  "dead_letter_queue",
14583
14612
  {
14584
14613
  id: uuid("id").defaultRandom().primaryKey(),
14585
- source: text("source").notNull(),
14586
- sourceId: text("source_id"),
14614
+ source: text2("source").notNull(),
14615
+ sourceId: text2("source_id"),
14587
14616
  payload: jsonb("payload").$type().notNull(),
14588
- error: text("error").notNull(),
14617
+ error: text2("error").notNull(),
14589
14618
  retryCount: integer("retry_count").notNull().default(0),
14590
14619
  status: dlqStatusEnum("status").notNull().default("pending"),
14591
14620
  retriedAt: timestamp("retried_at", { withTimezone: true }),
@@ -14603,8 +14632,8 @@ var emailPreferences = pgTable(
14603
14632
  "email_preferences",
14604
14633
  {
14605
14634
  id: uuid("id").defaultRandom().primaryKey(),
14606
- userId: text("user_id").notNull(),
14607
- email: text("email").notNull(),
14635
+ userId: text2("user_id").notNull(),
14636
+ email: text2("email").notNull(),
14608
14637
  unsubscribedAll: boolean("unsubscribed_all").notNull().default(false),
14609
14638
  suppressed: boolean("suppressed").notNull().default(false),
14610
14639
  bounceCount: integer("bounce_count").notNull().default(0),
@@ -14626,15 +14655,15 @@ var journeyStates = pgTable(
14626
14655
  "journey_states",
14627
14656
  {
14628
14657
  id: uuid("id").defaultRandom().primaryKey(),
14629
- organizationId: text("organization_id"),
14630
- userId: text("user_id").notNull(),
14631
- userEmail: text("user_email").notNull(),
14632
- journeyId: text("journey_id").notNull(),
14633
- currentNodeId: text("current_node_id").notNull(),
14658
+ organizationId: text2("organization_id"),
14659
+ userId: text2("user_id").notNull(),
14660
+ userEmail: text2("user_email").notNull(),
14661
+ journeyId: text2("journey_id").notNull(),
14662
+ currentNodeId: text2("current_node_id").notNull(),
14634
14663
  status: journeyStatusEnum("status").notNull().default("active"),
14635
- hatchetRunId: text("hatchet_run_id"),
14664
+ hatchetRunId: text2("hatchet_run_id"),
14636
14665
  context: jsonb("context").$type().default({}),
14637
- errorMessage: text("error_message"),
14666
+ errorMessage: text2("error_message"),
14638
14667
  entryCount: integer("entry_count").notNull().default(1),
14639
14668
  completedAt: timestamp("completed_at", { withTimezone: true }),
14640
14669
  exitedAt: timestamp("exited_at", { withTimezone: true }),
@@ -14672,19 +14701,19 @@ var emailSends = pgTable(
14672
14701
  "email_sends",
14673
14702
  {
14674
14703
  id: uuid("id").defaultRandom().primaryKey(),
14675
- organizationId: text("organization_id"),
14704
+ organizationId: text2("organization_id"),
14676
14705
  journeyStateId: uuid("journey_state_id").references(() => journeyStates.id),
14677
14706
  // Denormalized recipient identity, set at send time. Lets reporting attribute
14678
14707
  // a send to a contact without joining journey_states, and captures journeyless
14679
14708
  // (raw/batch) sends that have no journey linkage. Both nullable.
14680
- userId: text("user_id"),
14681
- userEmail: text("user_email"),
14682
- templateKey: text("template_key"),
14683
- messageId: text("message_id"),
14684
- fromEmail: text("from_email").notNull(),
14685
- toEmail: text("to_email").notNull(),
14686
- subject: text("subject").notNull(),
14687
- category: text("category"),
14709
+ userId: text2("user_id"),
14710
+ userEmail: text2("user_email"),
14711
+ templateKey: text2("template_key"),
14712
+ messageId: text2("message_id"),
14713
+ fromEmail: text2("from_email").notNull(),
14714
+ toEmail: text2("to_email").notNull(),
14715
+ subject: text2("subject").notNull(),
14716
+ category: text2("category"),
14688
14717
  status: emailSendStatusEnum("status").notNull().default("queued"),
14689
14718
  sentAt: timestamp("sent_at", { withTimezone: true }),
14690
14719
  deliveredAt: timestamp("delivered_at", { withTimezone: true }),
@@ -14693,13 +14722,13 @@ var emailSends = pgTable(
14693
14722
  bouncedAt: timestamp("bounced_at", { withTimezone: true }),
14694
14723
  complainedAt: timestamp("complained_at", { withTimezone: true }),
14695
14724
  // Bounce classification from the Resend webhook (hard/soft/transient + reason).
14696
- bounceType: text("bounce_type"),
14697
- bounceReason: text("bounce_reason"),
14725
+ bounceType: text2("bounce_type"),
14726
+ bounceReason: text2("bounce_reason"),
14698
14727
  // Caller-supplied idempotency key (POST /v1/emails). A retry with the same
14699
14728
  // key short-circuits to the prior send instead of dispatching a duplicate —
14700
14729
  // mirrors the user_events idempotency pattern. Nullable: journey/system sends
14701
14730
  // don't set it.
14702
- idempotencyKey: text("idempotency_key"),
14731
+ idempotencyKey: text2("idempotency_key"),
14703
14732
  // Free-form per-send annotations. Set ONLY by test-mode redirected sends
14704
14733
  // today — `{ testMode: true, originalTo: <real recipient> }` — so Studio can
14705
14734
  // flag a TEST row and show who the mail was REALLY for. Nullable: normal
@@ -14735,8 +14764,8 @@ var importJobs = pgTable(
14735
14764
  "import_jobs",
14736
14765
  {
14737
14766
  id: uuid("id").defaultRandom().primaryKey(),
14738
- fileName: text("file_name"),
14739
- format: text("format").notNull(),
14767
+ fileName: text2("file_name"),
14768
+ format: text2("format").notNull(),
14740
14769
  status: importJobStatusEnum("status").notNull().default("pending"),
14741
14770
  totalRows: integer("total_rows"),
14742
14771
  processedRows: integer("processed_rows").notNull().default(0),
@@ -14752,7 +14781,7 @@ var journeyConfigs = pgTable(
14752
14781
  "journey_configs",
14753
14782
  {
14754
14783
  id: uuid("id").defaultRandom().primaryKey(),
14755
- journeyId: text("journey_id").notNull(),
14784
+ journeyId: text2("journey_id").notNull(),
14756
14785
  enabled: boolean("enabled").notNull().default(true),
14757
14786
  ...timestamps
14758
14787
  },
@@ -14767,9 +14796,9 @@ var journeyLogs = pgTable(
14767
14796
  {
14768
14797
  id: uuid("id").defaultRandom().primaryKey(),
14769
14798
  journeyStateId: uuid("journey_state_id").notNull().references(() => journeyStates.id, { onDelete: "cascade" }),
14770
- fromNodeId: text("from_node_id"),
14771
- toNodeId: text("to_node_id"),
14772
- action: text("action").notNull(),
14799
+ fromNodeId: text2("from_node_id"),
14800
+ toNodeId: text2("to_node_id"),
14801
+ action: text2("action").notNull(),
14773
14802
  detail: jsonb("detail").$type(),
14774
14803
  ...timestamps
14775
14804
  },
@@ -14784,12 +14813,12 @@ var trackedLinks = pgTable(
14784
14813
  {
14785
14814
  id: uuid("id").defaultRandom().primaryKey(),
14786
14815
  emailSendId: uuid("email_send_id").notNull().references(() => emailSends.id, { onDelete: "cascade" }),
14787
- originalUrl: text("original_url").notNull(),
14816
+ originalUrl: text2("original_url").notNull(),
14788
14817
  clickCount: integer("click_count").notNull().default(0),
14789
14818
  // Semantic link metadata, lifted from the template's data-hs-* attributes
14790
14819
  // at send time. NULL for plain tracked links. `event` is the consumer event
14791
14820
  // name emitted at click time; `eventProperties` its scalar payload.
14792
- event: text("event"),
14821
+ event: text2("event"),
14793
14822
  eventProperties: jsonb("event_properties").$type(),
14794
14823
  // Set exactly once by the click route when the semantic event is emitted —
14795
14824
  // the per-link emit-once gate today, and the provisional-then-confirm
@@ -14808,8 +14837,8 @@ var linkClicks = pgTable(
14808
14837
  {
14809
14838
  id: uuid("id").defaultRandom().primaryKey(),
14810
14839
  trackedLinkId: uuid("tracked_link_id").notNull().references(() => trackedLinks.id, { onDelete: "cascade" }),
14811
- ipAddress: text("ip_address"),
14812
- userAgent: text("user_agent"),
14840
+ ipAddress: text2("ip_address"),
14841
+ userAgent: text2("user_agent"),
14813
14842
  clickedAt: timestamp("clicked_at", { withTimezone: true }).defaultNow().notNull()
14814
14843
  },
14815
14844
  (table) => [
@@ -14825,11 +14854,11 @@ var providerCredentials = pgTable(
14825
14854
  id: uuid("id").defaultRandom().primaryKey(),
14826
14855
  // e.g. "posthog" — matches an AnalyticsProvider meta.id by convention,
14827
14856
  // but deliberately NOT foreign-keyed: providers are code-defined.
14828
- providerId: text("provider_id").notNull(),
14857
+ providerId: text2("provider_id").notNull(),
14829
14858
  // "oauth" today; "api_key" is the anticipated future kind.
14830
- kind: text("kind").notNull().default("oauth"),
14859
+ kind: text2("kind").notNull().default("oauth"),
14831
14860
  // Encrypted JSON: base64url(iv || ciphertext || gcmTag).
14832
- payload: text("payload").notNull(),
14861
+ payload: text2("payload").notNull(),
14833
14862
  ...timestamps
14834
14863
  },
14835
14864
  (table) => [
@@ -14847,11 +14876,11 @@ var userEvents = pgTable(
14847
14876
  "user_events",
14848
14877
  {
14849
14878
  id: uuid("id").defaultRandom().primaryKey(),
14850
- organizationId: text("organization_id"),
14851
- userId: text("user_id").notNull(),
14852
- event: text("event").notNull(),
14879
+ organizationId: text2("organization_id"),
14880
+ userId: text2("user_id").notNull(),
14881
+ event: text2("event").notNull(),
14853
14882
  properties: jsonb("properties").$type(),
14854
- idempotencyKey: text("idempotency_key"),
14883
+ idempotencyKey: text2("idempotency_key"),
14855
14884
  occurredAt: timestamp("occurred_at", { withTimezone: true }).defaultNow().notNull()
14856
14885
  },
14857
14886
  (table) => [
@@ -14872,15 +14901,15 @@ var webhookEndpoints = pgTable(
14872
14901
  "webhook_endpoints",
14873
14902
  {
14874
14903
  id: uuid("id").defaultRandom().primaryKey(),
14875
- organizationId: text("organization_id"),
14876
- url: text("url").notNull(),
14877
- description: text("description"),
14904
+ organizationId: text2("organization_id"),
14905
+ url: text2("url").notNull(),
14906
+ description: text2("description"),
14878
14907
  // The delivery adapter selector. "webhook" (the default) is the signed
14879
14908
  // Standard-Webhooks POST that existing subscribers receive — byte-identical
14880
14909
  // to before this column existed. Any other value (e.g. "posthog") selects a
14881
14910
  // delivery-time TRANSFORM adapter that reuses the same durable delivery
14882
14911
  // machinery but rewrites url/headers/body for a vendor destination.
14883
- kind: text("kind").notNull().default("webhook"),
14912
+ kind: text2("kind").notNull().default("webhook"),
14884
14913
  // Per-destination configuration for keyed adapters (e.g. PostHog's
14885
14914
  // `{ apiKey, host }`). Null for `kind="webhook"` (it reads `secret` instead).
14886
14915
  // Keyed destinations keep their credentials HERE, not in a fake `whsec_`.
@@ -14889,9 +14918,9 @@ var webhookEndpoints = pgTable(
14889
14918
  // Nullable: only `kind="webhook"` carries a signing secret; keyed
14890
14919
  // destinations authenticate via `config` and the webhook adapter is the only
14891
14920
  // reader of this column.
14892
- secret: text("secret"),
14921
+ secret: text2("secret"),
14893
14922
  // e.g. "whsec_AbCd" — safe to show on list/get. Nullable alongside `secret`.
14894
- secretPrefix: text("secret_prefix"),
14923
+ secretPrefix: text2("secret_prefix"),
14895
14924
  eventTypes: jsonb("event_types").$type().notNull().default([]),
14896
14925
  disabled: boolean("disabled").notNull().default(false),
14897
14926
  // written by the delivery task on a successful (2xx) delivery.
@@ -14912,13 +14941,13 @@ var webhookDeliveries = pgTable(
14912
14941
  id: uuid("id").defaultRandom().primaryKey(),
14913
14942
  endpointId: uuid("endpoint_id").notNull().references(() => webhookEndpoints.id, { onDelete: "cascade" }),
14914
14943
  // denormalized, nullable (MT deferred).
14915
- organizationId: text("organization_id"),
14944
+ organizationId: text2("organization_id"),
14916
14945
  // == Webhook-Id header; ONE per logical event, shared across endpoints +
14917
14946
  // reused across retries.
14918
- webhookId: text("webhook_id").notNull(),
14919
- eventType: text("event_type").notNull(),
14947
+ webhookId: text2("webhook_id").notNull(),
14948
+ eventType: text2("event_type").notNull(),
14920
14949
  // producer-side dedup (idempotencyKey/stateId/emailSendId/...).
14921
- dedupeKey: text("dedupe_key"),
14950
+ dedupeKey: text2("dedupe_key"),
14922
14951
  // the EXACT signed envelope { id, type, timestamp, data }.
14923
14952
  payload: jsonb("payload").$type().notNull(),
14924
14953
  status: webhookDeliveryStatusEnum("status").notNull().default("pending"),
@@ -14927,9 +14956,9 @@ var webhookDeliveries = pgTable(
14927
14956
  lastAttemptAt: timestamp("last_attempt_at", { withTimezone: true }),
14928
14957
  responseStatus: integer("response_status"),
14929
14958
  // truncated to ≤1KB in app.
14930
- responseBodySnippet: text("response_body_snippet"),
14959
+ responseBodySnippet: text2("response_body_snippet"),
14931
14960
  deliveredAt: timestamp("delivered_at", { withTimezone: true }),
14932
- lastError: text("last_error"),
14961
+ lastError: text2("last_error"),
14933
14962
  ...timestamps
14934
14963
  },
14935
14964
  (table) => [
@@ -15386,7 +15415,7 @@ async function resolveEmail(ctx, flags, defaultEmail) {
15386
15415
  ctx.out.fail("--email is required (no TTY to prompt).");
15387
15416
  }
15388
15417
  const value = bail(
15389
- await text2({
15418
+ await text3({
15390
15419
  message: "Admin email",
15391
15420
  placeholder: defaultEmail ?? "admin@example.com",
15392
15421
  initialValue: defaultEmail,