@drhomet/mithaq 0.0.0-stage → 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.
Files changed (152) hide show
  1. package/LICENSE +22 -0
  2. package/LICENSES/openstatus-time-picker.txt +21 -0
  3. package/LICENSES/payload.txt +22 -0
  4. package/LICENSES/ponytail.txt +21 -0
  5. package/README.md +160 -2
  6. package/dist/asas/actor.d.ts +96 -0
  7. package/dist/asas/actor.js +114 -0
  8. package/dist/asas/build.d.ts +239 -0
  9. package/dist/asas/build.js +834 -0
  10. package/dist/asas/cli/mithaq.d.ts +2 -0
  11. package/dist/asas/cli/mithaq.js +177 -0
  12. package/dist/asas/cli/upgrade.d.ts +33 -0
  13. package/dist/asas/cli/upgrade.js +256 -0
  14. package/dist/asas/http/fetch.d.ts +41 -0
  15. package/dist/asas/http/fetch.js +178 -0
  16. package/dist/asas/http/orpc.d.ts +45 -0
  17. package/dist/asas/http/orpc.js +153 -0
  18. package/dist/asas/runner/bulk.d.ts +20 -0
  19. package/dist/asas/runner/bulk.js +196 -0
  20. package/dist/asas/runner/errors.d.ts +63 -0
  21. package/dist/asas/runner/errors.js +75 -0
  22. package/dist/asas/runner/read.d.ts +72 -0
  23. package/dist/asas/runner/read.js +601 -0
  24. package/dist/asas/runner/runtime.d.ts +21 -0
  25. package/dist/asas/runner/runtime.js +8 -0
  26. package/dist/asas/runner/steps.d.ts +418 -0
  27. package/dist/asas/runner/steps.js +277 -0
  28. package/dist/asas/runner/store.d.ts +4 -0
  29. package/dist/asas/runner/store.js +21 -0
  30. package/dist/asas/runner/tenant.d.ts +54 -0
  31. package/dist/asas/runner/tenant.js +275 -0
  32. package/dist/asas/runner/write.d.ts +606 -0
  33. package/dist/asas/runner/write.js +1019 -0
  34. package/dist/auth/better-auth/access.d.ts +29 -0
  35. package/dist/auth/better-auth/access.js +103 -0
  36. package/dist/auth/better-auth/generate.d.ts +31 -0
  37. package/dist/auth/better-auth/generate.js +328 -0
  38. package/dist/auth/better-auth/index.d.ts +94 -0
  39. package/dist/auth/better-auth/index.js +81 -0
  40. package/dist/auth/better-auth/tenant.d.ts +26 -0
  41. package/dist/auth/better-auth/tenant.js +34 -0
  42. package/dist/auth/local/index.d.ts +285 -0
  43. package/dist/auth/local/index.js +738 -0
  44. package/dist/base/decimal.d.ts +9 -0
  45. package/dist/base/decimal.js +16 -0
  46. package/dist/base/fields.d.ts +124 -0
  47. package/dist/base/fields.js +52 -0
  48. package/dist/base/index.d.ts +47 -0
  49. package/dist/base/index.js +5 -0
  50. package/dist/base/json-schema.d.ts +7 -0
  51. package/dist/base/json-schema.js +35 -0
  52. package/dist/base/kinds.d.ts +75 -0
  53. package/dist/base/kinds.js +123 -0
  54. package/dist/base/rules.d.ts +73 -0
  55. package/dist/base/rules.js +81 -0
  56. package/dist/drizzle/index.d.ts +308 -0
  57. package/dist/drizzle/index.js +951 -0
  58. package/dist/drizzle/kinds.d.ts +28 -0
  59. package/dist/drizzle/kinds.js +43 -0
  60. package/dist/drizzle/migrate.d.ts +159 -0
  61. package/dist/drizzle/migrate.js +1328 -0
  62. package/dist/drizzle/proxy/index.d.ts +1 -0
  63. package/dist/drizzle/proxy/index.js +1 -0
  64. package/dist/drizzle/proxy/node-postgres.d.ts +1 -0
  65. package/dist/drizzle/proxy/node-postgres.js +1 -0
  66. package/dist/drizzle/proxy/pg-core.d.ts +1 -0
  67. package/dist/drizzle/proxy/pg-core.js +1 -0
  68. package/dist/drizzle/rules.d.ts +336 -0
  69. package/dist/drizzle/rules.js +44 -0
  70. package/dist/index.d.ts +35 -0
  71. package/dist/index.js +26 -0
  72. package/dist/mithaq/define.d.ts +335 -0
  73. package/dist/mithaq/define.js +57 -0
  74. package/dist/mithaq/generate-messages.d.ts +38 -0
  75. package/dist/mithaq/generate-messages.js +235 -0
  76. package/dist/mithaq/language.d.ts +374 -0
  77. package/dist/mithaq/language.js +76 -0
  78. package/dist/mithaq/lock.d.ts +71 -0
  79. package/dist/mithaq/lock.js +329 -0
  80. package/dist/mithaq/message-file.d.ts +13 -0
  81. package/dist/mithaq/message-file.js +29 -0
  82. package/dist/mithaq/messages.d.ts +55 -0
  83. package/dist/mithaq/messages.js +111 -0
  84. package/dist/mithaq/refusal.d.ts +6 -0
  85. package/dist/mithaq/refusal.js +6 -0
  86. package/dist/mithaq/resolve.d.ts +10 -0
  87. package/dist/mithaq/resolve.js +1014 -0
  88. package/dist/mithaq/rows.d.ts +87 -0
  89. package/dist/mithaq/rows.js +174 -0
  90. package/dist/mithaq/rukn.d.ts +72 -0
  91. package/dist/mithaq/rukn.js +15 -0
  92. package/dist/mithaq/standard-schema.d.ts +38 -0
  93. package/dist/mithaq/standard-schema.js +2 -0
  94. package/dist/mithaq/types.d.ts +386 -0
  95. package/dist/mithaq/types.js +15 -0
  96. package/dist/mithaq/user.d.ts +19 -0
  97. package/dist/mithaq/user.js +16 -0
  98. package/dist/mithaq/where.d.ts +32 -0
  99. package/dist/mithaq/where.js +87 -0
  100. package/dist/rbac/index.d.ts +105 -0
  101. package/dist/rbac/index.js +182 -0
  102. package/dist/rbac/steps.d.ts +22 -0
  103. package/dist/rbac/steps.js +161 -0
  104. package/dist/rich-text/index.d.ts +28 -0
  105. package/dist/rich-text/index.js +59 -0
  106. package/dist/rich-text/rich-text.d.ts +106 -0
  107. package/dist/rich-text/rich-text.js +249 -0
  108. package/dist/rich-text/value.d.ts +55 -0
  109. package/dist/rich-text/value.js +126 -0
  110. package/dist/screen/client.d.ts +156 -0
  111. package/dist/screen/client.js +71 -0
  112. package/dist/screen/generate.d.ts +14 -0
  113. package/dist/screen/generate.js +268 -0
  114. package/dist/screen/index.d.ts +496 -0
  115. package/dist/screen/index.js +663 -0
  116. package/dist/screen/react.d.ts +97 -0
  117. package/dist/screen/react.js +58 -0
  118. package/dist/screen/studio.d.ts +24 -0
  119. package/dist/screen/studio.js +68 -0
  120. package/dist/service/index.d.ts +63 -0
  121. package/dist/service/index.js +15 -0
  122. package/dist/storage/allowed-type.d.ts +5 -0
  123. package/dist/storage/allowed-type.js +7 -0
  124. package/dist/storage/index.d.ts +42 -0
  125. package/dist/storage/index.js +43 -0
  126. package/dist/storage/storage.d.ts +386 -0
  127. package/dist/storage/storage.js +412 -0
  128. package/dist/targets.d.ts +14 -0
  129. package/dist/targets.js +16 -0
  130. package/dist/versions/index.d.ts +37 -0
  131. package/dist/versions/index.js +8 -0
  132. package/dist/versions/versions.d.ts +104 -0
  133. package/dist/versions/versions.js +160 -0
  134. package/dist/vite.d.ts +7 -0
  135. package/dist/vite.js +81 -0
  136. package/dist/zod/index.d.ts +193 -0
  137. package/dist/zod/index.js +122 -0
  138. package/dist/zod/kinds.d.ts +36 -0
  139. package/dist/zod/kinds.js +58 -0
  140. package/dist/zod/rules.d.ts +117 -0
  141. package/dist/zod/rules.js +67 -0
  142. package/docs/packages/mithaq/README.md +962 -0
  143. package/docs/packages/mithaq/src/asas/cli/README.md +252 -0
  144. package/docs/packages/mithaq/src/asas/runner/README.md +472 -0
  145. package/docs/packages/mithaq/src/drizzle/README.md +39 -0
  146. package/docs/packages/mithaq-admin/README.md +312 -0
  147. package/docs/templates/asas/README.md +1056 -0
  148. package/package.json +92 -4
  149. package/skills/add-field/SKILL.md +27 -0
  150. package/skills/add-kayan/SKILL.md +26 -0
  151. package/skills/eject-admin-piece/SKILL.md +28 -0
  152. package/skills/upgrade-mithaq/SKILL.md +35 -0
