@drhomet/mithaq 0.0.0-stage → 0.1.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.
Files changed (151) hide show
  1. package/LICENSE +22 -0
  2. package/LICENSES/payload.txt +22 -0
  3. package/LICENSES/ponytail.txt +21 -0
  4. package/dist/asas/actor.d.ts +96 -0
  5. package/dist/asas/actor.js +114 -0
  6. package/dist/asas/build.d.ts +231 -0
  7. package/dist/asas/build.js +787 -0
  8. package/dist/asas/cli/mithaq.d.ts +2 -0
  9. package/dist/asas/cli/mithaq.js +145 -0
  10. package/dist/asas/cli/upgrade.d.ts +20 -0
  11. package/dist/asas/cli/upgrade.js +147 -0
  12. package/dist/asas/http/fetch.d.ts +23 -0
  13. package/dist/asas/http/fetch.js +115 -0
  14. package/dist/asas/http/orpc.d.ts +43 -0
  15. package/dist/asas/http/orpc.js +135 -0
  16. package/dist/asas/runner/bulk.d.ts +20 -0
  17. package/dist/asas/runner/bulk.js +191 -0
  18. package/dist/asas/runner/errors.d.ts +60 -0
  19. package/dist/asas/runner/errors.js +59 -0
  20. package/dist/asas/runner/read.d.ts +68 -0
  21. package/dist/asas/runner/read.js +579 -0
  22. package/dist/asas/runner/runtime.d.ts +21 -0
  23. package/dist/asas/runner/runtime.js +8 -0
  24. package/dist/asas/runner/steps.d.ts +400 -0
  25. package/dist/asas/runner/steps.js +271 -0
  26. package/dist/asas/runner/tenant.d.ts +54 -0
  27. package/dist/asas/runner/tenant.js +213 -0
  28. package/dist/asas/runner/write.d.ts +444 -0
  29. package/dist/asas/runner/write.js +791 -0
  30. package/dist/auth/better-auth/access.d.ts +15 -0
  31. package/dist/auth/better-auth/access.js +71 -0
  32. package/dist/auth/better-auth/generate.d.ts +29 -0
  33. package/dist/auth/better-auth/generate.js +310 -0
  34. package/dist/auth/better-auth/index.d.ts +92 -0
  35. package/dist/auth/better-auth/index.js +81 -0
  36. package/dist/auth/better-auth/tenant.d.ts +18 -0
  37. package/dist/auth/better-auth/tenant.js +26 -0
  38. package/dist/auth/local/index.d.ts +285 -0
  39. package/dist/auth/local/index.js +736 -0
  40. package/dist/base/decimal.d.ts +9 -0
  41. package/dist/base/decimal.js +16 -0
  42. package/dist/base/fields.d.ts +123 -0
  43. package/dist/base/fields.js +51 -0
  44. package/dist/base/index.d.ts +46 -0
  45. package/dist/base/index.js +5 -0
  46. package/dist/base/kinds.d.ts +54 -0
  47. package/dist/base/kinds.js +78 -0
  48. package/dist/base/rules.d.ts +73 -0
  49. package/dist/base/rules.js +80 -0
  50. package/dist/drizzle/index.d.ts +438 -0
  51. package/dist/drizzle/index.js +832 -0
  52. package/dist/drizzle/kinds.d.ts +27 -0
  53. package/dist/drizzle/kinds.js +41 -0
  54. package/dist/drizzle/migrate.d.ts +133 -0
  55. package/dist/drizzle/migrate.js +1285 -0
  56. package/dist/drizzle/proxy/index.d.ts +1 -0
  57. package/dist/drizzle/proxy/index.js +1 -0
  58. package/dist/drizzle/proxy/node-postgres.d.ts +1 -0
  59. package/dist/drizzle/proxy/node-postgres.js +1 -0
  60. package/dist/drizzle/proxy/pg-core.d.ts +1 -0
  61. package/dist/drizzle/proxy/pg-core.js +1 -0
  62. package/dist/drizzle/rules.d.ts +336 -0
  63. package/dist/drizzle/rules.js +44 -0
  64. package/dist/index.d.ts +45 -0
  65. package/dist/index.js +36 -0
  66. package/dist/mithaq/define.d.ts +288 -0
  67. package/dist/mithaq/define.js +43 -0
  68. package/dist/mithaq/generate-messages.d.ts +38 -0
  69. package/dist/mithaq/generate-messages.js +234 -0
  70. package/dist/mithaq/language.d.ts +335 -0
  71. package/dist/mithaq/language.js +76 -0
  72. package/dist/mithaq/lock.d.ts +71 -0
  73. package/dist/mithaq/lock.js +329 -0
  74. package/dist/mithaq/messages.d.ts +55 -0
  75. package/dist/mithaq/messages.js +106 -0
  76. package/dist/mithaq/refusal.d.ts +6 -0
  77. package/dist/mithaq/refusal.js +6 -0
  78. package/dist/mithaq/resolve.d.ts +10 -0
  79. package/dist/mithaq/resolve.js +954 -0
  80. package/dist/mithaq/rows.d.ts +87 -0
  81. package/dist/mithaq/rows.js +174 -0
  82. package/dist/mithaq/rukn.d.ts +72 -0
  83. package/dist/mithaq/rukn.js +15 -0
  84. package/dist/mithaq/standard-schema.d.ts +38 -0
  85. package/dist/mithaq/standard-schema.js +2 -0
  86. package/dist/mithaq/types.d.ts +358 -0
  87. package/dist/mithaq/types.js +15 -0
  88. package/dist/mithaq/user.d.ts +19 -0
  89. package/dist/mithaq/user.js +16 -0
  90. package/dist/mithaq/where.d.ts +32 -0
  91. package/dist/mithaq/where.js +87 -0
  92. package/dist/rbac/index.d.ts +105 -0
  93. package/dist/rbac/index.js +182 -0
  94. package/dist/rbac/steps.d.ts +22 -0
  95. package/dist/rbac/steps.js +161 -0
  96. package/dist/rich-text/index.d.ts +27 -0
  97. package/dist/rich-text/index.js +58 -0
  98. package/dist/rich-text/rich-text.d.ts +159 -0
  99. package/dist/rich-text/rich-text.js +372 -0
  100. package/dist/screen/client.d.ts +153 -0
  101. package/dist/screen/client.js +68 -0
  102. package/dist/screen/generate.d.ts +14 -0
  103. package/dist/screen/generate.js +226 -0
  104. package/dist/screen/index.d.ts +479 -0
  105. package/dist/screen/index.js +645 -0
  106. package/dist/screen/react.d.ts +95 -0
  107. package/dist/screen/react.js +58 -0
  108. package/dist/screen/studio.d.ts +24 -0
  109. package/dist/screen/studio.js +68 -0
  110. package/dist/service/index.d.ts +63 -0
  111. package/dist/service/index.js +15 -0
  112. package/dist/storage/allowed-type.d.ts +5 -0
  113. package/dist/storage/allowed-type.js +7 -0
  114. package/dist/storage/index.d.ts +43 -0
  115. package/dist/storage/index.js +44 -0
  116. package/dist/storage/storage.d.ts +384 -0
  117. package/dist/storage/storage.js +405 -0
  118. package/dist/versions/index.d.ts +37 -0
  119. package/dist/versions/index.js +8 -0
  120. package/dist/versions/versions.d.ts +104 -0
  121. package/dist/versions/versions.js +160 -0
  122. package/dist/zod/index.d.ts +184 -0
  123. package/dist/zod/index.js +121 -0
  124. package/dist/zod/kinds.d.ts +34 -0
  125. package/dist/zod/kinds.js +49 -0
  126. package/dist/zod/rules.d.ts +117 -0
  127. package/dist/zod/rules.js +67 -0
  128. package/package.json +63 -4
  129. package/r/mithaq-cells.json +20 -0
  130. package/r/mithaq-controls.json +37 -0
  131. package/r/mithaq-directional-icon.json +15 -0
  132. package/r/mithaq-expected-updated-at.json +15 -0
  133. package/r/mithaq-field-shell.json +18 -0
  134. package/r/mithaq-filter-operators.json +15 -0
  135. package/r/mithaq-form.json +33 -0
  136. package/r/mithaq-list-columns.json +23 -0
  137. package/r/mithaq-list-filters.json +24 -0
  138. package/r/mithaq-list-pagination.json +24 -0
  139. package/r/mithaq-list-query.json +18 -0
  140. package/r/mithaq-list-selection.json +19 -0
  141. package/r/mithaq-list.json +33 -0
  142. package/r/mithaq-nav.json +24 -0
  143. package/r/mithaq-nodes.json +34 -0
  144. package/r/mithaq-relationship-cell.json +20 -0
  145. package/r/mithaq-relationship-control.json +20 -0
  146. package/r/mithaq-rich-text.json +40 -0
  147. package/r/mithaq-screens-host.json +96 -0
  148. package/r/mithaq-storage.json +44 -0
  149. package/r/mithaq-upload.json +29 -0
  150. package/r/registry.json +550 -0
  151. package/README.md +0 -3
