@company-semantics/contracts 58.5.1 → 59.0.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.
@@ -25,184 +25,20 @@ export function resolveScope(context: {
25
25
  return { orgId: context.impersonatedOrgId ?? context.orgId };
26
26
  }
27
27
 
28
- /*
29
- * ---------------------------------------------------------------------------
30
- * fromQueryKey's routing tables, and the drift detector over them.
31
- * ---------------------------------------------------------------------------
32
- *
33
- * `toQueryKey` has always been safe: its switch is exhaustive and its `never`
34
- * guard makes a new union member a compile error. `fromQueryKey` was not. Its
35
- * five lookup tables are hand-maintained, and a member missing from all of them
36
- * fell through to a RUNTIME `throw` — which `matchesResourceKey` catches and
37
- * turns into "matches nothing", and which `useResource` turns into a query that
38
- * never fetches. Silent in both directions (ADR-CONTRACTS-119).
39
- *
40
- * Two mechanisms, and BOTH are needed:
41
- *
42
- * `satisfies` on each table catches a WRONG entry — a typo, or a literal
43
- * parked under the wrong scope. It cannot catch an entry that is simply
44
- * absent, because an array is free to be a subset of its element type.
45
- *
46
- * `_EveryResourceKeyIsRouted` below catches the ABSENT entry, which is the
47
- * failure that actually shipped. It is the half that closes the hole.
48
- */
49
-
50
- /**
51
- * The identity segments a member carries — every field that is neither the type
52
- * tag nor a scope discriminator. `member` → `"memberId"`; `commentThreads` →
53
- * `"subjectType" | "subjectId"`; a scope-only key → `never`.
54
- */
55
- type IdentityFieldsOf<T extends ResourceKey["type"]> = Exclude<
56
- keyof Extract<ResourceKey, { type: T }>,
57
- "type" | "orgId" | "userId" | "scope"
58
- >;
59
-
60
- /**
61
- * Type literals whose whole shape is the tag plus one scope discriminator —
62
- * i.e. the members that belong in a scope ARRAY rather than an identity MAP.
63
- * Distributes over the union (`K` is a naked type parameter).
64
- */
65
- type ScopeOnlyType<K = ResourceKey> = K extends {
66
- type: infer T extends ResourceKey["type"];
67
- }
68
- ? [IdentityFieldsOf<T>] extends [never]
69
- ? T
70
- : never
71
- : never;
72
-
73
- type OrgScopedType = Extract<
74
- ScopeOnlyType,
75
- Extract<ResourceKey, { orgId: string }>["type"]
76
- >;
77
- type UserScopedType = Extract<
78
- ScopeOnlyType,
79
- Extract<ResourceKey, { userId: string }>["type"]
80
- >;
81
- type SystemScopedType = Extract<
82
- ScopeOnlyType,
83
- Extract<ResourceKey, { scope: "system" }>["type"]
84
- >;
85
-
86
- /**
87
- * Identities with a single extra segment. The `satisfies` checks the FIELD NAME
88
- * against that member's own keys, so renaming `memberId` in the union — or
89
- * pointing a key at a field it does not have — fails to compile here.
90
- */
91
- const IDENTITY_FIELDS = {
92
- member: "memberId",
93
- team: "teamId",
94
- department: "departmentId",
95
- chat: "chatId",
96
- companyMdDoc: "slug",
97
- companyMdContextBank: "slug",
98
- companyMdAccessRequests: "docId",
99
- companyMdDocHistory: "docId",
100
- orgUnit: "unitId",
101
- orgUnitChildren: "unitId",
102
- orgUnitAncestors: "unitId",
103
- orgUnitMemberships: "unitId",
104
- orgUnitPermissions: "unitId",
105
- orgUnitOpenRoles: "unitId",
106
- orgUnitMyAuthority: "unitId",
107
- } as const satisfies { [T in ResourceKey["type"]]?: IdentityFieldsOf<T> };
108
-
109
- /**
110
- * Identities with a COMPOSITE (multi-segment) identity. Checked before
111
- * {@link IDENTITY_FIELDS}, which hard-asserts a two-element `rest` and would
112
- * otherwise reject these.
113
- *
114
- * A map of its own rather than widening `IDENTITY_FIELDS` to `string | string[]`:
115
- * the single-segment case is every other key in the union, and making it pay for
116
- * this one would put a branch in the hot path for no reader's benefit.
117
- */
118
- const COMPOSITE_IDENTITY_FIELDS = {
119
- commentThreads: ["subjectType", "subjectId"],
120
- companyMdDocVersion: ["docId", "versionId"],
121
- } as const satisfies {
122
- [T in ResourceKey["type"]]?: readonly IdentityFieldsOf<T>[];
123
- };
124
-
125
- const ORG_SCOPED_TYPES = [
126
- "members",
127
- "departments",
128
- "chats",
129
- "teams",
130
- "integrations",
131
- "invites",
132
- "orgDirectory",
133
- "auditEvents",
134
- "timeline",
135
- "workspace",
136
- "workspaceDomains",
137
- "authSettings",
138
- "billing",
139
- "aiUsage",
140
- "deletionEligibility",
141
- "transferOwnership",
142
- "companyMdDocs",
143
- "directGrants",
144
- "orgTree",
145
- "orgLevelConfig",
146
- "peopleOrgChart",
147
- "orgUnitOwners",
148
- "actionItems",
149
- "feed",
150
- "orgSystemEvents",
151
- ] as const satisfies readonly OrgScopedType[];
152
-
153
- const USER_SCOPED_TYPES = [
154
- "dismissedBanners",
155
- "userOrgs",
156
- "sessions",
157
- "userMd",
158
- "viewer",
159
- ] as const satisfies readonly UserScopedType[];
160
-
161
28
  /**
162
- * System-scoped types (ADR-CONTRACTS-052) tenant-less super-admin resources.
163
- * Their query key is [type, 'system']; they carry no orgId or userId.
164
- * Intentionally NOT exported internal to the parser like the other scope arrays.
165
- */
166
- const SYSTEM_SCOPED_TYPES = [
167
- "internalAdminAiProviders",
168
- "internalAdminPrompts",
169
- "internalAdminAiRuntimeDefaults",
170
- "factoryFloor",
171
- "factorySnapshot",
172
- "factoryKpis",
173
- ] as const satisfies readonly SystemScopedType[];
174
-
175
- /** Every literal `fromQueryKey` can route, across all five tables. */
176
- type RoutedType =
177
- | keyof typeof IDENTITY_FIELDS
178
- | keyof typeof COMPOSITE_IDENTITY_FIELDS
179
- | (typeof ORG_SCOPED_TYPES)[number]
180
- | (typeof USER_SCOPED_TYPES)[number]
181
- | (typeof SYSTEM_SCOPED_TYPES)[number];
182
-
183
- type Assert<T extends true> = T;
184
-
185
- /**
186
- * THE DRIFT DETECTOR. Register a union member and forget its routing table and
187
- * this fails to compile — instead of shipping a key that parses nowhere,
188
- * matches nothing, and disables the query that reads it.
189
- *
190
- * The false branch resolves to the UNROUTED LITERALS rather than to `false`, so
191
- * the diagnostic names the culprit:
192
- * `Type '"directGrants"' does not satisfy the constraint 'true'`.
193
- *
194
- * EXPORTED, though nothing consumes it. This package ships `src`, so every
195
- * consumer typechecks this file under ITS OWN compiler options — and the
196
- * backend sets `noUnusedLocals`, which rejects an unexported type alias that
197
- * nothing references. Keeping it private broke `tsc` in a consumer while
198
- * passing here, so the export is what makes the assertion portable, not a
199
- * widening of the public vocabulary. Do not "tidy" it away.
29
+ * The routing tables `fromQueryKey` reads, and the drift detector over them,
30
+ * live in `resource-key-tables.ts`. `RoutingExhaustivenessWitness` is
31
+ * re-exported so its import path is unchanged see the note on its definition
32
+ * for why it is exported at all.
200
33
  */
201
- export type RoutingExhaustivenessWitness = Assert<
202
- [Exclude<ResourceKey["type"], RoutedType>] extends [never]
203
- ? true
204
- : Exclude<ResourceKey["type"], RoutedType>
205
- >;
34
+ export type { RoutingExhaustivenessWitness } from "./resource-key-tables";
35
+ import {
36
+ IDENTITY_FIELDS,
37
+ COMPOSITE_IDENTITY_FIELDS,
38
+ ORG_SCOPED_TYPES,
39
+ USER_SCOPED_TYPES,
40
+ SYSTEM_SCOPED_TYPES,
41
+ } from "./resource-key-tables";
206
42
 
207
43
  /**
208
44
  * Canonical ResourceKey → query key conversion.