@happyvertical/smrt-cli 0.51.14 → 0.51.16

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 (27) hide show
  1. package/AGENTS.md +1 -0
  2. package/dist/ApiKey-BZmbOTnL-Dz-PO2sa.js +157 -0
  3. package/dist/ApiKeyCollection-Bfb_nw81-Dks_0546.js +2 -0
  4. package/dist/AuditLogCollection-B1YonCAP-Db9tLDtf.js +2 -0
  5. package/dist/NostrIdentity-n70E0vck-CZwoR7Rs.js +4189 -0
  6. package/dist/NostrIdentityCollection-Ca74dkaL-DESXyrjY.js +2 -0
  7. package/dist/OidcIdentity-CChQnYNH-DV9jiJ5r.js +117 -0
  8. package/dist/OidcIdentityCollection-D3L0WYbM-C85jz9CB.js +2 -0
  9. package/dist/ProfileAssetCollection-V8u4wqSL-BKz6v8py.js +2 -0
  10. package/dist/ProfileCollection-BvhD2cfL-CT6ctQ3l.js +1753 -0
  11. package/dist/ProfileMetadataCollection-DxX_BJKV-StatXt-E.js +2 -0
  12. package/dist/ProfileMetafieldCollection-CMKhVi2I--ba-T4qA.js +2 -0
  13. package/dist/ProfileRelationshipCollection-DUVgaIqf-B4TDc4TQ.js +2 -0
  14. package/dist/ProfileRelationshipTermCollection-DtA9OM23-1ZkGUm00.js +2 -0
  15. package/dist/ProfileRelationshipType-BRiRka6t-Dw1efEX5.js +101 -0
  16. package/dist/ProfileRelationshipTypeCollection-BdXwd7Kf-GEu0alx6.js +2 -0
  17. package/dist/{commands-BhDS-TVS.js → commands-CL85adn5.js} +95 -21
  18. package/dist/{config-DfBo4hHU.js → config-hqNo4lzH.js} +1 -13
  19. package/dist/dist-9EA_5mOX.js +142 -0
  20. package/dist/dist-BIA7A6wF.js +3712 -0
  21. package/dist/dist-mLcl4Ttr.js +1487 -0
  22. package/dist/index.js +14 -14
  23. package/dist/{json-validator-CjX8fHx9.js → json-validator-oEN7eUI3.js} +1 -1
  24. package/dist/oidcProvisioningPrimitives-CjOkg3Zd-DhC5lyKE.js +161 -0
  25. package/dist/resolveIdentity-73HQnTlT-DQB4z5h5.js +2 -0
  26. package/dist/rolldown-runtime-8H4AJuhK.js +14 -0
  27. package/package.json +8 -7