@@ -0,0 +1,496 @@
1
+ import { builtInScreenKinds, registryCells, registryControls } from './client.ts';
2
+ import { type Localized, type LocalesOf, type ResolvedKayan, type RuntimeField } from '../mithaq/types.ts';
3
+ import { defaultKinds } from '../base/kinds.ts';
4
+ import { type Where } from '../mithaq/where.ts';
5
+ /** What one kind is drawn by on a screen: its form control and its list cell, each a name or a `ui()` reference. */
6
+ export type ScreenKind = {
7
+ readonly cell: string | Ui;
8
+ readonly control: string | Ui;
9
+ };
10
+ /** What the shipped registry draws each shipped kind with. A screen's `controls` spreads it and adds or rewrites rows. */
11
+ export declare const screenKinds: {
12
+ readonly text: {
13
+ cell: "text";
14
+ control: "text";
15
+ };
16
+ readonly email: {
17
+ cell: "email";
18
+ control: "email";
19
+ };
20
+ readonly number: {
21
+ cell: "number";
22
+ control: "number";
23
+ };
24
+ readonly integer: {
25
+ cell: "integer";
26
+ control: "integer";
27
+ };
28
+ readonly decimal: {
29
+ cell: "decimal";
30
+ control: "decimal";
31
+ };
32
+ readonly checkbox: {
33
+ cell: "checkbox";
34
+ control: "checkbox";
35
+ };
36
+ readonly datetime: {
37
+ cell: "datetime";
38
+ control: "datetime";
39
+ };
40
+ readonly date: {
41
+ cell: "date";
42
+ control: "date";
43
+ };
44
+ readonly textArray: {
45
+ cell: "textArray";
46
+ control: "textArray";
47
+ };
48
+ readonly uuid: {
49
+ cell: "uuid";
50
+ control: "uuid";
51
+ };
52
+ readonly relationship: {
53
+ cell: "relationship";
54
+ control: "relationship";
55
+ };
56
+ readonly json: {
57
+ cell: "json";
58
+ control: "json";
59
+ };
60
+ readonly join: {
61
+ cell: "join";
62
+ control: "join";
63
+ };
64
+ };
65
+ type OwnScreenNames<Kinds> = {
66
+ [Name in keyof Kinds]: Kinds[Name] extends {
67
+ targets: {
68
+ screen: {
69
+ control: infer Control;
70
+ cell: infer Cell;
71
+ };
72
+ };
73
+ } ? Extract<Control, (typeof registryControls)[number]> | Extract<Cell, (typeof registryCells)[number]> : never;
74
+ }[keyof Kinds];
75
+ declare const uiBrand: unique symbol;
76
+ /** One export of one file, as a URL whose hash is the export's name: `ui('dashboard.tsx#Dashboard')`. */
77
+ export type Ui<Path extends string = string> = URL & {
78
+ readonly [uiBrand]: Path;
79
+ };
80
+ /**
81
+ * The folder a project's screen files sit in, handed back as `ui`:
82
+ * `const ui = folderOf(new URL('./ui-dashboard/', import.meta.url))`. A missing file or export fails the build.
83
+ */
84
+ export declare const folderOf: (folder: URL) => <const Path extends `${string}#${string}`>(path: Path) => Ui<Path>;
85
+ /** A component named where a screen draws one: a name the screen registered, a bare built-in the registry ships, or a `ui()` reference. */
86
+ export type ScreenRef<Registered extends string = string> = Registered | Ui;
87
+ /** A page of the screen's own, which belongs to no kayan: one component drawing the whole page. */
88
+ export type ScreenOwnPage<Locale extends string = string, Ref extends string | Ui = string | Ui> = {
89
+ readonly path: string;
90
+ readonly component: Ref;
91
+ /** A nav entry for this page, under this label. */
92
+ readonly nav?: {
93
+ readonly label: Localized<Locale>;
94
+ };
95
+ /** The catalog key an actor needs for the nav to list this page. */
96
+ readonly permission?: string;
97
+ };
98
+ /** The screen as a target, `capability: 'screen'`. */
99
+ export type ScreenTarget<Controls extends Record<string, ScreenKind> = Record<string, ScreenKind>, Layouts extends Record<string, Ui> = Record<string, Ui>, Components extends Record<string, Ui> = Record<string, Ui>> = {
100
+ readonly capability: 'screen';
101
+ readonly type: 'screen';
102
+ /** Where the screen mounts. */
103
+ readonly path: string;
104
+ /** Every kayan the screen draws, by name. A kayan it does not list writes no `targets.<screen>`. */
105
+ readonly kayan: readonly string[];
106
+ /** One row per kind of the language: what draws its value in a form and in a list. */
107
+ readonly controls: Controls;
108
+ /** Outermost first, each handed `{ children }`. */
109
+ readonly providers: readonly ScreenRef<keyof Components & string>[];
110
+ /** The pages that belong to no kayan, each drawn whole by one component. One of them is at `/`. */
111
+ readonly pages: Readonly<Record<string, ScreenOwnPage<string, ScreenRef<keyof Components & string>>>>;
112
+ /** The shells and layouts a page tree names, by a short name. */
113
+ readonly layouts: Layouts;
114
+ /** The components a page names, by a short name. */
115
+ readonly components: Components;
116
+ };
117
+ export declare const screenTarget: <const Controls extends Record<string, ScreenKind>, const Layouts extends Record<string, Ui>, const Components extends Record<string, Ui>>(target: Omit<ScreenTarget<Controls, Layouts, Components>, 'capability' | 'type'>) => ScreenTarget<Controls, Layouts, Components>;
118
+ /** What `targets.<screen>` on a field may say: how it is drawn, never what it holds. */
119
+ export type ScreenField<Ref extends string | Ui = string | Ui> = {
120
+ readonly component?: Ref;
121
+ readonly cell?: Ref;
122
+ readonly width?: string;
123
+ readonly filter?: true;
124
+ readonly searchable?: true;
125
+ readonly sortable?: false;
126
+ };
127
+ /** When a node is drawn: a `Where` over the form's values, the loaded row under `record.` and the access report under `$user.`. */
128
+ export type When = {
129
+ readonly when?: Where;
130
+ };
131
+ /** A field on one page: its name, or its name with what this page alone draws it with. */
132
+ export type ScreenLeaf<Locale extends string = string, Ref extends string | Ui = string | Ui, FieldName extends string = string> = FieldName | ({
133
+ readonly field: FieldName;
134
+ readonly component?: Ref;
135
+ readonly cell?: Ref;
136
+ readonly placeholder?: Localized<Locale>;
137
+ readonly description?: Localized<Locale>;
138
+ readonly readOnly?: boolean;
139
+ readonly width?: string;
140
+ } & When);
141
+ type ScreenGroup<Locale extends string, Ref extends string | Ui, FieldName extends string> = {
142
+ readonly label: Localized<Locale>;
143
+ readonly description?: Localized<Locale>;
144
+ readonly fields: readonly ScreenNode<Locale, Ref, FieldName>[];
145
+ };
146
+ /** The regions of a shell or a layout, each a list of nodes, by the names its file exports. */
147
+ export interface ScreenRegions<Locale extends string = string, Ref extends string | Ui = string | Ui, FieldName extends string = string> {
148
+ readonly [region: string]: readonly ScreenNode<Locale, Ref, FieldName>[] | Ref | Where | undefined;
149
+ }
150
+ /** A page's tree: a shell by name at its root, whose regions hold nodes. */
151
+ export interface ScreenFrame<Locale extends string = string, Ref extends string | Ui = string | Ui, FieldName extends string = string> extends ScreenRegions<Locale, Ref, FieldName> {
152
+ readonly shell: Ref;
153
+ }
154
+ /** A layout nested in a region, with regions of its own. */
155
+ export interface ScreenLayout<Locale extends string = string, Ref extends string | Ui = string | Ui, FieldName extends string = string> extends ScreenRegions<Locale, Ref, FieldName> {
156
+ readonly layout: Ref;
157
+ readonly when?: Where;
158
+ }
159
+ /**
160
+ * One node of a page's region. A layout's regions are keys of its own, so a
161
+ * walk rules out `layout` before it asks for any other key.
162
+ */
163
+ export type ScreenNode<Locale extends string = string, Ref extends string | Ui = string | Ui, FieldName extends string = string> = ScreenLeaf<Locale, Ref, FieldName> | ({
164
+ readonly form: readonly ScreenNode<Locale, Ref, FieldName>[];
165
+ readonly component?: Ref;
166
+ } & When) | ({
167
+ readonly list: ScreenList<Locale, Ref, FieldName> | (ScreenList<Locale, Ref, string> & {
168
+ /** Another kayan of the screen, whose rows this list draws, each column one of its fields. */
169
+ readonly of: string;
170
+ /** `of`'s relationship holding this page's row, which scopes the list to the rows pointing here. */
171
+ readonly where: string;
172
+ });
173
+ readonly component?: Ref;
174
+ } & When) | ({
175
+ readonly component: Ref;
176
+ } & When) | ScreenLayout<Locale, Ref, FieldName> | ScreenButton<Locale, Ref> | ({
177
+ readonly title: Readonly<Record<string, never>>;
178
+ } & When) | ({
179
+ readonly nav: Readonly<Record<string, never>>;
180
+ } & When)
181
+ /** The form's controls: where the row stands, the last save and the save buttons. */
182
+ | ({
183
+ readonly controls: Readonly<Record<string, never>>;
184
+ } & When) | ({
185
+ readonly row: readonly ScreenNode<Locale, Ref, FieldName>[];
186
+ readonly resizable?: true;
187
+ } & When) | ({
188
+ readonly separator: true;
189
+ } & When) | ({
190
+ readonly section: string;
191
+ readonly collapsed?: boolean;
192
+ readonly width?: number;
193
+ /** A CSS height the section's body scrolls within, shadcn's `scroll-area`. */
194
+ readonly scroll?: string;
195
+ } & ScreenGroup<Locale, Ref, FieldName> & When) | ({
196
+ readonly tabs: readonly ({
197
+ readonly tab: string;
198
+ } & ScreenGroup<Locale, Ref, FieldName>)[];
199
+ } & When) | ({
200
+ readonly accordion: readonly ({
201
+ readonly item: string;
202
+ } & ScreenGroup<Locale, Ref, FieldName>)[];
203
+ } & When);
204
+ /** A list node's own keys: its columns, what it filters, searches and opens with, and its buttons. */
205
+ export type ScreenList<Locale extends string = string, Ref extends string | Ui = string | Ui, FieldName extends string = string> = {
206
+ readonly columns: readonly ScreenLeaf<Locale, Ref, FieldName>[];
207
+ readonly filters?: readonly FieldName[];
208
+ /** The fields a search box runs over: a field of this kayan, or one hop to a text field of a kayan it points at, `userId.email`. */
209
+ readonly search?: readonly (FieldName | `${FieldName}.${string}`)[];
210
+ readonly empty?: Ref;
211
+ /** What each row's menu offers after the list's own items: a component handed the row (`MenuProps`). */
212
+ readonly menu?: Ref;
213
+ /** Buttons above the table, which run over no row. */
214
+ readonly toolbar?: readonly ScreenButton<Locale, Ref>[];
215
+ /** Buttons over the ticked rows, each an `updateMany` or a `deleteMany`. */
216
+ readonly bulk?: readonly ScreenButton<Locale, Ref>[];
217
+ /** Buttons on each row, each an `update` or a `remove` over that row, drawn where its `when` holds. */
218
+ readonly row?: readonly ScreenButton<Locale, Ref>[];
219
+ /** The order a list opens in, which the URL's own `sort` overrides. */
220
+ readonly sort?: FieldName | `-${FieldName}`;
221
+ /** The page size a list opens with, which the URL's own `limit` overrides. */
222
+ readonly limit?: number;
223
+ /** The list's tabs, each a `where` it holds every page to; the first is the one it opens on. */
224
+ readonly tabs?: readonly {
225
+ readonly tab: string;
226
+ readonly label: Localized<Locale>;
227
+ readonly where?: Where;
228
+ }[];
229
+ };
230
+ /** A button that runs one of the kayan's operations, wherever it sits: `button` names the operation. */
231
+ export type ScreenButton<Locale extends string = string, Ref extends string | Ui = string | Ui> = {
232
+ readonly button: string;
233
+ readonly label: Localized<Locale>;
234
+ readonly fields?: readonly string[];
235
+ readonly reload?: boolean;
236
+ readonly component?: Ref;
237
+ /** What the button asks before it runs. */
238
+ readonly confirm?: {
239
+ readonly title: Localized<Locale>;
240
+ readonly body: Localized<Locale>;
241
+ };
242
+ readonly when?: Where;
243
+ };
244
+ /** One page: `list`, `create` and `edit` by name, any other name a custom page. Declared as one tree, or drawn whole by one component. */
245
+ export type ScreenPage<Locale extends string = string, Ref extends string | Ui = string | Ui, FieldName extends string = string> = {
246
+ readonly path: string;
247
+ readonly page: ScreenFrame<Locale, Ref, FieldName>;
248
+ /** `create` and `edit` only: the record opens over the list, in shadcn's dialog or sheet, or a full-page drawer as Payload's document drawer. */
249
+ readonly mode?: 'dialog' | 'drawer' | 'sheet';
250
+ readonly component?: never;
251
+ } | {
252
+ readonly path: string;
253
+ readonly component: Ref;
254
+ readonly page?: never;
255
+ readonly mode?: never;
256
+ };
257
+ /** What `targets.<screen>` on a kayan says, complete for that screen. */
258
+ export type ScreenKayan<Locale extends string = string, Ref extends string | Ui = string | Ui, FieldName extends string = string> = {
259
+ readonly useAsTitle?: FieldName;
260
+ readonly description?: Localized<Locale>;
261
+ /** The rows this screen lists of the kayan, ANDed with whatever a list asks. A list filter, not access: a row it leaves out is still read by its id. */
262
+ readonly baseFilter?: Where;
263
+ readonly pages?: Readonly<Record<string, ScreenPage<Locale, Ref, FieldName>>>;
264
+ };
265
+ /** The screen keys of a build's targets. */
266
+ export type ScreenKeys<Targets> = {
267
+ [Name in keyof Targets]: Targets[Name] extends {
268
+ capability: 'screen';
269
+ } ? Name : never;
270
+ }[keyof Targets] & string;
271
+ /** Every reference a declaration may write on one screen of a build. */
272
+ export type RefOf<Target, Kinds = {}> = Target extends {
273
+ layouts: infer Layouts;
274
+ components: infer Components;
275
+ } ? ScreenRef<(keyof Layouts | keyof Components | keyof typeof builtInScreenKinds | keyof typeof defaultKinds | OwnScreenNames<Kinds>) & string> : string | Ui;
276
+ type FieldData = {
277
+ name: string;
278
+ kind: string;
279
+ label?: Localized;
280
+ rules: Readonly<Record<string, unknown>>;
281
+ /** Relationship and join only: the name of the kayan this field points at. */
282
+ relationTo?: string;
283
+ /** Join only: the child's relationship that holds this row's id. */
284
+ on?: string;
285
+ /** Relationship only: whether this field holds a set of rows rather than one. */
286
+ hasMany?: true;
287
+ /** Relationship only: whether its picker reads `for` this field, so the server holds the rows to its `filterOptions`. */
288
+ filterOptions?: true;
289
+ };
290
+ /** One field as a screen draws it: the data a browser needs, and this screen's drawing facts decided. */
291
+ export type ClientField = FieldData & {
292
+ options?: readonly {
293
+ value: string;
294
+ label: Localized;
295
+ }[];
296
+ placeholder?: Localized;
297
+ prefix?: Localized;
298
+ suffix?: Localized;
299
+ description?: Localized;
300
+ /** The control the form draws it with where a page names nothing else, resolved. */
301
+ component: string;
302
+ /** The cell the list draws it with where a page names nothing else, resolved. */
303
+ cell: string;
304
+ } & Omit<ScreenField, 'component' | 'cell'>;
305
+ /** A leaf as `screen.json` prints it: the field, and what this page decided it is drawn with. */
306
+ export type LeafClient = {
307
+ field: string;
308
+ component?: string;
309
+ cell?: string;
310
+ /** Which level decided what this leaf draws: the `leaf`, the `field`'s own `targets.<screen>`, or the screen's `controls` `table`. */
311
+ decided?: 'field' | 'leaf' | 'table';
312
+ placeholder?: Localized;
313
+ description?: Localized;
314
+ readOnly?: boolean;
315
+ width?: string;
316
+ when?: Where;
317
+ };
318
+ type GroupClient = {
319
+ label: Localized;
320
+ description?: Localized;
321
+ fields: NodeClient[];
322
+ };
323
+ /** A shell's or a layout's regions as `screen.json` prints them. */
324
+ export type RegionsClient = {
325
+ [region: string]: NodeClient[] | string | Where | undefined;
326
+ };
327
+ /** A button node as `screen.json` prints it. */
328
+ export type ButtonClient = {
329
+ button: string;
330
+ label: Localized;
331
+ fields?: string[];
332
+ reload?: boolean;
333
+ component?: string;
334
+ confirm?: {
335
+ title: Localized;
336
+ body: Localized;
337
+ };
338
+ when?: Where;
339
+ };
340
+ /** A list node's own keys as `screen.json` prints them. */
341
+ export type ListClient = {
342
+ columns: LeafClient[];
343
+ filters?: string[];
344
+ search?: string[];
345
+ empty?: string;
346
+ menu?: string;
347
+ toolbar?: ButtonClient[];
348
+ bulk?: ButtonClient[];
349
+ row?: ButtonClient[];
350
+ sort?: string;
351
+ limit?: number;
352
+ tabs?: {
353
+ tab: string;
354
+ label: Localized;
355
+ where?: Where;
356
+ }[];
357
+ /** A list of another kayan: its name, and its relationship holding this page's row. */
358
+ of?: string;
359
+ where?: string;
360
+ };
361
+ /** A node as `screen.json` prints it, every reference resolved, and its `when` where it has one. */
362
+ export type NodeClient = LeafClient | ButtonClient | (({
363
+ form: NodeClient[];
364
+ component?: string;
365
+ } | {
366
+ list: ListClient;
367
+ component?: string;
368
+ } | {
369
+ component: string;
370
+ } | ({
371
+ layout: string;
372
+ } & RegionsClient) | {
373
+ title: Record<string, never>;
374
+ } | {
375
+ nav: Record<string, never>;
376
+ } | {
377
+ controls: Record<string, never>;
378
+ } | {
379
+ row: NodeClient[];
380
+ resizable?: true;
381
+ } | {
382
+ separator: true;
383
+ } | ({
384
+ section: string;
385
+ collapsed?: boolean;
386
+ width?: number;
387
+ scroll?: string;
388
+ } & GroupClient) | {
389
+ tabs: ({
390
+ tab: string;
391
+ } & GroupClient)[];
392
+ } | {
393
+ accordion: ({
394
+ item: string;
395
+ } & GroupClient)[];
396
+ }) & {
397
+ when?: Where;
398
+ });
399
+ /** A page's tree as `screen.json` prints it: the shell at the root, and its regions. */
400
+ export type FrameClient = {
401
+ shell: string;
402
+ } & RegionsClient;
403
+ /** A kayan's page: its tree, or the one component drawing it whole. */
404
+ export type PageClient = {
405
+ path: string;
406
+ page: FrameClient;
407
+ mode?: 'dialog' | 'drawer' | 'sheet';
408
+ } | {
409
+ path: string;
410
+ component: string;
411
+ };
412
+ /** A page of the screen's own, drawn whole by one component. */
413
+ export type ScreenPageClient = {
414
+ path: string;
415
+ component: string;
416
+ nav?: {
417
+ label: Localized;
418
+ };
419
+ permission?: string;
420
+ };
421
+ /** One entry of the screen's nav: a kayan's page or a page of the screen's own, and the catalog key an actor needs to see it. */
422
+ export type NavEntry = {
423
+ path: string;
424
+ page: string;
425
+ kayan?: string;
426
+ label?: Localized;
427
+ permission?: string;
428
+ };
429
+ export type ClientKayan<Pages extends string = string> = {
430
+ name: string;
431
+ single: boolean;
432
+ fields: ClientField[];
433
+ operations: {
434
+ name: string;
435
+ effect: string;
436
+ fields?: ClientField[];
437
+ updatesMany?: true;
438
+ }[];
439
+ useAsTitle?: string;
440
+ description?: Localized;
441
+ /** The rows every list of this kayan on the screen is held to (`ScreenKayan` `baseFilter`). */
442
+ baseFilter?: Where;
443
+ /** Whether the kayan keeps drafts, and its autosave interval where it does. */
444
+ drafts?: {
445
+ autosave?: {
446
+ interval: number;
447
+ };
448
+ };
449
+ /** The types a kayan holding files takes and its largest file in bytes, so the upload control refuses a file before sending it. */
450
+ storage?: {
451
+ mimeTypes: readonly string[];
452
+ fileSize: number;
453
+ };
454
+ pages: Record<Pages, PageClient>;
455
+ };
456
+ /** What `asas.targets.<screen>.client` holds and `screen.json` prints, with every reference resolved. */
457
+ export type ScreenClient<Pages extends Record<string, string> = Record<string, string>> = {
458
+ path: string;
459
+ providers: string[];
460
+ pages: Record<string, ScreenPageClient>;
461
+ nav: NavEntry[];
462
+ layouts: Record<string, string>;
463
+ components: Record<string, string>;
464
+ controls: Record<string, {
465
+ control: string;
466
+ cell: string;
467
+ }>;
468
+ kayan: {
469
+ [Name in keyof Pages]: ClientKayan<Pages[Name]>;
470
+ };
471
+ /** The most rows a served read answers, so a page paging through every row holds to the project's number. */
472
+ maxLimit: number;
473
+ };
474
+ export declare const clientFieldOf: (name: string, field: RuntimeField & {
475
+ target?: {
476
+ name: string;
477
+ };
478
+ }) => FieldData;
479
+ /** The folder holding the nearest `package.json` above a file; references print relative to it, so `screen.json` names no absolute path. */
480
+ export declare const packageOf: (file: URL) => URL | undefined;
481
+ /** Every screen of a build, checked and projected in one walk. Each refusal names the screen, kayan, page and node. */
482
+ export declare const screensOf: (language: {
483
+ kinds: Record<string, {
484
+ targets?: Readonly<Record<string, unknown>>;
485
+ }>;
486
+ locales?: readonly string[];
487
+ targets: Record<string, unknown>;
488
+ }, resolved: readonly ResolvedKayan[]) => Record<string, ScreenClient>;
489
+ declare module '../mithaq/rukn.ts' {
490
+ interface KayanConfigs<L, F, T> {
491
+ screen: ScreenKayan<LocalesOf<L>, RefOf<T, L extends {
492
+ kinds: infer Kinds;
493
+ } ? Kinds : {}>, keyof F & string>;
494
+ }
495
+ }
496
+ export {};