@@ -0,0 +1,444 @@
1
+ import type { AdminAccess, LocalesOf, ResolvedKayan, RuntimeField, ServiceOf } from '../../mithaq/types.ts';
2
+ import type { BuiltTables } from '../../drizzle/index.ts';
3
+ import { defaultKinds, type Kind } from '../../base/kinds.ts';
4
+ import type { RichTextValue } from '../../rich-text/rich-text.ts';
5
+ import type { Store } from '../../mithaq/language.ts';
6
+ import type { LanguageOf } from '../../mithaq/define.ts';
7
+ import type { InferInput, InferOutput, StandardSchemaV1 } from '../../mithaq/standard-schema.ts';
8
+ import { type BulkResult, type Context, type ContextOf, type Ctx, type DerivedSchemas, type OperationEffect, type ResolvedOperation, type StepsOf, type Tools, type WriteTools, type WriteStep } from './steps.ts';
9
+ import { type Open } from './runtime.ts';
10
+ import type { FindInput } from './read.ts';
11
+ import { type TenantReach } from './tenant.ts';
12
+ import type { FieldWhere, Operator, Where } from '../../mithaq/where.ts';
13
+ /** The key of `Options` only the bulk runner sets. */
14
+ export declare const ontoRow: unique symbol;
15
+ /** The caller's own context, required where the project declared one. */
16
+ type ContextOption<Extra extends Record<string, unknown>> = [Record<string, unknown>] extends [Extra] ? {
17
+ context?: Extra;
18
+ } : {
19
+ context: Extra;
20
+ };
21
+ /** The second argument of every write function. */
22
+ export type Options<Actor = unknown, Extra extends Record<string, unknown> = Record<string, unknown>> = {
23
+ /** Whoever is writing. A `user.<key>` default reads off it. */
24
+ actor?: Actor;
25
+ /** On a kayan that keeps drafts, save a version alone unless the write sends `_status: 'published'`; a read then reads each row's latest version. */
26
+ draft?: boolean;
27
+ /** With `draft`, overwrite the latest version in place where it is itself an autosave. */
28
+ autosave?: boolean;
29
+ [ontoRow]?: true;
30
+ } & ContextOption<Extra>;
31
+ export type ReadOptions<Actor = unknown, Extra extends Record<string, unknown> = Record<string, unknown>> = Options<Actor, Extra> & {
32
+ /**
33
+ * How far the read reaches past the active organization: `'mine'` is every organization the
34
+ * actor is a verified member of, each under the roles it holds there; `'all'` is every tenant,
35
+ * for platform staff in the platform app alone. A `where` on the tenant field only narrows it.
36
+ */
37
+ tenant?: TenantReach;
38
+ };
39
+ /**
40
+ * The keys this build's runner declared, which is what a caller of it has to
41
+ * send and what every step of it reads.
42
+ */
43
+ type ContextExtra<L> = ContextOf<ServiceOf<L>>;
44
+ /** The options a caller of this build passes every operation. */
45
+ type CallOptions<L, Actor, Read extends boolean = false> = Read extends true ? ReadOptions<Actor, ContextExtra<L>> : Options<Actor, ContextExtra<L>>;
46
+ type CallArgs<L, Actor, Input, Read extends boolean = false> = [Record<string, unknown>] extends [ContextExtra<L>] ? {} extends Input ? [input?: Input, options?: CallOptions<L, Actor, Read>] : [input: Input, options?: CallOptions<L, Actor, Read>] : [input: Input, options: CallOptions<L, Actor, Read>];
47
+ /** The admin provider as the runner sees it: the kayan's name, and its gate. */
48
+ export type ManagedAdmin<Actor = unknown> = {
49
+ access?: AdminAccess<Actor>;
50
+ kayan?: string;
51
+ };
52
+ export declare const assertFieldWhere: ({ said, key, kind, operators, value, valued }: {
53
+ said: string;
54
+ key: string;
55
+ kind: string;
56
+ operators?: readonly Operator[];
57
+ value: unknown;
58
+ valued?: boolean;
59
+ }) => FieldWhere;
60
+ export declare const assertWhere: (kayan: ResolvedKayan, where: unknown) => Where;
61
+ export declare const assertWhereGrammar: (kayan: ResolvedKayan, where: unknown) => Where;
62
+ export declare const aliveWhere: (kayan: ResolvedKayan) => Where | undefined;
63
+ export declare const publishedWhere: (kayan: ResolvedKayan) => Where | undefined;
64
+ export declare const projectReadableFields: <Actor>({ kayan, row, actor, }: {
65
+ kayan: ResolvedKayan;
66
+ row: Record<string, unknown>;
67
+ actor: Actor | null;
68
+ }) => Promise<{
69
+ [x: string]: unknown;
70
+ }>;
71
+ export declare const publicResult: <Actor>({ kayan, row, actor, internalOutput, publicOutput, }: {
72
+ kayan: ResolvedKayan;
73
+ row: Record<string, unknown>;
74
+ actor: Actor | null;
75
+ internalOutput: StandardSchemaV1;
76
+ publicOutput?: StandardSchemaV1;
77
+ }) => Promise<Record<string, unknown>>;
78
+ export declare const assertSingleConstrained: (kayan: ResolvedKayan, where: Where | undefined) => void;
79
+ /**
80
+ * Refuses a relationship value naming a row the write may not point at: one of another
81
+ * organization than the written row's, or one `access` leaves out. A step's own raw write
82
+ * passes no `access`, so it is held to the organization alone.
83
+ */
84
+ export declare const assertReferences: ({ kayan, store, data, tenant, access, tx }: {
85
+ kayan: ResolvedKayan;
86
+ store: Pick<Store, 'find'>;
87
+ data: Record<string, unknown>;
88
+ /** The organization the written row belongs to, or the active one where the row belongs to none. */
89
+ tenant: unknown;
90
+ /** What else the target's row must meet: its read access for this actor. */
91
+ access?: (target: ResolvedKayan) => Promise<Where | undefined>;
92
+ tx?: unknown;
93
+ }) => Promise<void>;
94
+ export declare const defaultAccess: <Actor>(admin: ManagedAdmin<Actor> | undefined, actor: Actor | null) => Promise<boolean>;
95
+ export type Authorize = <Actor>(args: {
96
+ admin?: ManagedAdmin<Actor>;
97
+ actor: Actor | null;
98
+ data: Record<string, unknown>;
99
+ effect: OperationEffect;
100
+ kayan: ResolvedKayan;
101
+ kind?: Tools['kind'];
102
+ operation?: string;
103
+ }) => Promise<Where | undefined>;
104
+ export declare const defaultAuthorize: Authorize;
105
+ export declare const beginWrite: <Actor = unknown>({ kayan, operation, store, cap, options, }: {
106
+ kayan: ResolvedKayan;
107
+ operation: string;
108
+ store: Store;
109
+ cap: number;
110
+ options?: Options<Actor>;
111
+ }) => {
112
+ actor: NonNullable<Actor> | null;
113
+ context: Context;
114
+ entry: Open;
115
+ open: Map<any, any>;
116
+ };
117
+ export declare const runOutside: <Actor>({ kayan, tools, slot, list, start, around, }: {
118
+ kayan: ResolvedKayan;
119
+ tools: WriteTools<unknown, Actor>;
120
+ slot: 'afterCommit' | 'beforeTransaction';
121
+ list: readonly WriteStep[];
122
+ start: Ctx;
123
+ around: {
124
+ context: Context;
125
+ user: Actor | null;
126
+ };
127
+ }) => Promise<Ctx>;
128
+ export declare const drain: (queue: readonly (() => Promise<void>)[]) => Promise<void>;
129
+ export declare const write: <Actor = unknown>({ kayan, declaration, tools, store, cap, authorize, admin, tenantOf, }: {
130
+ kayan: ResolvedKayan;
131
+ declaration: ResolvedOperation;
132
+ tools: WriteTools<unknown, Actor>;
133
+ store: Store;
134
+ cap: number;
135
+ authorize: Authorize;
136
+ admin?: ManagedAdmin<Actor>;
137
+ /** The organization the actor's session names, which a tenant-owned row is made in. */
138
+ tenantOf: (actor: unknown) => string | undefined;
139
+ }) => (data?: Record<string, unknown>, options?: Options<Actor>) => Promise<Record<string, unknown>>;
140
+ type Registry = readonly {
141
+ name: string;
142
+ fields: Record<string, RuntimeField>;
143
+ }[];
144
+ type LanguageValues = {
145
+ kinds: Record<string, Kind>;
146
+ targets?: unknown;
147
+ };
148
+ type Registered<List extends Registry, Name> = Extract<List[number], {
149
+ name: Name;
150
+ }>;
151
+ type Related<F, List extends Registry> = F extends {
152
+ relationTo: infer Relation;
153
+ } ? Relation extends string ? Registered<List, Relation> : Relation extends () => infer Target ? Target extends {
154
+ name: infer Name;
155
+ } ? [Registered<List, Name>] extends [never] ? Target : Registered<List, Name> : never : never : never;
156
+ type OverrideSchema<F, L extends LanguageValues> = ServiceOf<L> extends {
157
+ schema: infer Name extends string;
158
+ } ? string extends Name ? never : F extends {
159
+ targets: infer Overrides;
160
+ } ? Name extends keyof Overrides ? Overrides[Name] extends StandardSchemaV1 ? Overrides[Name] : never : never : never : never;
161
+ type Localize<F, L extends LanguageValues, V> = F extends {
162
+ rules: {
163
+ localized: true;
164
+ };
165
+ } ? Record<LocalesOf<L>, V> : V;
166
+ type KindCarried<F, L extends LanguageValues, List extends Registry> = F extends {
167
+ kind: infer Name extends keyof L['kinds'];
168
+ } ? L['kinds'][Name] extends {
169
+ pointsAtRow: true;
170
+ } ? Related<F, List> extends {
171
+ fields: {
172
+ id: infer Id;
173
+ };
174
+ } ? F extends {
175
+ hasMany: true;
176
+ } ? Value<Id, L, List>[] : Value<Id, L, List> : never : L['kinds'][Name] extends Kind<infer V, string> ? V : never : never;
177
+ type Value<F, L extends LanguageValues, List extends Registry> = [OverrideSchema<F, L>] extends [never] ? Localize<F, L, KindCarried<F, L, List>> : Exclude<InferOutput<OverrideSchema<F, L> & StandardSchemaV1>, undefined>;
178
+ type InputValue<F, L extends LanguageValues, List extends Registry> = [OverrideSchema<F, L>] extends [never] ? Value<F, L, List> : InferInput<OverrideSchema<F, L> & StandardSchemaV1>;
179
+ type Supplied<Fields, On extends 'create' | 'update'> = {
180
+ [K in keyof Fields as K extends 'id' ? K : Fields[K] extends {
181
+ rules: {
182
+ providedBy: Record<On, infer Provider>;
183
+ };
184
+ } ? [Provider] extends ['client'] ? K : never : K]: Fields[K];
185
+ };
186
+ /** Required, and nothing fills it for you. */
187
+ type Needed<F> = F extends {
188
+ rules: {
189
+ required: true;
190
+ };
191
+ } ? F extends {
192
+ rules: {
193
+ defaultValue: unknown;
194
+ };
195
+ } | {
196
+ rules: {
197
+ defaultNow: true;
198
+ };
199
+ } ? false : true : false;
200
+ /** Optional columns accept null; required columns and ids never do. */
201
+ type Settable<F, L extends LanguageValues, List extends Registry> = F extends {
202
+ rules: {
203
+ required: true;
204
+ };
205
+ } ? InputValue<F, L, List> : InputValue<F, L, List> | null;
206
+ type CreateInput<Fields extends Record<string, RuntimeField>, L extends LanguageValues, List extends Registry> = CreateKeys<Supplied<Fields, 'create'>, L, List>;
207
+ type CreateKeys<Fields, L extends LanguageValues, List extends Registry> = {
208
+ [K in keyof Fields as K extends 'id' ? never : Needed<Fields[K]> extends true ? K : never]: InputValue<Fields[K], L, List>;
209
+ } & {
210
+ [K in keyof Fields as K extends 'id' ? K : Needed<Fields[K]> extends true ? never : K]?: K extends 'id' ? InputValue<Fields[K], L, List> : Settable<Fields[K], L, List>;
211
+ };
212
+ /** An update carries only what changes; each site that takes one adds the id beside it. */
213
+ type UpdateInput<Fields extends Record<string, RuntimeField>, L extends LanguageValues, List extends Registry> = {
214
+ [K in keyof Supplied<Fields, 'update'> as K extends 'id' ? never : K]?: Settable<Supplied<Fields, 'update'>[K], L, List>;
215
+ };
216
+ /**
217
+ * The id's type, and `never` for fields that name no id. `never` is reachable
218
+ * at the type level only: `buildAsas` refuses a kayan with no id field.
219
+ */
220
+ type Id<Fields, L extends LanguageValues, List extends Registry> = Fields extends {
221
+ id: infer F;
222
+ } ? InputValue<F, L, List> : never;
223
+ type StoredRow<Fields extends Record<string, RuntimeField>, L extends LanguageValues, List extends Registry> = {
224
+ [K in keyof Fields]: K extends 'id' ? Value<Fields[K], L, List> : Fields[K] extends {
225
+ rules: {
226
+ required: true;
227
+ };
228
+ } ? Value<Fields[K], L, List> : Value<Fields[K], L, List> | null;
229
+ };
230
+ type Opaque<F> = F extends {
231
+ kind: 'join';
232
+ } ? F : F extends {
233
+ relationTo: unknown;
234
+ } ? Omit<F, 'kind'> & {
235
+ kind: 'opaque';
236
+ } : F;
237
+ type DerivedFields<Fields extends Record<string, RuntimeField>> = {
238
+ [K in keyof Fields]: Opaque<Fields[K]>;
239
+ };
240
+ type Deriving<Schema extends string> = {
241
+ kinds: typeof defaultKinds & {
242
+ opaque: Kind<unknown>;
243
+ richText: Kind<RichTextValue>;
244
+ };
245
+ targets: {
246
+ service: {
247
+ capability: 'service';
248
+ schema: Schema;
249
+ };
250
+ };
251
+ };
252
+ /** Every field, with the id optional: what a target's derived create shape takes. */
253
+ export type CreateOf<Fields extends Record<string, RuntimeField>, Schema extends string> = CreateInput<DerivedFields<Fields>, Deriving<Schema>, []>;
254
+ /** What an addressed operation takes: the id, inside its input. */
255
+ export type ByID<Fields, L extends LanguageValues, List extends Registry> = {
256
+ id: Id<Fields, L, List>;
257
+ };
258
+ /** The same shape partial, with the id required. */
259
+ export type UpdateOf<Fields extends Record<string, RuntimeField>, Schema extends string> = UpdateInput<DerivedFields<Fields>, Deriving<Schema>, []> & ByID<DerivedFields<Fields>, Deriving<Schema>, []>;
260
+ /** The id alone: what a target's derived id shape takes, and nothing beside it. */
261
+ export type IdOf<Fields extends Record<string, RuntimeField>, Schema extends string> = ByID<DerivedFields<Fields>, Deriving<Schema>, []>;
262
+ /** Every column, and a nullable one wherever nothing requires the field. */
263
+ export type RowOf<Fields extends Record<string, RuntimeField>, Schema extends string> = StoredRow<DerivedFields<Fields>, Deriving<Schema>, []>;
264
+ /** The row that comes back after field read access projection. */
265
+ export type Row<Fields extends Record<string, RuntimeField>, L extends LanguageValues, List extends Registry> = Omit<StoredRow<Fields, L, List>, {
266
+ [K in keyof Fields]: Fields[K] extends {
267
+ access: {
268
+ read: unknown;
269
+ };
270
+ } ? K : never;
271
+ }[keyof Fields]> & Partial<Pick<StoredRow<Fields, L, List>, {
272
+ [K in keyof Fields]: Fields[K] extends {
273
+ access: {
274
+ read: unknown;
275
+ };
276
+ } ? K : never;
277
+ }[keyof Fields]>>;
278
+ type OperationInput<Operation> = Operation extends {
279
+ input: (...args: never[]) => infer Schema;
280
+ } ? Schema extends StandardSchemaV1 ? InferInput<Schema> : never : never;
281
+ /** The declared input where the operation has one, and the derived shape where it does not. */
282
+ export type OperationData<Operation, Derived> = [OperationInput<Operation>] extends [never] ? Derived : OperationInput<Operation>;
283
+ type OperationOutput<Operation> = Operation extends {
284
+ input: (...args: never[]) => infer Schema;
285
+ } ? Schema extends StandardSchemaV1 ? InferOutput<Schema> : never : never;
286
+ /** What a step is handed: the parsed shape where the operation declares one, the derived shape where it does not. */
287
+ export type OperationParsed<Operation, Derived> = [OperationOutput<Operation>] extends [never] ? Derived : OperationOutput<Operation>;
288
+ type SealOfStep<Held> = Held extends {
289
+ __seal: infer Name;
290
+ } ? Name : never;
291
+ type ActingSeal<Operation> = StepsOf<Operation> extends readonly (infer Held)[] ? Extract<SealOfStep<Held>, 'count' | 'find' | 'findOne' | 'insert' | 'remove' | 'update' | 'updateMany' | 'deleteMany' | 'findVersions' | 'findVersionByID' | 'restoreVersion'> : never;
292
+ /** `many`, `one`, `count`, `versions`, `version`, or nothing at all for an operation that writes. */
293
+ type ReadModeOf<Operation> = [ActingSeal<Operation>] extends [never] ? undefined : ActingSeal<Operation> extends 'find' ? 'many' : ActingSeal<Operation> extends 'findOne' ? 'one' : ActingSeal<Operation> extends 'count' ? 'count' : ActingSeal<Operation> extends 'findVersions' ? 'versions' : ActingSeal<Operation> extends 'findVersionByID' ? 'version' : undefined;
294
+ type IsReadOperation<Operation> = [ReadModeOf<Operation>] extends [undefined] ? false : true;
295
+ /**
296
+ * A kayan's operations, read off its own declaration alone: nothing is merged
297
+ * in, so the names a kayan answers are the keys it wrote.
298
+ */
299
+ type OwnOperations<K> = K extends {
300
+ targets: {
301
+ service: {
302
+ operations: infer O;
303
+ };
304
+ };
305
+ } ? O : Record<never, never>;
306
+ type OwnOperation<K, Name extends PropertyKey> = Name extends keyof OwnOperations<K> ? OwnOperations<K>[Name] : never;
307
+ export type DerivedInput<Operation, Fields extends Record<string, RuntimeField>, L extends LanguageValues, List extends Registry> = ActingSeal<Operation> extends 'insert' ? CreateInput<Fields, L, List> : ActingSeal<Operation> extends 'updateMany' ? {
308
+ where: Where;
309
+ data: UpdateInput<Fields, L, List>;
310
+ } : ActingSeal<Operation> extends 'deleteMany' ? {
311
+ where: Where;
312
+ } : ActingSeal<Operation> extends 'findOne' ? ByID<Fields, L, List> & Pick<FindInput, 'depth'> : ActingSeal<Operation> extends 'remove' ? ByID<Fields, L, List> : ActingSeal<Operation> extends 'findVersionByID' | 'restoreVersion' ? {
313
+ id: string;
314
+ } : ActingSeal<Operation> extends 'update' ? UpdateInput<Fields, L, List> & ByID<Fields, L, List> : ActingSeal<Operation> extends 'count' ? {
315
+ where?: Where;
316
+ } : FindInput;
317
+ /** One version as a version read answers it: its snapshot cut to the reader's field access and held to its kinds, so every column may be absent. */
318
+ export type Version<Doc> = {
319
+ id: string;
320
+ parent: unknown;
321
+ latest: boolean;
322
+ autosave: boolean;
323
+ createdAt: Date;
324
+ updatedAt: Date;
325
+ version: Partial<Doc>;
326
+ };
327
+ type PaginatedRows<Doc> = {
328
+ docs: Doc[];
329
+ totalDocs: number;
330
+ limit: number;
331
+ page: number;
332
+ totalPages: number;
333
+ hasNextPage: boolean;
334
+ hasPrevPage: boolean;
335
+ nextPage: number | null;
336
+ prevPage: number | null;
337
+ pagingCounter: number;
338
+ };
339
+ type OutputRow<Operation> = Operation extends {
340
+ output: infer Given;
341
+ } ? Given extends (...args: never[]) => infer Schema ? Schema extends StandardSchemaV1 ? InferOutput<Schema> : never : Given extends StandardSchemaV1 ? InferOutput<Given> : never : never;
342
+ /** The custom output's row where the operation declares one, the kayan's row where it does not. */
343
+ type ResultRow<Operation, Fields extends Record<string, RuntimeField>, L extends LanguageValues, List extends Registry> = [
344
+ OutputRow<Operation>
345
+ ] extends [never] ? Row<Fields, L, List> : OutputRow<Operation>;
346
+ type BulkOutput<Operation, Doc> = [OutputRow<Operation>] extends [never] ? BulkResult<Doc> : OutputRow<Operation>;
347
+ type OperationResult<Operation, Fields extends Record<string, RuntimeField>, L extends LanguageValues, List extends Registry> = [
348
+ ActingSeal<Operation>
349
+ ] extends [never] ? Promise<ResultRow<Operation, Fields, L, List>> : ActingSeal<Operation> extends 'updateMany' | 'deleteMany' ? Promise<BulkOutput<Operation, Row<Fields, L, List>>> : ReadModeOf<Operation> extends 'count' ? Promise<{
350
+ totalDocs: number;
351
+ }> : ReadModeOf<Operation> extends 'versions' ? Promise<PaginatedRows<Version<Row<Fields, L, List>>>> : ReadModeOf<Operation> extends 'version' ? Promise<Version<Row<Fields, L, List>>> : ReadModeOf<Operation> extends 'many' ? Promise<PaginatedRows<ResultRow<Operation, Fields, L, List>>> : ReadModeOf<Operation> extends 'one' ? Promise<ResultRow<Operation, Fields, L, List>> : Promise<ResultRow<Operation, Fields, L, List>>;
352
+ /** What one operation takes: its declared input, or the shape its seal implies. */
353
+ type InputOf<K, Name extends PropertyKey, Fields extends Record<string, RuntimeField>, L extends LanguageValues, List extends Registry> = OperationData<OwnOperation<K, Name>, DerivedInput<OwnOperation<K, Name>, Fields, L, List>>;
354
+ type BoundOne<K, Fields extends Record<string, RuntimeField>, L extends LanguageValues, List extends Registry, Mode extends 'read' | 'write'> = {
355
+ [Name in keyof OwnOperations<K> as Mode extends 'write' ? Name : IsReadOperation<OwnOperation<K, Name>> extends true ? Name : never]: (...input: {} extends InputOf<K, Name, Fields, L, List> ? [input?: InputOf<K, Name, Fields, L, List>] : [input: InputOf<K, Name, Fields, L, List>]) => OperationResult<OwnOperation<K, Name>, Fields, L, List>;
356
+ };
357
+ export type BoundOf<Mode extends 'read' | 'write'> = <const K extends Registry[number] & {
358
+ single?: never;
359
+ }>(kayan: K) => BoundOne<K, K['fields'], LanguageOf<K>, readonly [K], Mode>;
360
+ export type BoundKayans<KayanList extends Registry, L extends LanguageValues, Mode extends 'read' | 'write' = 'write'> = {
361
+ [K in KayanList[number] as K['name']]: BoundOne<K, K['fields'], L, KayanList, Mode>;
362
+ };
363
+ type OwnService<K> = K extends {
364
+ targets: {
365
+ service: infer Service;
366
+ };
367
+ } ? Service : unknown;
368
+ type DefaultStoreOf<L> = ServiceOf<L> extends {
369
+ store: infer Name extends string;
370
+ } ? Name : never;
371
+ type StoreNameOf<K, L> = OwnService<K> extends {
372
+ store: infer Name extends string;
373
+ } ? Name : DefaultStoreOf<L>;
374
+ type SchemaNameOf<K, L> = OwnService<K> extends {
375
+ schema: infer Name extends string;
376
+ } ? Name : ServiceOf<L> extends {
377
+ schema: infer Name extends string;
378
+ } ? Name : never;
379
+ type TargetNamed<L, Name> = L extends {
380
+ targets: infer Targets;
381
+ } ? Name extends keyof Targets ? Targets[Name] : never : never;
382
+ type FieldsOfKayan<K> = K extends {
383
+ fields: infer Fields extends Record<string, RuntimeField>;
384
+ } ? Fields : never;
385
+ type KayanOutputs<K, List extends Registry, L extends LanguageValues, Operations> = {
386
+ service: {
387
+ operations: Operations;
388
+ };
389
+ } & {
390
+ [Name in SchemaNameOf<K, L>]: {
391
+ schemas: DerivedSchemas<TargetNamed<L, Name>, FieldsOfKayan<K>>;
392
+ };
393
+ } & (TargetNamed<L, StoreNameOf<K, L>> extends {
394
+ tables: unknown;
395
+ } ? K extends {
396
+ name: infer Name extends string;
397
+ } ? {
398
+ [Named in StoreNameOf<K, L>]: {
399
+ table: BuiltTables<List, StoreNameOf<K, L>, DefaultStoreOf<L>, L['kinds']>[Name];
400
+ };
401
+ } : {} : {});
402
+ type Built<K, List extends Registry, L extends LanguageValues, Operations> = {
403
+ name: K extends {
404
+ name: infer Name;
405
+ } ? Name : string;
406
+ fields: FieldsOfKayan<K>;
407
+ /** The same object as `targets.service.operations`, which the service capability always publishes. */
408
+ operations: Operations;
409
+ targets: KayanOutputs<K, List, L, Operations>;
410
+ };
411
+ type GlobalOperations<K extends Registry[number], List extends Registry, L extends LanguageValues, Actor> = {
412
+ findOne(...args: CallArgs<L, Actor, {
413
+ depth?: number;
414
+ }>): Promise<Row<K['fields'], L, List> | null>;
415
+ update(...args: CallArgs<L, Actor, UpdateInput<K['fields'], L, List>>): Promise<Row<K['fields'], L, List>>;
416
+ };
417
+ /** What `asas.global` holds: one built global per name, of the shape a kayan has. */
418
+ export type Globals<GlobalList extends Registry, List extends Registry, L extends LanguageValues, Actor = unknown> = {
419
+ [K in GlobalList[number] as K['name']]: Built<K, List, L, GlobalOperations<K, List, L, Actor>>;
420
+ };
421
+ type KayanOperations<K extends Registry[number], List extends Registry, L extends LanguageValues, Actor> = {
422
+ [Name in keyof OwnOperations<K>]: (...args: CallArgs<L, Actor, InputOf<K, Name, K['fields'], L, List>, IsReadOperation<OwnOperation<K, Name>>>) => OperationResult<OwnOperation<K, Name>, K['fields'], L, List>;
423
+ };
424
+ /** What `asas.kayan` holds. A relationship may point at a global, so `List` holds both. */
425
+ export type Writes<KayanList extends Registry, List extends Registry, L extends LanguageValues, Actor = unknown> = {
426
+ [K in KayanList[number] as K['name']]: Built<K, List, L, KayanOperations<K, List, L, Actor>>;
427
+ };
428
+ type Sent<Method> = Method extends (...args: infer Args) => infer Answer ? (input: Exclude<Args[0], undefined>) => Answer : never;
429
+ /** Every operation of one bound kayan, as procedures. */
430
+ type Procedural<Bound> = {
431
+ [Name in keyof Bound]: Sent<Bound[Name]>;
432
+ };
433
+ /** The static view of the operation table, keyed by kayan then operation: what each published operation takes and answers. */
434
+ export type Procedures<KayanList extends Registry, GlobalList extends Registry, List extends Registry, L extends LanguageValues> = {
435
+ [K in KayanList[number] as K['name']]: Procedural<BoundOne<K, K['fields'], L, List, 'write'>>;
436
+ } & {
437
+ [K in GlobalList[number] as K['name']]: {
438
+ findOne: (input: {
439
+ depth?: number;
440
+ }) => Promise<Row<K['fields'], L, List> | null>;
441
+ update: (input: UpdateInput<K['fields'], L, List>) => Promise<Row<K['fields'], L, List>>;
442
+ };
443
+ };
444
+ export {};