@@ -0,0 +1,2 @@
1
+ import { v as ProfileMetadataCollection_exports } from "./dist-BIA7A6wF.js";
2
+ export { ProfileMetadataCollection_exports as n };
@@ -0,0 +1,2 @@
1
+ import { h as ProfileMetafieldCollection_exports } from "./dist-BIA7A6wF.js";
2
+ export { ProfileMetafieldCollection_exports as n };
@@ -0,0 +1,2 @@
1
+ import { f as ProfileRelationshipCollection_exports } from "./dist-BIA7A6wF.js";
2
+ export { ProfileRelationshipCollection_exports as n };
@@ -0,0 +1,2 @@
1
+ import { l as ProfileRelationshipTermCollection_exports } from "./dist-BIA7A6wF.js";
2
+ export { ProfileRelationshipTermCollection_exports as n };
@@ -0,0 +1,101 @@
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
2
+ import { n as __exportAll$1 } from "./NostrIdentity-n70E0vck-CZwoR7Rs.js";
3
+ import { SmrtObject, field, smrt } from "@happyvertical/smrt-core";
4
+ //#region ../profiles/dist/chunks/ProfileRelationshipType-BRiRka6t.js
5
+ var ProfileRelationshipType_BRiRka6t_exports = /* @__PURE__ */ __exportAll({
6
+ n: () => ProfileRelationshipType_exports,
7
+ t: () => ProfileRelationshipType
8
+ });
9
+ var ProfileRelationshipType_exports = /* @__PURE__ */ __exportAll$1({ ProfileRelationshipType: () => ProfileRelationshipType });
10
+ var __defProp = Object.defineProperty;
11
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
12
+ var __decorateClass = (decorators, target, key, kind) => {
13
+ var result = kind > 1 ? void 0 : kind ? __getOwnPropDesc(target, key) : target;
14
+ for (var i = decorators.length - 1, decorator; i >= 0; i--) if (decorator = decorators[i]) result = (kind ? decorator(target, key, result) : decorator(result)) || result;
15
+ if (kind && result) __defProp(target, key, result);
16
+ return result;
17
+ };
18
+ function getReciprocalHandlers() {
19
+ if (!globalThis.__smrtProfileRelationshipHandlers) globalThis.__smrtProfileRelationshipHandlers = /* @__PURE__ */ new Map();
20
+ return globalThis.__smrtProfileRelationshipHandlers;
21
+ }
22
+ var DEFAULT_HANDLERS = {
23
+ friend: async (from, to, context) => {
24
+ await to.addRelationship(from, "friend", context);
25
+ },
26
+ spouse: async (from, to) => {
27
+ await to.addRelationship(from, "spouse");
28
+ },
29
+ partner: async (from, to, context) => {
30
+ await to.addRelationship(from, "partner", context);
31
+ },
32
+ colleague: async (from, to, context) => {
33
+ await to.addRelationship(from, "colleague", context);
34
+ },
35
+ sibling: async (from, to) => {
36
+ await to.addRelationship(from, "sibling");
37
+ }
38
+ };
39
+ if (!globalThis.__smrtProfileRelationshipHandlersInitialized) {
40
+ globalThis.__smrtProfileRelationshipHandlersInitialized = true;
41
+ for (const [slug, handler] of Object.entries(DEFAULT_HANDLERS)) getReciprocalHandlers().set(slug, handler);
42
+ }
43
+ var ProfileRelationshipType = class extends SmrtObject {
44
+ name = "";
45
+ reciprocal = true;
46
+ constructor(options = {}) {
47
+ super(options);
48
+ if (options.name) this.name = options.name;
49
+ if (options.reciprocal !== void 0) this.reciprocal = options.reciprocal;
50
+ }
51
+ /**
52
+ * Convenience method for slug-based lookup
53
+ *
54
+ * @param slug - The slug to search for
55
+ * @returns ProfileRelationshipType instance or null if not found
56
+ */
57
+ static async getBySlug(_slug) {
58
+ return null;
59
+ }
60
+ /**
61
+ * Register a custom reciprocal handler for a relationship type
62
+ *
63
+ * @param slug - The relationship type slug
64
+ * @param handler - The handler function to execute when creating reciprocal relationship
65
+ */
66
+ static registerReciprocalHandler(slug, handler) {
67
+ getReciprocalHandlers().set(slug, handler);
68
+ }
69
+ /**
70
+ * Get the reciprocal handler for a relationship type
71
+ *
72
+ * @param slug - The relationship type slug
73
+ * @returns The handler function or undefined
74
+ */
75
+ static getReciprocalHandler(slug) {
76
+ return getReciprocalHandlers().get(slug);
77
+ }
78
+ /**
79
+ * Check if a relationship type is reciprocal
80
+ *
81
+ * @param slug - The relationship type slug
82
+ * @returns True if reciprocal, false otherwise
83
+ */
84
+ static async isReciprocal(slug) {
85
+ return (await ProfileRelationshipType.getBySlug(slug))?.reciprocal || false;
86
+ }
87
+ };
88
+ __decorateClass([field({ required: true })], ProfileRelationshipType.prototype, "name", 2);
89
+ ProfileRelationshipType = __decorateClass([smrt({
90
+ tableStrategy: "sti",
91
+ api: { include: [
92
+ "list",
93
+ "get",
94
+ "create",
95
+ "update"
96
+ ] },
97
+ mcp: { include: ["list", "get"] },
98
+ cli: { skipApiCheck: true }
99
+ })], ProfileRelationshipType);
100
+ //#endregion
101
+ export { ProfileRelationshipType_BRiRka6t_exports as n, ProfileRelationshipType as t };
@@ -0,0 +1,2 @@
1
+ import { o as ProfileRelationshipTypeCollection_exports } from "./dist-BIA7A6wF.js";
2
+ export { ProfileRelationshipTypeCollection_exports as n };
@@ -1,5 +1,5 @@
1
- import { t as DEFAULT_CLI_CONFIG } from "./config-DfBo4hHU.js";
2
1
  import { t as resolveManifestEntryPackageName } from "./index.js";
