@wtfalch/authz-store 0.2.0 → 0.2.1

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/grants.d.ts CHANGED
@@ -138,7 +138,6 @@ export declare const policyGrants: import("drizzle-orm/pg-core").PgTableWithColu
138
138
  data: {
139
139
  kind: "organisation";
140
140
  organisationId: string;
141
- descendants?: boolean | undefined;
142
141
  } | {
143
142
  kind: "organisations";
144
143
  organisationIds: string[];
@@ -159,7 +158,6 @@ export declare const policyGrants: import("drizzle-orm/pg-core").PgTableWithColu
159
158
  $type: {
160
159
  kind: "organisation";
161
160
  organisationId: string;
162
- descendants?: boolean | undefined;
163
161
  } | {
164
162
  kind: "organisations";
165
163
  organisationIds: string[];
package/dist/migrate.js CHANGED
@@ -1,7 +1,17 @@
1
1
  import { readFile, readdir } from 'node:fs/promises';
2
+ import { dirname, join } from 'node:path';
3
+ import { fileURLToPath } from 'node:url';
2
4
  import { sql } from 'drizzle-orm';
3
- /** The shipped SQL, next to `dist/` in the package and next to `src/` in this repository. */
4
- const MIGRATIONS = new URL('../migrations/', import.meta.url);
5
+ /**
6
+ * The shipped SQL, next to `dist/` in the package and next to `src/` in this repository. Computed
7
+ * lazily inside `migrateStore` rather than as a module-level `new URL('../migrations/',
8
+ * import.meta.url)`: Turbopack resolves that literal statically when an app imports the package
9
+ * barrel, and fails with "Can't resolve '../migrations/'" because the directory holds no importable
10
+ * module.
11
+ */
12
+ function migrationsDir() {
13
+ return join(dirname(fileURLToPath(import.meta.url)), '..', 'migrations');
14
+ }
5
15
  /** Files split on this line, the marker drizzle-kit writes, so any driver can run them one statement at a time. */
6
16
  const BREAKPOINT = '--> statement-breakpoint';
7
17
  /** One key for every host, so two containers starting at once apply each file once between them. */
@@ -12,10 +22,11 @@ const LOCK = 7_310_422_001;
12
22
  * migrations, so everything the package owns exists before a host migration references it.
13
23
  */
14
24
  export async function migrateStore(db) {
15
- const names = (await readdir(MIGRATIONS)).filter((n) => n.endsWith('.sql')).sort();
25
+ const dir = migrationsDir();
26
+ const names = (await readdir(dir)).filter((n) => n.endsWith('.sql')).sort();
16
27
  const applied = [];
17
28
  for (const name of names) {
18
- const text = await readFile(new URL(name, MIGRATIONS), 'utf8');
29
+ const text = await readFile(join(dir, name), 'utf8');
19
30
  const ran = await db.transaction(async (tx) => {
20
31
  await tx.execute(sql `select pg_advisory_xact_lock(${LOCK})`);
21
32
  // Created under the lock: two runners creating it at once collide in pg_type.
package/dist/owners.d.ts CHANGED
@@ -17,7 +17,12 @@ export interface OwnerCoverageOptions {
17
17
  readonly excludePrincipalId?: string;
18
18
  readonly excludePrincipalClass?: string;
19
19
  }
20
- /** A credential cannot be the recovery owner: expiry or issuer revocation can remove its authority. */
20
+ /**
21
+ * A credential cannot be the recovery owner: expiry or issuer revocation can remove its authority.
22
+ *
23
+ * Owners are counted by the fixed `owner` role key, not the `builtIn` flag: the owner role is
24
+ * fixed, one per org, never renamed (decided in https://github.com/wtfalch/authz/issues/67).
25
+ */
21
26
  export declare function ownerCoverage(tx: DbOrTx, binding: PolicyBinding, tenantId: string, options?: OwnerCoverageOptions): Promise<OwnerCoverage>;
22
27
  export declare function ownerSeatCovered(coverage: OwnerCoverage): boolean;
23
28
  export declare function principalIsReachable(): import("drizzle-orm").SQL<unknown>;
package/dist/owners.js CHANGED
@@ -1,7 +1,12 @@
1
1
  import { and, eq, gt, isNull, sql } from 'drizzle-orm';
2
2
  import { policyAssignments, policyRoles } from './policy-schema.js';
3
3
  import { credentials, invitations, memberships } from './schema.js';
4
- /** A credential cannot be the recovery owner: expiry or issuer revocation can remove its authority. */
4
+ /**
5
+ * A credential cannot be the recovery owner: expiry or issuer revocation can remove its authority.
6
+ *
7
+ * Owners are counted by the fixed `owner` role key, not the `builtIn` flag: the owner role is
8
+ * fixed, one per org, never renamed (decided in https://github.com/wtfalch/authz/issues/67).
9
+ */
5
10
  export async function ownerCoverage(tx, binding, tenantId, options = {}) {
6
11
  const a = policyAssignments;
7
12
  const r = policyRoles;
@@ -11,7 +16,6 @@ export async function ownerCoverage(tx, binding, tenantId, options = {}) {
11
16
  eq(a.platformId, binding.platformId),
12
17
  eq(a.source, 'direct'),
13
18
  eq(a.principalClass, 'human'),
14
- eq(r.builtIn, true),
15
19
  eq(r.key, 'owner'),
16
20
  isNull(a.expiresAt),
17
21
  sql `${a.scope}->>'kind' = 'organisation'`,
@@ -29,7 +33,7 @@ export async function ownerCoverage(tx, binding, tenantId, options = {}) {
29
33
  .select({ count: sql `count(*)::int` })
30
34
  .from(invitations)
31
35
  .innerJoin(r, eq(invitations.roleId, r.id))
32
- .where(and(eq(invitations.tenantId, tenantId), eq(r.builtIn, true), eq(r.key, 'owner'), eq(invitations.status, 'pending'), gt(invitations.expiresAt, sql `now()`)));
36
+ .where(and(eq(invitations.tenantId, tenantId), eq(r.key, 'owner'), eq(invitations.status, 'pending'), gt(invitations.expiresAt, sql `now()`)));
33
37
  return { directOwners: owners?.count ?? 0, pendingOwnerInvitations: pending?.count ?? 0 };
34
38
  }
35
39
  export function ownerSeatCovered(coverage) {
@@ -166,7 +166,6 @@ export declare const policyRoles: import("drizzle-orm/pg-core").PgTableWithColum
166
166
  boundary: {
167
167
  kind: "organisation";
168
168
  organisationId: string;
169
- descendants?: boolean | undefined;
170
169
  } | {
171
170
  kind: "organisations";
172
171
  organisationIds: string[];
@@ -205,7 +204,6 @@ export declare const policyRoles: import("drizzle-orm/pg-core").PgTableWithColum
205
204
  boundary: {
206
205
  kind: "organisation";
207
206
  organisationId: string;
208
- descendants?: boolean | undefined;
209
207
  } | {
210
208
  kind: "organisations";
211
209
  organisationIds: string[];
@@ -509,7 +507,6 @@ export declare const policyAssignments: import("drizzle-orm/pg-core").PgTableWit
509
507
  data: {
510
508
  kind: "organisation";
511
509
  organisationId: string;
512
- descendants?: boolean | undefined;
513
510
  } | {
514
511
  kind: "organisations";
515
512
  organisationIds: string[];
@@ -530,7 +527,6 @@ export declare const policyAssignments: import("drizzle-orm/pg-core").PgTableWit
530
527
  $type: {
531
528
  kind: "organisation";
532
529
  organisationId: string;
533
- descendants?: boolean | undefined;
534
530
  } | {
535
531
  kind: "organisations";
536
532
  organisationIds: string[];
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@wtfalch/authz-store",
3
- "version": "0.2.0",
3
+ "version": "0.2.1",
4
4
  "description": "Persistence and lifecycle for @wtfalch/authz: the storage a host would otherwise write itself.",
5
5
  "type": "module",
6
6
  "files": [
@@ -17,7 +17,7 @@
17
17
  },
18
18
  "peerDependencies": {
19
19
  "@wtfalch/authz": "^0.15.0",
20
- "drizzle-orm": "^0.39.0"
20
+ "drizzle-orm": ">=0.39.0 <1.0.0"
21
21
  },
22
22
  "engines": {
23
23
  "node": ">=22.0.0"