@govcore/schema 0.1.0 → 0.2.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/CHANGELOG.md +14 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +16 -0
- package/package.json +1 -1
- package/src/index.ts +16 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# @govcore/schema
|
|
2
2
|
|
|
3
|
+
## 0.2.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- d255afc: Operator-plane console mutations (#63). The org/user administration flows behind an instance console were rebuilt by every consumer (GovEA `actions/instance.ts`, GovCRM `lib/platform.ts`), and the user path is exactly where they diverged. Promote the mutations to core, composing the membership invariants from #65 so the guard and write-sync are identical everywhere.
|
|
8
|
+
|
|
9
|
+
`@govcore/tenancy` gains `createOrganization` (auto-slug via the new exported `slugify`; a duplicate slug returns a typed `slug-taken`), `renameOrganization` (name-only; audited before/after), and `updateUserAdministration` — the guard-heavy one: it enforces the last-active-admin invariant via `assertNotLastActiveAdmin` (inside the transaction) and an own-instance-admin lockout, updates the `users` row, and keeps the membership in lockstep via `upsertMembership`. All audited as `platform.org.*` / `platform.user.update` and generic over the app's admin role name; tenancy now depends on `@govcore/audit`.
|
|
10
|
+
|
|
11
|
+
`@govcore/auth` gains `provisionUser` — create a user with an initial password + primary membership. It lives here (not tenancy) because it hashes: validates against the policy, hashes, inserts, writes the membership through tenancy's `upsertMembership`, and audits `platform.user.create` without ever putting the password in the payload; a duplicate email returns a typed `email-taken`.
|
|
12
|
+
|
|
13
|
+
`@govcore/schema` gains `isUniqueViolation(err)` — a pure, edge-safe SQLSTATE-23505 predicate so operator flows turn a duplicate slug/email into a typed result instead of a 500.
|
|
14
|
+
|
|
15
|
+
All framework-agnostic (no FormData/redirect/revalidate — the consumer keeps the thin `'use server'` wrapper and the `instance_admin` gate) and returning typed results rather than throwing.
|
|
16
|
+
|
|
3
17
|
## 0.1.0
|
|
4
18
|
|
|
5
19
|
### Minor Changes
|
package/dist/index.d.ts
CHANGED
|
@@ -6,6 +6,15 @@ export * from './schema';
|
|
|
6
6
|
* app's `postgres-js` db, or a `tx` inside a transaction — which extends it).
|
|
7
7
|
*/
|
|
8
8
|
export type GovcoreDb = PgDatabase<PgQueryResultHKT, any, any>;
|
|
9
|
+
/**
|
|
10
|
+
* True when `err` is (or wraps) a Postgres unique-constraint violation
|
|
11
|
+
* (SQLSTATE 23505). Pure and edge-safe — inspects `code`, touches no DB client.
|
|
12
|
+
* Lets operator flows turn a duplicate slug/email into a typed result instead of
|
|
13
|
+
* a 500. Walks the `cause` chain because Drizzle wraps the driver error in a
|
|
14
|
+
* `DrizzleQueryError` and puts the `postgres-js`/`pg` error (which carries the
|
|
15
|
+
* `code`) on `.cause` — so the top-level error's own `code` is undefined.
|
|
16
|
+
*/
|
|
17
|
+
export declare function isUniqueViolation(err: unknown): boolean;
|
|
9
18
|
/**
|
|
10
19
|
* Bumped whenever the platform schema changes. Written to instance settings on
|
|
11
20
|
* boot for observability ("this instance runs platform schema vN", design §5),
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAEvE,cAAc,UAAU,CAAA;AAExB;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAE9D;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,UAAU,CAAA"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAA;AAEvE,cAAc,UAAU,CAAA;AAExB;;;;GAIG;AACH,MAAM,MAAM,SAAS,GAAG,UAAU,CAAC,gBAAgB,EAAE,GAAG,EAAE,GAAG,CAAC,CAAA;AAE9D;;;;;;;GAOG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,OAAO,GAAG,OAAO,CAMvD;AAED;;;;;GAKG;AACH,eAAO,MAAM,mBAAmB,UAAU,CAAA"}
|
package/dist/index.js
CHANGED
|
@@ -1,6 +1,22 @@
|
|
|
1
1
|
// @govcore/schema — platform table definitions + schema version.
|
|
2
2
|
// Edge-safe entrypoint (no DB client). The migrate runner is ./migrate.
|
|
3
3
|
export * from './schema';
|
|
4
|
+
/**
|
|
5
|
+
* True when `err` is (or wraps) a Postgres unique-constraint violation
|
|
6
|
+
* (SQLSTATE 23505). Pure and edge-safe — inspects `code`, touches no DB client.
|
|
7
|
+
* Lets operator flows turn a duplicate slug/email into a typed result instead of
|
|
8
|
+
* a 500. Walks the `cause` chain because Drizzle wraps the driver error in a
|
|
9
|
+
* `DrizzleQueryError` and puts the `postgres-js`/`pg` error (which carries the
|
|
10
|
+
* `code`) on `.cause` — so the top-level error's own `code` is undefined.
|
|
11
|
+
*/
|
|
12
|
+
export function isUniqueViolation(err) {
|
|
13
|
+
for (let e = err, depth = 0; e && typeof e === 'object' && depth < 5; depth++) {
|
|
14
|
+
if (e.code === '23505')
|
|
15
|
+
return true;
|
|
16
|
+
e = e.cause;
|
|
17
|
+
}
|
|
18
|
+
return false;
|
|
19
|
+
}
|
|
4
20
|
/**
|
|
5
21
|
* Bumped whenever the platform schema changes. Written to instance settings on
|
|
6
22
|
* boot for observability ("this instance runs platform schema vN", design §5),
|
package/package.json
CHANGED
package/src/index.ts
CHANGED
|
@@ -12,6 +12,22 @@ export * from './schema'
|
|
|
12
12
|
*/
|
|
13
13
|
export type GovcoreDb = PgDatabase<PgQueryResultHKT, any, any>
|
|
14
14
|
|
|
15
|
+
/**
|
|
16
|
+
* True when `err` is (or wraps) a Postgres unique-constraint violation
|
|
17
|
+
* (SQLSTATE 23505). Pure and edge-safe — inspects `code`, touches no DB client.
|
|
18
|
+
* Lets operator flows turn a duplicate slug/email into a typed result instead of
|
|
19
|
+
* a 500. Walks the `cause` chain because Drizzle wraps the driver error in a
|
|
20
|
+
* `DrizzleQueryError` and puts the `postgres-js`/`pg` error (which carries the
|
|
21
|
+
* `code`) on `.cause` — so the top-level error's own `code` is undefined.
|
|
22
|
+
*/
|
|
23
|
+
export function isUniqueViolation(err: unknown): boolean {
|
|
24
|
+
for (let e: unknown = err, depth = 0; e && typeof e === 'object' && depth < 5; depth++) {
|
|
25
|
+
if ((e as { code?: string }).code === '23505') return true
|
|
26
|
+
e = (e as { cause?: unknown }).cause
|
|
27
|
+
}
|
|
28
|
+
return false
|
|
29
|
+
}
|
|
30
|
+
|
|
15
31
|
/**
|
|
16
32
|
* Bumped whenever the platform schema changes. Written to instance settings on
|
|
17
33
|
* boot for observability ("this instance runs platform schema vN", design §5),
|