2
+ import { t as DEFAULT_CLI_CONFIG } from "./config-hqNo4lzH.js";
3
3
  import { createRequire } from "node:module";
4
4
  import * as fs from "node:fs";
5
5
  import { existsSync, mkdirSync, readFileSync, realpathSync, writeFileSync } from "node:fs";
@@ -145,7 +145,7 @@ var configExportCommand = {
145
145
  process.exit(1);
146
146
  }
147
147
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
148
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
148
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
149
149
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
150
150
  if (!config.database?.url || config.database.url === ":memory:") {
151
151
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -1264,7 +1264,7 @@ var dbDiffCommand = {
1264
1264
  return;
1265
1265
  }
1266
1266
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
1267
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
1267
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
1268
1268
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
1269
1269
  if (!config.database?.url || config.database.url === ":memory:") {
1270
1270
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -1587,7 +1587,7 @@ var dbHistoryCommand = {
1587
1587
  let db;
1588
1588
  try {
1589
1589
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
1590
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
1590
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
1591
1591
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
1592
1592
  if (!config.database?.url || config.database.url === ":memory:") {
1593
1593
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -1855,7 +1855,7 @@ var dbOrphansCommand = {
1855
1855
  let db;
1856
1856
  try {
1857
1857
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
1858
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
1858
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
1859
1859
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
1860
1860
  if (!config.database?.url || config.database.url === ":memory:") {
1861
1861
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -2157,7 +2157,7 @@ var dbPruneCommand = {
2157
2157
  let db;
2158
2158
  try {
2159
2159
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
2160
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
2160
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
2161
2161
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
2162
2162
  if (!config.database?.url) {
2163
2163
  const message = "Database not configured. Set database.url in smrt.config.ts.";
@@ -2317,7 +2317,7 @@ var dbRollbackCommand = {
2317
2317
  const markOnly = options["mark-only"] ?? options.markOnly;
2318
2318
  try {
2319
2319
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
2320
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
2320
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
2321
2321
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
2322
2322
  if (!config.database?.url || config.database.url === ":memory:") {
2323
2323
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -2592,7 +2592,7 @@ async function runLiveSchemaParity(options = {}) {
2592
2592
  let db;
2593
2593
  try {
2594
2594
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
2595
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
2595
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
2596
2596
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
2597
2597
  if (!config.database?.url || config.database.url === ":memory:") return {
2598
2598
  report: null,
@@ -3154,7 +3154,7 @@ var dbStatusCommand = {
3154
3154
  let db;
3155
3155
  try {
3156
3156
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
3157
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
3157
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
3158
3158
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
3159
3159
  if (!config.database?.url || config.database.url === ":memory:") {
3160
3160
  if (options.json) console.log(JSON.stringify({ error: "Database not configured" }));
@@ -3449,7 +3449,7 @@ async function getDispatchBus() {
3449
3449
  const { createDispatchBus } = await import("@happyvertical/smrt-core");
3450
3450
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
3451
3451
  const { getDatabase } = await import("@happyvertical/sql");
3452
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
3452
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
3453
3453
  const dbConfig = getPackageConfig("cli", DEFAULT_CLI_CONFIG).database;
3454
3454
  if (!dbConfig?.url) throw new Error("Database not configured. Set database.url in smrt.config.ts or use --db option.");
3455
3455
  let db;
@@ -4384,7 +4384,7 @@ var exportCommand = {
4384
4384
  let db;
4385
4385
  try {
4386
4386
  const { getConfig, getPackageConfig } = await import("@happyvertical/smrt-config");
4387
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
4387
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
4388
4388
  const smrtConfig = getConfig();
4389
4389
  const cliConfig = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
4390
4390
  if (!smrtConfig) {
@@ -6858,7 +6858,7 @@ var dbDropFrameworkBaseTablesCommand = {
6858
6858
  const dryRun = Boolean(options["dry-run"]);
6859
6859
  try {
6860
6860
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
6861
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
6861
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
6862
6862
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
6863
6863
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:drop-framework-base-tables. Configure database.url in smrt.config.ts (or DATABASE_URL).");
6864
6864
  const dbType = config.database.type || "sqlite";
@@ -6908,6 +6908,79 @@ var dbDropFrameworkBaseTablesCommand = {
6908
6908
  }
6909
6909
  };
6910
6910
  //#endregion
6911
+ //#region src/commands/db-materialize-tenant-hierarchy.ts
6912
+ /**
6913
+ * `smrt db:materialize-tenant-hierarchy` (smrt#3036).
6914
+ *
6915
+ * Backfills `tenants.hierarchy_path` / `hierarchy_level` from each row's
6916
+ * `parent_tenant_id` chain. `Tenant.save()` in `@happyvertical/smrt-users`
6917
+ * now maintains both; this repairs rows written before it did, which left `inheritsToDescendants` and the declared ancestor-read
6918
+ * policy failing closed. Idempotent; refuses (writing nothing) when any
6919
+ * tenant's parent chain is broken.
6920
+ */
6921
+ var dbMaterializeTenantHierarchyCommand = {
6922
+ name: "db:materialize-tenant-hierarchy",
6923
+ description: "Backfill tenant hierarchy_path/hierarchy_level from parent_tenant_id (smrt-users). Idempotent; run after db:migrate.",
6924
+ aliases: ["materialize-tenant-hierarchy", "tenancy:materialize-hierarchy"],
6925
+ args: [],
6926
+ options: {
6927
+ "dry-run": {
6928
+ type: "boolean",
6929
+ description: "Report the tenants that would change without writing.",
6930
+ default: false
6931
+ },
6932
+ table: {
6933
+ type: "string",
6934
+ description: "Tenant table name (default: tenants)."
6935
+ }
6936
+ },
6937
+ handler: async (_args, options) => {
6938
+ let db;
6939
+ try {
6940
+ const { getPackageConfig } = await import("@happyvertical/smrt-config");
6941
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
6942
+ const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
6943
+ if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:materialize-tenant-hierarchy. Configure database.url in smrt.config.ts (or DATABASE_URL).");
6944
+ const dbType = config.database.type || "sqlite";
6945
+ const { getDatabase } = await import("@happyvertical/sql");
6946
+ const { materializeTenantHierarchy, TenantHierarchyMaterializationError } = await import("./dist-BIA7A6wF.js");
6947
+ db = await getDatabase({
6948
+ type: dbType,
6949
+ url: config.database.url
6950
+ });
6951
+ console.log("\n🌳 Tenant hierarchy materialization\n");
6952
+ console.log(`✓ Connected to ${formatDatabaseDisplayUrl(dbType, config.database.url)}\n`);
6953
+ const dryRun = options["dry-run"] === true;
6954
+ let result;
6955
+ try {
6956
+ result = await materializeTenantHierarchy(db, {
6957
+ dryRun,
6958
+ tableName: options.table
6959
+ });
6960
+ } catch (error) {
6961
+ if (error instanceof TenantHierarchyMaterializationError) {
6962
+ for (const problem of error.problems) console.error(` ✗ ${problem.code}: ${problem.message}`);
6963
+ throw new Error(`${error.problems.length} tenant(s) have a broken parent chain; repair parent_tenant_id and re-run. No changes were made.`);
6964
+ }
6965
+ throw error;
6966
+ }
6967
+ for (const change of result.changes) console.log(` ${dryRun ? "~" : "✓"} ${change.id}: level ${change.previousLevel ?? "null"} → ${change.hierarchyLevel}, path "${change.previousPath ?? ""}" → "${change.hierarchyPath}"`);
6968
+ for (const problem of result.problems) console.log(` ✗ ${problem.code}: ${problem.message}`);
6969
+ if (dryRun) {
6970
+ console.log(`\nDRY RUN: ${result.total} tenant(s) examined; ${result.changes.length} would be updated, ${result.problems.length} have a broken parent chain. No changes made.\n`);
6971
+ if (result.problems.length > 0) process.exitCode = 1;
6972
+ return;
6973
+ }
6974
+ console.log(result.changes.length > 0 ? `\n✓ Materialized the hierarchy for ${result.changes.length} of ${result.total} tenant(s).\n` : `\nAll ${result.total} tenant(s) already carry the correct hierarchy; nothing to do.\n`);
6975
+ } catch (error) {
6976
+ console.error(`\n❌ Tenant hierarchy materialization failed: ${redactConnectionStringsInText(error instanceof Error ? error.message : String(error))}\n`);
6977
+ process.exitCode = 1;
6978
+ } finally {
6979
+ await closeDatabaseConnection(db);
6980
+ }
6981
+ }
6982
+ };
6983
+ //#endregion
6911
6984
  //#region src/commands/db-migrate-agent-schedule-slugs.ts
6912
6985
  var dbMigrateAgentScheduleSlugsCommand = {
6913
6986
  name: "db:migrate-agent-schedule-slugs",
@@ -6923,7 +6996,7 @@ var dbMigrateAgentScheduleSlugsCommand = {
6923
6996
  let db;
6924
6997
  try {
6925
6998
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
6926
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
6999
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
6927
7000
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
6928
7001
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:migrate-agent-schedule-slugs. Configure database.url in smrt.config.ts (or DATABASE_URL).");
6929
7002
  const dbType = config.database.type || "sqlite";
@@ -6993,7 +7066,7 @@ var dbMigrateInt8Command = {
6993
7066
  const dryRun = Boolean(options["dry-run"]);
6994
7067
  try {
6995
7068
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
6996
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
7069
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
6997
7070
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
6998
7071
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required for db:migrate-int8. Configure database.url in smrt.config.ts (or DATABASE_URL).");
6999
7072
  await autoDiscoverAndLoad();
@@ -7066,7 +7139,7 @@ var dbMigrateNullEqualIndexesCommand = {
7066
7139
  let db;
7067
7140
  try {
7068
7141
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
7069
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
7142
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
7070
7143
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
7071
7144
  if (!config.database?.url || config.database.url === ":memory:") throw new Error("Database configuration required: set database.url in smrt.config.ts (or DATABASE_URL).");
7072
7145
  await autoDiscoverAndLoad();
@@ -7379,7 +7452,7 @@ var dbMigrateUuidCommand = {
7379
7452
  let db;
7380
7453
  try {
7381
7454
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
7382
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
7455
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
7383
7456
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
7384
7457
  if (!config.database?.url || config.database.url === ":memory:") {
7385
7458
  console.error("\n❌ Database configuration required for db:migrate-uuid");
@@ -9485,7 +9558,7 @@ export default testManifest;
9485
9558
  let db;
9486
9559
  try {
9487
9560
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
9488
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
9561
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
9489
9562
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
9490
9563
  if (!config.database?.url || config.database.url === ":memory:") {
9491
9564
  console.error("❌ Database configuration required for db:setup");
@@ -9729,7 +9802,7 @@ export default testManifest;
9729
9802
  handler: async (_args, options) => {
9730
9803
  const startTime = Date.now();
9731
9804
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
9732
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
9805
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
9733
9806
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
9734
9807
  if (!options.data && config.database?.type === "postgres") {
9735
9808
  const permissions = await runPostgresPermissions({}, true);
@@ -9739,7 +9812,7 @@ export default testManifest;
9739
9812
  }
9740
9813
  }
9741
9814
  try {
9742
- const { resolveDataPath, discoverJsonFiles, JsonDatabaseValidator, displayValidationResults } = await import("./json-validator-CjX8fHx9.js");
9815
+ const { resolveDataPath, discoverJsonFiles, JsonDatabaseValidator, displayValidationResults } = await import("./json-validator-oEN7eUI3.js");
9743
9816
  const dataPath = await resolveDataPath(options.data);
9744
9817
  if (!dataPath) {
9745
9818
  console.error("\n❌ Could not find data directory");
@@ -9921,7 +9994,7 @@ export default testManifest;
9921
9994
  const postgresTimestampMigration = resolvePostgresTimestampMigration(options["postgres-timestamp-legacy-timezone"]);
9922
9995
  const isDryRun = options["dry-run"] ?? false;
9923
9996
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
9924
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
9997
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
9925
9998
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
9926
9999
  if (!config.database?.url || config.database.url === ":memory:") {
9927
10000
  console.error("❌ Database configuration required for db:migrate");
@@ -10712,7 +10785,7 @@ export default testManifest;
10712
10785
  check("src/lib/server/smrt.ts exists", existsSync(resolve(cwd, "src/lib/server/smrt.ts")), "Missing server config - run: smrt init");
10713
10786
  try {
10714
10787
  const { getPackageConfig } = await import("@happyvertical/smrt-config");
10715
- const { DEFAULT_CLI_CONFIG } = await import("./config-DfBo4hHU.js").then((n) => n.n);
10788
+ const { DEFAULT_CLI_CONFIG } = await import("./config-hqNo4lzH.js").then((n) => n.n);
10716
10789
  const config = getPackageConfig("cli", DEFAULT_CLI_CONFIG);
10717
10790
  if (config.database?.url && config.database.url !== ":memory:") check(`Database configured (${config.database.type || "sqlite"})`, true);
10718
10791
  else check("Database configured", false, void 0, "Using in-memory database - set DATABASE_URL for persistence");
@@ -10778,6 +10851,7 @@ export default testManifest;
10778
10851
  "db:migrate-int8": dbMigrateInt8Command,
10779
10852
  "db:migrate-null-equal-indexes": dbMigrateNullEqualIndexesCommand,
10780
10853
  "db:migrate-agent-schedule-slugs": dbMigrateAgentScheduleSlugsCommand,
10854
+ "db:materialize-tenant-hierarchy": dbMaterializeTenantHierarchyCommand,
10781
10855
  "db:drop-framework-base-tables": dbDropFrameworkBaseTablesCommand,
10782
10856
  "db:orphans": dbOrphansCommand,
10783
10857
  "db:prune": dbPruneCommand,
@@ -1,16 +1,4 @@
1
- import "node:module";
2
- //#region \0rolldown/runtime.js
3
- var __defProp = Object.defineProperty;
4
- var __exportAll = (all, no_symbols) => {
5
- let target = {};
6
- for (var name in all) __defProp(target, name, {
7
- get: all[name],
8
- enumerable: true
9
- });
10
- if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
11
- return target;
12
- };
13
- //#endregion
1
+ import { t as __exportAll } from "./rolldown-runtime-8H4AJuhK.js";
14
2
  //#region src/config.ts
15
3
  var config_exports = /* @__PURE__ */ __exportAll({ DEFAULT_CLI_CONFIG: () => DEFAULT_CLI_CONFIG });
16
4
  /**
@@ -0,0 +1,142 @@
1
+ import { ObjectRegistry, applyPendingDecoratorRegistrations, registerCompatibleFieldDecorator } from "@happyvertical/smrt-core";
2
+ import { createLogger } from "@happyvertical/logger";
3
+ import { AsyncLocalStorage } from "node:async_hooks";
4
+ //#region ../tenancy/dist/chunks/context-CwbLwyIV.js
5
+ var SYSTEM_CONTEXT_MARKER = /* @__PURE__ */ Symbol.for("smrt:system-context");
6
+ var TENANT_STORAGE_KEY = /* @__PURE__ */ Symbol.for("smrt:tenant-context-storage");
7
+ function resolveTenantStorage() {
8
+ const root = globalThis;
9
+ root[TENANT_STORAGE_KEY] ??= new AsyncLocalStorage();
10
+ return root[TENANT_STORAGE_KEY];
11
+ }
12
+ var tenantStorage = resolveTenantStorage();
13
+ function getCurrentTenant() {
14
+ const store = tenantStorage.getStore();
15
+ if (store === SYSTEM_CONTEXT_MARKER) return;
16
+ return store;
17
+ }
18
+ function getTenantId() {
19
+ const store = tenantStorage.getStore();
20
+ if (store === SYSTEM_CONTEXT_MARKER) return;
21
+ return store?.tenantId;
22
+ }
23
+ function isSystemContext() {
24
+ return tenantStorage.getStore() === SYSTEM_CONTEXT_MARKER;
25
+ }
26
+ function isSuperAdminBypass() {
27
+ const store = tenantStorage.getStore();
28
+ if (store === SYSTEM_CONTEXT_MARKER) return false;
29
+ return store?.superAdminBypass === true;
30
+ }
31
+ async function withSystemContext(fn) {
32
+ return tenantStorage.run(SYSTEM_CONTEXT_MARKER, fn);
33
+ }
34
+ var TenantIsolationError = class extends Error {
35
+ /** Stable error code; always `'TENANT_ISOLATION_VIOLATION'`. */
36
+ code = "TENANT_ISOLATION_VIOLATION";
37
+ /** The tenant ID that is active in the current context. */
38
+ tenantId;
39
+ /** The tenant ID that was attempted (and rejected). */
40
+ attemptedTenantId;
41
+ constructor(message, details) {
42
+ super(message);
43
+ this.name = "TenantIsolationError";
44
+ this.tenantId = details?.tenantId;
45
+ this.attemptedTenantId = details?.attemptedTenantId;
46
+ }
47
+ };
48
+ //#endregion
49
+ //#region ../tenancy/dist/chunks/testing-s12-pjzJ.js
50
+ var DEFAULT_CONFIG = {
51
+ mode: "required",
52
+ field: "tenantId",
53
+ autoFilter: true,
54
+ autoPopulate: true,
55
+ allowSuperAdminBypass: false
56
+ };
57
+ var tenantScopedClasses = /* @__PURE__ */ new Map();
58
+ var unregisteredDecoratorRegistrations = /* @__PURE__ */ new Map();
59
+ function registerTenantScopedConstructor(target, config = {}) {
60
+ const resolved = {
61
+ ...DEFAULT_CONFIG,
62
+ ...config
63
+ };
64
+ unregisteredDecoratorRegistrations.set(target.name, resolved);
65
+ tenantScopedClasses.set(target.name, resolved);
66
+ }
67
+ var KEY = /* @__PURE__ */ Symbol.for("smrt:tenant-global-read-scope");
68
+ var root = globalThis;
69
+ root[KEY] ??= new AsyncLocalStorage();
70
+ root[KEY];
71
+ function assertTenantReadAllowed(tenantId, label) {
72
+ const tenantContext = getCurrentTenant();
73
+ if (tenantContext && !isSuperAdminBypass() && tenantContext.tenantId !== tenantId) throw new TenantIsolationError(`Tenant isolation violation in ${label}: context tenant is '${tenantContext.tenantId}' but query requested '${tenantId}'`, {
74
+ tenantId: tenantContext.tenantId,
75
+ attemptedTenantId: tenantId
76
+ });
77
+ }
78
+ async function queryGlobal(collection) {
79
+ const metaType = collection.getStiChildMetaType();
80
+ const where = metaType ? "WHERE _meta_type = ? AND tenant_id IS NULL" : "WHERE tenant_id IS NULL";
81
+ const params = metaType ? [metaType] : [];
82
+ return await collection.query(`SELECT * FROM ${collection.tableName} ${where}`, params, { allowRawOnTenantScoped: true });
83
+ }
84
+ async function queryWithGlobals(collection, tenantId, label) {
85
+ assertTenantReadAllowed(tenantId, label);
86
+ const metaType = collection.getStiChildMetaType();
87
+ const where = metaType ? "WHERE _meta_type = ? AND (tenant_id = ? OR tenant_id IS NULL)" : "WHERE tenant_id = ? OR tenant_id IS NULL";
88
+ const params = metaType ? [metaType, tenantId] : [tenantId];
89
+ return await collection.query(`SELECT * FROM ${collection.tableName} ${where}`, params, { allowRawOnTenantScoped: true });
90
+ }
91
+ createLogger({ level: "info" });
92
+ //#endregion
93
+ //#region ../tenancy/dist/index.js
94
+ ObjectRegistry.registerPackageManifest(JSON.parse("{\"version\":\"1.0.0\",\"timestamp\":0,\"packageName\":\"@happyvertical/smrt-tenancy\",\"packageVersion\":\"0.51.16\",\"objects\":{},\"moduleType\":\"smrt\",\"smrtDependencies\":[\"@happyvertical/smrt-core\"]}"));
95
+ function TenantScoped(options = {}) {
96
+ return (target, decoratorContext) => {
97
+ applyPendingDecoratorRegistrations(target, decoratorContext);
98
+ const config = {
99
+ mode: options.mode ?? "required",
100
+ field: options.field ?? "tenantId",
101
+ autoFilter: options.autoFilter ?? true,
102
+ autoPopulate: options.autoPopulate ?? true,
103
+ allowSuperAdminBypass: options.allowSuperAdminBypass ?? false
104
+ };
105
+ registerTenantScopedConstructor(target, config);
106
+ ObjectRegistry.reconcileTenantScopedConfig(target, {
107
+ mode: config.mode ?? "required",
108
+ field: config.field ?? "tenantId",
109
+ autoFilter: config.autoFilter ?? true,
110
+ autoPopulate: config.autoPopulate ?? true,
111
+ allowSuperAdminBypass: config.allowSuperAdminBypass ?? false
112
+ });
113
+ return target;
114
+ };
115
+ }
116
+ function tenantId(options = {}) {
117
+ const opts = {
118
+ autoFilter: true,
119
+ required: true,
120
+ autoPopulate: true,
121
+ nullable: false,
122
+ ...options
123
+ };
124
+ return ((targetOrValue, propertyKeyOrContext) => {
125
+ registerCompatibleFieldDecorator(targetOrValue, propertyKeyOrContext, (className, propertyKey, ctor) => {
126
+ const fieldOptions = {
127
+ type: "foreignKey",
128
+ related: "Tenant",
129
+ sqlType: "UUID",
130
+ required: opts.required,
131
+ nullable: opts.nullable,
132
+ __tenancy: {
133
+ ...opts,
134
+ isTenantIdField: true
135
+ }
136
+ };
137
+ ObjectRegistry.registerFieldDecorator(className, propertyKey, fieldOptions, ctor);
138
+ });
139
+ });
140
+ }
141
+ //#endregion
142
+ export { getTenantId as a, queryWithGlobals as i, tenantId as n, isSystemContext as o, queryGlobal as r, withSystemContext as s, TenantScoped as t };