@happyvertical/smrt-users 0.51.39 → 0.53.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/README.md CHANGED
@@ -113,6 +113,8 @@ Catalog sync is additive and fail-closed:
113
113
  - it updates `name`, `description`, and `category` by slug
114
114
  - it does not auto-grant permissions to roles
115
115
  - it does not delete stale permissions in v1
116
+ - it commits created/updated rows in small batched transactions; when calling
117
+ it inside your own transaction, pass that transaction's database handle
116
118
 
117
119
  ### App-defined permissions in `smrt.config.ts`
118
120
 
@@ -93,7 +93,11 @@ membership or tenant DENY to attenuate inherited role authority.
93
93
  seedSystemRoles({ seedPermissions: true }) maps owner/admin to all catalog
94
94
  permissions, member to ordinary-resource read/create, viewer to read. Member
95
95
  create excludes identity/RBAC/security resources and their joins/overrides.
96
- Seeding is additive/idempotent; removal requires prune: true.
96
+ Seeding is additive/idempotent; removal requires prune: true. Catalog sync
97
+ and grants plan from one read, then commit in `SEEDING_BATCH_SIZE` batches
98
+ (#3323): never one durable commit per row (an fsync each on local SQLite),
99
+ and never one catalog-wide transaction (`@happyvertical/sql` transaction
100
+ scopes cost superlinearly per statement). Pass a caller transaction's handle.
97
101
  - When a package adds built-in self-personalization permissions after role
98
102
  creation, explicitly call seedDefaultRolePersonalizationPermissions(). It
99
103
  upgrades owner/admin/member/viewer idempotently and never grants custom roles.
@@ -36,7 +36,7 @@ export interface OidcTestServer {
36
36
  * `(tenant_id, slug, context, _meta_type)` since smrt#2360 — keep this DDL in
37
37
  * step with the framework schema or `save()`'s ON CONFLICT cannot bind.
38
38
  */
39
- export declare const OIDC_USERS_TEST_SCHEMA = "\nCREATE TABLE IF NOT EXISTS \"_smrt_backfills\" (\n \"name\" TEXT PRIMARY KEY NOT NULL,\n \"applied_at\" TIMESTAMP DEFAULT current_timestamp,\n \"description\" TEXT,\n \"package_name\" TEXT\n);\n\nCREATE TABLE IF NOT EXISTS \"profile_types\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" TEXT,\n \"name\" TEXT DEFAULT '',\n \"description\" TEXT\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"profile_types_slug_context_meta_type_idx\" ON \"profile_types\" (\"tenant_id\", \"slug\", \"context\", \"_meta_type\");\nCREATE INDEX IF NOT EXISTS \"profile_types_meta_type_idx\" ON \"profile_types\" (\"_meta_type\");\n\nCREATE TABLE IF NOT EXISTS \"profiles\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" TEXT,\n \"type_id\" TEXT,\n \"email\" TEXT,\n \"email_key\" TEXT,\n \"name\" TEXT DEFAULT '',\n \"description\" TEXT\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"profiles_slug_context_meta_type_idx\" ON \"profiles\" (\"tenant_id\", \"slug\", \"context\", \"_meta_type\");\nCREATE INDEX IF NOT EXISTS \"profiles_meta_type_idx\" ON \"profiles\" (\"_meta_type\");\nCREATE INDEX IF NOT EXISTS \"profiles_email_key_idx\" ON \"profiles\" (\"email_key\");\n\nCREATE TABLE IF NOT EXISTS \"oidc_profile_email_reservations\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"profile_id\" TEXT NOT NULL,\n \"email_key\" TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_profile_email_reservations_slug_context_idx\" ON \"oidc_profile_email_reservations\" (\"slug\", \"context\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_profile_email_reservations_profile_id_idx\" ON \"oidc_profile_email_reservations\" (\"profile_id\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_profile_email_reservations_email_key_idx\" ON \"oidc_profile_email_reservations\" (\"email_key\");\n\nCREATE TABLE IF NOT EXISTS \"oidc_identities\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"profile_id\" TEXT NOT NULL,\n \"provider\" TEXT DEFAULT '',\n \"issuer\" TEXT DEFAULT '',\n \"subject\" TEXT DEFAULT '',\n \"identity_key\" TEXT,\n \"email\" TEXT DEFAULT '',\n \"last_used_at\" TIMESTAMP\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_identities_slug_context_idx\" ON \"oidc_identities\" (\"slug\", \"context\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_identities_identity_key_idx\" ON \"oidc_identities\" (\"identity_key\");\n\nCREATE TABLE IF NOT EXISTS \"users\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"profile_id\" TEXT DEFAULT '',\n \"email\" TEXT DEFAULT '',\n \"email_key\" TEXT,\n \"status\" TEXT,\n \"last_login_at\" TIMESTAMP\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"users_slug_context_idx\" ON \"users\" (\"slug\", \"context\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"users_profile_id_idx\" ON \"users\" (\"profile_id\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"users_email_key_idx\" ON \"users\" (\"email_key\");\n\nCREATE TABLE IF NOT EXISTS \"sessions\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"user_id\" TEXT DEFAULT '',\n \"tenant_id\" TEXT,\n \"status\" TEXT,\n \"expires_at\" TIMESTAMP,\n \"user_agent\" TEXT DEFAULT '',\n \"ip_address\" TEXT DEFAULT '',\n \"last_accessed_at\" TIMESTAMP,\n \"data\" JSON DEFAULT '{}'\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"sessions_slug_context_idx\" ON \"sessions\" (\"slug\", \"context\");\n";
39
+ export declare const OIDC_USERS_TEST_SCHEMA = "\nCREATE TABLE IF NOT EXISTS \"_smrt_backfills\" (\n \"name\" TEXT PRIMARY KEY NOT NULL,\n \"applied_at\" TIMESTAMP DEFAULT current_timestamp,\n \"description\" TEXT,\n \"package_name\" TEXT\n);\n\nCREATE TABLE IF NOT EXISTS \"profile_types\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" TEXT,\n \"name\" TEXT DEFAULT '',\n \"description\" TEXT\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"profile_types_slug_context_meta_type_idx\" ON \"profile_types\" (\"tenant_id\", \"slug\", \"context\", \"_meta_type\");\nCREATE INDEX IF NOT EXISTS \"profile_types_meta_type_idx\" ON \"profile_types\" (\"_meta_type\");\n\nCREATE TABLE IF NOT EXISTS \"profiles\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"_meta_type\" TEXT NOT NULL,\n \"_meta_data\" JSON,\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"tenant_id\" TEXT,\n \"type_id\" TEXT,\n \"email\" TEXT,\n \"email_key\" TEXT,\n \"name\" TEXT DEFAULT '',\n \"description\" TEXT,\n \"is_public\" BOOLEAN DEFAULT FALSE\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"profiles_slug_context_meta_type_idx\" ON \"profiles\" (\"tenant_id\", \"slug\", \"context\", \"_meta_type\");\nCREATE INDEX IF NOT EXISTS \"profiles_meta_type_idx\" ON \"profiles\" (\"_meta_type\");\nCREATE INDEX IF NOT EXISTS \"profiles_email_key_idx\" ON \"profiles\" (\"email_key\");\n\nCREATE TABLE IF NOT EXISTS \"oidc_profile_email_reservations\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"profile_id\" TEXT NOT NULL,\n \"email_key\" TEXT NOT NULL\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_profile_email_reservations_slug_context_idx\" ON \"oidc_profile_email_reservations\" (\"slug\", \"context\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_profile_email_reservations_profile_id_idx\" ON \"oidc_profile_email_reservations\" (\"profile_id\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_profile_email_reservations_email_key_idx\" ON \"oidc_profile_email_reservations\" (\"email_key\");\n\nCREATE TABLE IF NOT EXISTS \"oidc_identities\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"profile_id\" TEXT NOT NULL,\n \"provider\" TEXT DEFAULT '',\n \"issuer\" TEXT DEFAULT '',\n \"subject\" TEXT DEFAULT '',\n \"identity_key\" TEXT,\n \"email\" TEXT DEFAULT '',\n \"last_used_at\" TIMESTAMP\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_identities_slug_context_idx\" ON \"oidc_identities\" (\"slug\", \"context\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"oidc_identities_identity_key_idx\" ON \"oidc_identities\" (\"identity_key\");\n\nCREATE TABLE IF NOT EXISTS \"users\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"profile_id\" TEXT DEFAULT '',\n \"email\" TEXT DEFAULT '',\n \"email_key\" TEXT,\n \"status\" TEXT,\n \"last_login_at\" TIMESTAMP\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"users_slug_context_idx\" ON \"users\" (\"slug\", \"context\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"users_profile_id_idx\" ON \"users\" (\"profile_id\");\nCREATE UNIQUE INDEX IF NOT EXISTS \"users_email_key_idx\" ON \"users\" (\"email_key\");\n\nCREATE TABLE IF NOT EXISTS \"sessions\" (\n \"id\" TEXT PRIMARY KEY NOT NULL,\n \"slug\" TEXT NOT NULL,\n \"context\" TEXT NOT NULL DEFAULT '',\n \"created_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"updated_at\" TIMESTAMP NOT NULL DEFAULT current_timestamp,\n \"user_id\" TEXT DEFAULT '',\n \"tenant_id\" TEXT,\n \"status\" TEXT,\n \"expires_at\" TIMESTAMP,\n \"user_agent\" TEXT DEFAULT '',\n \"ip_address\" TEXT DEFAULT '',\n \"last_accessed_at\" TIMESTAMP,\n \"data\" JSON DEFAULT '{}'\n);\nCREATE UNIQUE INDEX IF NOT EXISTS \"sessions_slug_context_idx\" ON \"sessions\" (\"slug\", \"context\");\n";
40
40
  /** Mark a freshly-created, empty test schema ready for indexed OIDC reads. */
41
41
  export declare function prepareOidcEmailKeyBackfills(db: DatabaseInterface): Promise<void>;
42
42
  /** Close every server started by this harness (call from `afterAll`). */
@@ -1 +1 @@
1
- {"version":3,"file":"oidc-test-server.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/oidc-test-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,qCAAqC,CAAC;AAK7C,MAAM,WAAW,qBAAqB;IACpC,oCAAoC,CAAC,EAAE,OAAO,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,aAAa,EAAE,KAAK,CAAC;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,w8IAwGlC,CAAC;AAEF,8EAA8E;AAC9E,wBAAsB,4BAA4B,CAChD,EAAE,EAAE,iBAAiB,GACpB,OAAO,CAAC,IAAI,CAAC,CAUf;AAaD,yEAAyE;AACzE,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzD;AAiBD,wBAAsB,eAAe,CACnC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,cAAc,CAAC,CAgIzB"}
1
+ {"version":3,"file":"oidc-test-server.d.ts","sourceRoot":"","sources":["../../../src/__tests__/helpers/oidc-test-server.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AASH,OAAO,EAEL,KAAK,iBAAiB,EACvB,MAAM,qCAAqC,CAAC;AAK7C,MAAM,WAAW,qBAAqB;IACpC,oCAAoC,CAAC,EAAE,OAAO,CAAC;IAC/C,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC;IAC7B,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,qBAAqB,CAAC,EAAE,OAAO,CAAC;CACjC;AAED,MAAM,WAAW,cAAc;IAC7B,KAAK,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAC;IAC3B,MAAM,EAAE,MAAM,CAAC;IACf,wDAAwD;IACxD,QAAQ,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAC;IAClC,aAAa,EAAE,KAAK,CAAC;QAAE,aAAa,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,eAAe,CAAA;KAAE,CAAC,CAAC;IAC1E,gBAAgB,EAAE,KAAK,CAAC;QAAE,aAAa,CAAC,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACrD;AAED;;;;;;;;GAQG;AACH,eAAO,MAAM,sBAAsB,g/IAyGlC,CAAC;AAEF,8EAA8E;AAC9E,wBAAsB,4BAA4B,CAChD,EAAE,EAAE,iBAAiB,GACpB,OAAO,CAAC,IAAI,CAAC,CAUf;AAaD,yEAAyE;AACzE,wBAAsB,mBAAmB,IAAI,OAAO,CAAC,IAAI,CAAC,CAEzD;AAiBD,wBAAsB,eAAe,CACnC,OAAO,GAAE,qBAA0B,GAClC,OAAO,CAAC,cAAc,CAAC,CAgIzB"}