@adminiumjs/manifest 0.3.5 → 0.3.7

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 (66) hide show
  1. package/dist/capacity.d.ts +786 -0
  2. package/dist/capacity.d.ts.map +1 -0
  3. package/dist/capacity.js +717 -0
  4. package/dist/capacity.js.map +1 -0
  5. package/dist/documents.d.ts +91 -5
  6. package/dist/documents.d.ts.map +1 -1
  7. package/dist/documents.js +129 -32
  8. package/dist/documents.js.map +1 -1
  9. package/dist/formula.d.ts +114 -2
  10. package/dist/formula.d.ts.map +1 -1
  11. package/dist/formula.js +291 -5
  12. package/dist/formula.js.map +1 -1
  13. package/dist/index.d.ts +12 -6
  14. package/dist/index.d.ts.map +1 -1
  15. package/dist/index.js +12 -6
  16. package/dist/index.js.map +1 -1
  17. package/dist/marketplace-wire.d.ts +230 -0
  18. package/dist/marketplace-wire.d.ts.map +1 -0
  19. package/dist/marketplace-wire.js +138 -0
  20. package/dist/marketplace-wire.js.map +1 -0
  21. package/dist/outbox.d.ts +242 -27
  22. package/dist/outbox.d.ts.map +1 -1
  23. package/dist/outbox.js +553 -27
  24. package/dist/outbox.js.map +1 -1
  25. package/dist/plan-context.d.ts +28 -3
  26. package/dist/plan-context.d.ts.map +1 -1
  27. package/dist/plan-context.js +291 -14
  28. package/dist/plan-context.js.map +1 -1
  29. package/dist/plan-model.d.ts +58 -3
  30. package/dist/plan-model.d.ts.map +1 -1
  31. package/dist/public-access.d.ts +637 -0
  32. package/dist/public-access.d.ts.map +1 -1
  33. package/dist/public-access.js +1593 -12
  34. package/dist/public-access.js.map +1 -1
  35. package/dist/refs.d.ts +86 -0
  36. package/dist/refs.d.ts.map +1 -1
  37. package/dist/refs.js +186 -0
  38. package/dist/refs.js.map +1 -1
  39. package/dist/roles.d.ts +10 -2
  40. package/dist/roles.d.ts.map +1 -1
  41. package/dist/roles.js +27 -5
  42. package/dist/roles.js.map +1 -1
  43. package/dist/sample.d.ts +218 -2
  44. package/dist/sample.d.ts.map +1 -1
  45. package/dist/sample.js +145 -7
  46. package/dist/sample.js.map +1 -1
  47. package/dist/schema.d.ts +2860 -360
  48. package/dist/schema.d.ts.map +1 -1
  49. package/dist/schema.js +1002 -54
  50. package/dist/schema.js.map +1 -1
  51. package/dist/shapes.d.ts +5 -1
  52. package/dist/shapes.d.ts.map +1 -1
  53. package/dist/shapes.js +13 -3
  54. package/dist/shapes.js.map +1 -1
  55. package/dist/states.d.ts +342 -2
  56. package/dist/states.d.ts.map +1 -1
  57. package/dist/states.js +566 -7
  58. package/dist/states.js.map +1 -1
  59. package/dist/table-shapes.d.ts +47 -0
  60. package/dist/table-shapes.d.ts.map +1 -0
  61. package/dist/table-shapes.js +159 -0
  62. package/dist/table-shapes.js.map +1 -0
  63. package/dist/validate.d.ts.map +1 -1
  64. package/dist/validate.js +80 -2
  65. package/dist/validate.js.map +1 -1
  66. package/package.json +2 -2
package/dist/sample.d.ts CHANGED
@@ -7,6 +7,10 @@
7
7
  *
8
8
  * `{"@ref": "<label>"}` the key of an earlier row with that `@label`
9
9
  * `{"@ago": "PT19M"}` an ISO-8601 duration before now
10
+ * `{"@in": "PT20M", "@grid": 15}` an ISO-8601 duration after now; with
11
+ * `@grid`, rounded up to the next time on that
12
+ * many minutes' grid of the venue's own clock
13
+ * (the first pickup slot at least 20 minutes on)
10
14
  * `{"@day": -1, "@time": "09:30"}` a wall time in the venue's own zone,
11
15
  * days from today
12
16
  * `{"@day": 3}` a date in the venue's own zone
@@ -15,7 +19,15 @@
15
19
  *
16
20
  * A `@day` may add `"@workdays": true`: its days count Monday to Friday, and
17
21
  * day 0 on a weekend is the Monday after — so "today's" busy day is never a
18
- * Saturday.
22
+ * Saturday. Or `"@week": true`: its days count from the bundle's anchor day
23
+ * (`weekAnchor`, a weekday) in the week nearest today, so every date keeps
24
+ * the weekday the sample was written for — a weekend stay stays on a
25
+ * weekend, whatever day the sample is added on.
26
+ *
27
+ * `{"@in": "PT20M", "@slot": "orders"}` the first open time of that
28
+ * table's slot limit at least that far ahead —
29
+ * its hours, closures and pauses, on its grid —
30
+ * on the next day it opens when today has none
19
31
  *
20
32
  * `{"@month": -2, "@dom": 14}` a date in the venue's own zone: that day of
21
33
  * the month so many months from this one; with
@@ -33,7 +45,13 @@
33
45
  * falls against the adding moment — more than half an hour before, within
34
46
  * half an hour, or later — so a sample day's statuses match the clock it is
35
47
  * added at. A set with `"@skip": true` leaves the row out (a payment for a
36
- * visit that has not happened yet).
48
+ * visit that has not happened yet). Or `@byStay` `{from, to, times?, before,
49
+ * during, after}`: by where the adding moment falls against the row's two
50
+ * times — its arrival and its departure (columns of the row, or `@day`s) —
51
+ * before the stay, during it, or after it; a date is read at `times.from` /
52
+ * `times.to` on its day (arriving from 15:00, leaving by 11:00), else at its
53
+ * midnight. So a stay's status (booked, in house, departed) matches the
54
+ * clock it is added at. A row takes one of the two.
37
55
  *
38
56
  * `"@onlyIfEmpty": true` is for a table that holds one row, the app's own
39
57
  * settings: the row is added only when the table has none, and otherwise its
@@ -49,13 +67,19 @@ export declare const sampleValueSchema: z.ZodUnion<readonly [z.ZodUnion<readonly
49
67
  '@ref': z.ZodString;
50
68
  }, z.core.$strict>, z.ZodObject<{
51
69
  '@ago': z.ZodString;
70
+ }, z.core.$strict>, z.ZodObject<{
71
+ '@in': z.ZodString;
72
+ '@grid': z.ZodOptional<z.ZodNumber>;
73
+ '@slot': z.ZodOptional<z.ZodString>;
52
74
  }, z.core.$strict>, z.ZodObject<{
53
75
  '@day': z.ZodNumber;
54
76
  '@time': z.ZodString;
55
77
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
78
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
56
79
  }, z.core.$strict>, z.ZodObject<{
57
80
  '@day': z.ZodNumber;
58
81
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
82
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
59
83
  }, z.core.$strict>, z.ZodObject<{
60
84
  '@month': z.ZodNumber;
61
85
  '@dom': z.ZodNumber;
@@ -69,13 +93,19 @@ export declare const sampleRowSchema: z.ZodRecord<z.ZodString, z.ZodUnion<readon
69
93
  '@ref': z.ZodString;
70
94
  }, z.core.$strict>, z.ZodObject<{
71
95
  '@ago': z.ZodString;
96
+ }, z.core.$strict>, z.ZodObject<{
97
+ '@in': z.ZodString;
98
+ '@grid': z.ZodOptional<z.ZodNumber>;
99
+ '@slot': z.ZodOptional<z.ZodString>;
72
100
  }, z.core.$strict>, z.ZodObject<{
73
101
  '@day': z.ZodNumber;
74
102
  '@time': z.ZodString;
75
103
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
104
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
76
105
  }, z.core.$strict>, z.ZodObject<{
77
106
  '@day': z.ZodNumber;
78
107
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
108
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
79
109
  }, z.core.$strict>, z.ZodObject<{
80
110
  '@month': z.ZodNumber;
81
111
  '@dom': z.ZodNumber;
@@ -91,13 +121,19 @@ export declare const byClockSchema: z.ZodObject<{
91
121
  '@ref': z.ZodString;
92
122
  }, z.core.$strict>, z.ZodObject<{
93
123
  '@ago': z.ZodString;
124
+ }, z.core.$strict>, z.ZodObject<{
125
+ '@in': z.ZodString;
126
+ '@grid': z.ZodOptional<z.ZodNumber>;
127
+ '@slot': z.ZodOptional<z.ZodString>;
94
128
  }, z.core.$strict>, z.ZodObject<{
95
129
  '@day': z.ZodNumber;
96
130
  '@time': z.ZodString;
97
131
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
132
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
98
133
  }, z.core.$strict>, z.ZodObject<{
99
134
  '@day': z.ZodNumber;
100
135
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
136
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
101
137
  }, z.core.$strict>, z.ZodObject<{
102
138
  '@month': z.ZodNumber;
103
139
  '@dom': z.ZodNumber;
@@ -111,13 +147,19 @@ export declare const byClockSchema: z.ZodObject<{
111
147
  '@ref': z.ZodString;
112
148
  }, z.core.$strict>, z.ZodObject<{
113
149
  '@ago': z.ZodString;
150
+ }, z.core.$strict>, z.ZodObject<{
151
+ '@in': z.ZodString;
152
+ '@grid': z.ZodOptional<z.ZodNumber>;
153
+ '@slot': z.ZodOptional<z.ZodString>;
114
154
  }, z.core.$strict>, z.ZodObject<{
115
155
  '@day': z.ZodNumber;
116
156
  '@time': z.ZodString;
117
157
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
158
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
118
159
  }, z.core.$strict>, z.ZodObject<{
119
160
  '@day': z.ZodNumber;
120
161
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
162
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
121
163
  }, z.core.$strict>, z.ZodObject<{
122
164
  '@month': z.ZodNumber;
123
165
  '@dom': z.ZodNumber;
@@ -131,13 +173,19 @@ export declare const byClockSchema: z.ZodObject<{
131
173
  '@ref': z.ZodString;
132
174
  }, z.core.$strict>, z.ZodObject<{
133
175
  '@ago': z.ZodString;
176
+ }, z.core.$strict>, z.ZodObject<{
177
+ '@in': z.ZodString;
178
+ '@grid': z.ZodOptional<z.ZodNumber>;
179
+ '@slot': z.ZodOptional<z.ZodString>;
134
180
  }, z.core.$strict>, z.ZodObject<{
135
181
  '@day': z.ZodNumber;
136
182
  '@time': z.ZodString;
137
183
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
184
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
138
185
  }, z.core.$strict>, z.ZodObject<{
139
186
  '@day': z.ZodNumber;
140
187
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
188
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
141
189
  }, z.core.$strict>, z.ZodObject<{
142
190
  '@month': z.ZodNumber;
143
191
  '@dom': z.ZodNumber;
@@ -151,13 +199,19 @@ export declare const byClockSchema: z.ZodObject<{
151
199
  '@ref': z.ZodString;
152
200
  }, z.core.$strict>, z.ZodObject<{
153
201
  '@ago': z.ZodString;
202
+ }, z.core.$strict>, z.ZodObject<{
203
+ '@in': z.ZodString;
204
+ '@grid': z.ZodOptional<z.ZodNumber>;
205
+ '@slot': z.ZodOptional<z.ZodString>;
154
206
  }, z.core.$strict>, z.ZodObject<{
155
207
  '@day': z.ZodNumber;
156
208
  '@time': z.ZodString;
157
209
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
210
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
158
211
  }, z.core.$strict>, z.ZodObject<{
159
212
  '@day': z.ZodNumber;
160
213
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
214
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
161
215
  }, z.core.$strict>, z.ZodObject<{
162
216
  '@month': z.ZodNumber;
163
217
  '@dom': z.ZodNumber;
@@ -169,11 +223,160 @@ export declare const byClockSchema: z.ZodObject<{
169
223
  }, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
170
224
  }, z.core.$strict>;
171
225
  export type ByClock = z.infer<typeof byClockSchema>;
226
+ /** `@byStay`: a row's columns by where the adding moment falls against its two times — before, during or after its stay. */
227
+ export declare const byStaySchema: z.ZodObject<{
228
+ from: z.ZodUnion<readonly [z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
229
+ '@ref': z.ZodString;
230
+ }, z.core.$strict>, z.ZodObject<{
231
+ '@ago': z.ZodString;
232
+ }, z.core.$strict>, z.ZodObject<{
233
+ '@in': z.ZodString;
234
+ '@grid': z.ZodOptional<z.ZodNumber>;
235
+ '@slot': z.ZodOptional<z.ZodString>;
236
+ }, z.core.$strict>, z.ZodObject<{
237
+ '@day': z.ZodNumber;
238
+ '@time': z.ZodString;
239
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
240
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
241
+ }, z.core.$strict>, z.ZodObject<{
242
+ '@day': z.ZodNumber;
243
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
244
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
245
+ }, z.core.$strict>, z.ZodObject<{
246
+ '@month': z.ZodNumber;
247
+ '@dom': z.ZodNumber;
248
+ '@time': z.ZodOptional<z.ZodString>;
249
+ }, z.core.$strict>, z.ZodObject<{
250
+ '@t': z.ZodRecord<z.ZodString, z.ZodString>;
251
+ }, z.core.$strict>, z.ZodObject<{
252
+ '@asset': z.ZodString;
253
+ }, z.core.$strict>]>]>;
254
+ to: z.ZodUnion<readonly [z.ZodString, z.ZodUnion<readonly [z.ZodObject<{
255
+ '@ref': z.ZodString;
256
+ }, z.core.$strict>, z.ZodObject<{
257
+ '@ago': z.ZodString;
258
+ }, z.core.$strict>, z.ZodObject<{
259
+ '@in': z.ZodString;
260
+ '@grid': z.ZodOptional<z.ZodNumber>;
261
+ '@slot': z.ZodOptional<z.ZodString>;
262
+ }, z.core.$strict>, z.ZodObject<{
263
+ '@day': z.ZodNumber;
264
+ '@time': z.ZodString;
265
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
266
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
267
+ }, z.core.$strict>, z.ZodObject<{
268
+ '@day': z.ZodNumber;
269
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
270
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
271
+ }, z.core.$strict>, z.ZodObject<{
272
+ '@month': z.ZodNumber;
273
+ '@dom': z.ZodNumber;
274
+ '@time': z.ZodOptional<z.ZodString>;
275
+ }, z.core.$strict>, z.ZodObject<{
276
+ '@t': z.ZodRecord<z.ZodString, z.ZodString>;
277
+ }, z.core.$strict>, z.ZodObject<{
278
+ '@asset': z.ZodString;
279
+ }, z.core.$strict>]>]>;
280
+ times: z.ZodOptional<z.ZodObject<{
281
+ from: z.ZodOptional<z.ZodString>;
282
+ to: z.ZodOptional<z.ZodString>;
283
+ }, z.core.$strict>>;
284
+ before: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodUnion<readonly [z.ZodObject<{
285
+ '@ref': z.ZodString;
286
+ }, z.core.$strict>, z.ZodObject<{
287
+ '@ago': z.ZodString;
288
+ }, z.core.$strict>, z.ZodObject<{
289
+ '@in': z.ZodString;
290
+ '@grid': z.ZodOptional<z.ZodNumber>;
291
+ '@slot': z.ZodOptional<z.ZodString>;
292
+ }, z.core.$strict>, z.ZodObject<{
293
+ '@day': z.ZodNumber;
294
+ '@time': z.ZodString;
295
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
296
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
297
+ }, z.core.$strict>, z.ZodObject<{
298
+ '@day': z.ZodNumber;
299
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
300
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
301
+ }, z.core.$strict>, z.ZodObject<{
302
+ '@month': z.ZodNumber;
303
+ '@dom': z.ZodNumber;
304
+ '@time': z.ZodOptional<z.ZodString>;
305
+ }, z.core.$strict>, z.ZodObject<{
306
+ '@t': z.ZodRecord<z.ZodString, z.ZodString>;
307
+ }, z.core.$strict>, z.ZodObject<{
308
+ '@asset': z.ZodString;
309
+ }, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
310
+ during: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodUnion<readonly [z.ZodObject<{
311
+ '@ref': z.ZodString;
312
+ }, z.core.$strict>, z.ZodObject<{
313
+ '@ago': z.ZodString;
314
+ }, z.core.$strict>, z.ZodObject<{
315
+ '@in': z.ZodString;
316
+ '@grid': z.ZodOptional<z.ZodNumber>;
317
+ '@slot': z.ZodOptional<z.ZodString>;
318
+ }, z.core.$strict>, z.ZodObject<{
319
+ '@day': z.ZodNumber;
320
+ '@time': z.ZodString;
321
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
322
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
323
+ }, z.core.$strict>, z.ZodObject<{
324
+ '@day': z.ZodNumber;
325
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
326
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
327
+ }, z.core.$strict>, z.ZodObject<{
328
+ '@month': z.ZodNumber;
329
+ '@dom': z.ZodNumber;
330
+ '@time': z.ZodOptional<z.ZodString>;
331
+ }, z.core.$strict>, z.ZodObject<{
332
+ '@t': z.ZodRecord<z.ZodString, z.ZodString>;
333
+ }, z.core.$strict>, z.ZodObject<{
334
+ '@asset': z.ZodString;
335
+ }, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
336
+ after: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodUnion<readonly [z.ZodUnion<readonly [z.ZodString, z.ZodNumber, z.ZodBoolean, z.ZodNull]>, z.ZodUnion<readonly [z.ZodObject<{
337
+ '@ref': z.ZodString;
338
+ }, z.core.$strict>, z.ZodObject<{
339
+ '@ago': z.ZodString;
340
+ }, z.core.$strict>, z.ZodObject<{
341
+ '@in': z.ZodString;
342
+ '@grid': z.ZodOptional<z.ZodNumber>;
343
+ '@slot': z.ZodOptional<z.ZodString>;
344
+ }, z.core.$strict>, z.ZodObject<{
345
+ '@day': z.ZodNumber;
346
+ '@time': z.ZodString;
347
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
348
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
349
+ }, z.core.$strict>, z.ZodObject<{
350
+ '@day': z.ZodNumber;
351
+ '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
352
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
353
+ }, z.core.$strict>, z.ZodObject<{
354
+ '@month': z.ZodNumber;
355
+ '@dom': z.ZodNumber;
356
+ '@time': z.ZodOptional<z.ZodString>;
357
+ }, z.core.$strict>, z.ZodObject<{
358
+ '@t': z.ZodRecord<z.ZodString, z.ZodString>;
359
+ }, z.core.$strict>, z.ZodObject<{
360
+ '@asset': z.ZodString;
361
+ }, z.core.$strict>]>, z.ZodArray<z.ZodUnknown>, z.ZodRecord<z.ZodString, z.ZodUnknown>]>>>;
362
+ }, z.core.$strict>;
363
+ export type ByStay = z.infer<typeof byStaySchema>;
172
364
  /** The keys of a row that are directives about the row, not columns. */
173
365
  export declare const ROW_DIRECTIVES: ReadonlySet<string>;
366
+ /** The weekdays a bundle's week anchor names. */
367
+ export declare const SAMPLE_WEEKDAYS: readonly ["mon", "tue", "wed", "thu", "fri", "sat", "sun"];
174
368
  export declare const sampleBundleSchema: z.ZodObject<{
175
369
  format: z.ZodLiteral<"adminium.sample/1">;
176
370
  app: z.ZodString;
371
+ weekAnchor: z.ZodOptional<z.ZodEnum<{
372
+ mon: "mon";
373
+ tue: "tue";
374
+ wed: "wed";
375
+ thu: "thu";
376
+ fri: "fri";
377
+ sat: "sat";
378
+ sun: "sun";
379
+ }>>;
177
380
  assets: z.ZodDefault<z.ZodRecord<z.ZodString, z.ZodObject<{
178
381
  file: z.ZodString;
179
382
  sha256: z.ZodString;
@@ -184,13 +387,19 @@ export declare const sampleBundleSchema: z.ZodObject<{
184
387
  '@ref': z.ZodString;
185
388
  }, z.core.$strict>, z.ZodObject<{
186
389
  '@ago': z.ZodString;
390
+ }, z.core.$strict>, z.ZodObject<{
391
+ '@in': z.ZodString;
392
+ '@grid': z.ZodOptional<z.ZodNumber>;
393
+ '@slot': z.ZodOptional<z.ZodString>;
187
394
  }, z.core.$strict>, z.ZodObject<{
188
395
  '@day': z.ZodNumber;
189
396
  '@time': z.ZodString;
190
397
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
398
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
191
399
  }, z.core.$strict>, z.ZodObject<{
192
400
  '@day': z.ZodNumber;
193
401
  '@workdays': z.ZodOptional<z.ZodLiteral<true>>;
402
+ '@week': z.ZodOptional<z.ZodLiteral<true>>;
194
403
  }, z.core.$strict>, z.ZodObject<{
195
404
  '@month': z.ZodNumber;
196
405
  '@dom': z.ZodNumber;
@@ -211,15 +420,22 @@ export declare function sampleDirective(value: unknown): {
211
420
  } | {
212
421
  kind: 'ago';
213
422
  duration: string;
423
+ } | {
424
+ kind: 'in';
425
+ duration: string;
426
+ grid: number | null;
427
+ slot: string | null;
214
428
  } | {
215
429
  kind: 'wall';
216
430
  day: number;
217
431
  time: string;
218
432
  workdays: boolean;
433
+ week: boolean;
219
434
  } | {
220
435
  kind: 'date';
221
436
  day: number;
222
437
  workdays: boolean;
438
+ week: boolean;
223
439
  } | {
224
440
  kind: 'month';
225
441
  months: number;
@@ -1 +1 @@
1
- {"version":3,"file":"sample.d.ts","sourceRoot":"","sources":["../src/sample.ts"],"names":[],"mappings":"AACA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA0CG;AACH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAC;AAExB,OAAO,KAAK,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAE5C,eAAO,MAAM,aAAa,sBAAsB,CAAC;AA+BjD,gGAAgG;AAChG,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;;;;wFAAuF,CAAC;AAEtH,eAAO,MAAM,eAAe;;;;;;;;;;;;;;;;;;;yFAA0C,CAAC;AAKvE,qFAAqF;AACrF,eAAO,MAAM,aAAa;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAQf,CAAC;AACZ,MAAM,MAAM,OAAO,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,aAAa,CAAC,CAAC;AAEpD,wEAAwE;AACxE,eAAO,MAAM,cAAc,EAAE,WAAW,CAAC,MAAM,CAAmD,CAAC;AAEnG,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kBAWpB,CAAC;AAEZ,MAAM,MAAM,YAAY,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,kBAAkB,CAAC,CAAC;AAC9D,MAAM,MAAM,WAAW,GAAG,CAAC,CAAC,KAAK,CAAC,OAAO,iBAAiB,CAAC,CAAC;AAE5D,2CAA2C;AAC3C,wBAAgB,eAAe,CAAC,KAAK,EAAE,OAAO,GAC1C;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9B;IAAE,IAAI,EAAE,KAAK,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,GACjC;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAC9D;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,GAAG,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,GACnE;IAAE,IAAI,EAAE,GAAG,CAAC;IAAC,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAChC,IAAI,CAiBP;AAED,4CAA4C;AAC5C,wBAAgB,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAUtD;AAED,MAAM,WAAW,WAAW;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;CACjB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,MAAM,EAAE,YAAY,EAAE,QAAQ,EAAE,QAAQ,GAAG,WAAW,EAAE,CAgG1F"}
1
+ {"version":3,"file":"sample.d.ts","sourceRoot":"","sources":["../src/sample.ts"],"names":[],"mappings":"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"}
package/dist/sample.js CHANGED
@@ -8,6 +8,10 @@
8
8
  *
9
9
  * `{"@ref": "<label>"}` the key of an earlier row with that `@label`
10
10
  * `{"@ago": "PT19M"}` an ISO-8601 duration before now
11
+ * `{"@in": "PT20M", "@grid": 15}` an ISO-8601 duration after now; with
12
+ * `@grid`, rounded up to the next time on that
13
+ * many minutes' grid of the venue's own clock
14
+ * (the first pickup slot at least 20 minutes on)
11
15
  * `{"@day": -1, "@time": "09:30"}` a wall time in the venue's own zone,
12
16
  * days from today
13
17
  * `{"@day": 3}` a date in the venue's own zone
@@ -16,7 +20,15 @@
16
20
  *
17
21
  * A `@day` may add `"@workdays": true`: its days count Monday to Friday, and
18
22
  * day 0 on a weekend is the Monday after — so "today's" busy day is never a
19
- * Saturday.
23
+ * Saturday. Or `"@week": true`: its days count from the bundle's anchor day
24
+ * (`weekAnchor`, a weekday) in the week nearest today, so every date keeps
25
+ * the weekday the sample was written for — a weekend stay stays on a
26
+ * weekend, whatever day the sample is added on.
27
+ *
28
+ * `{"@in": "PT20M", "@slot": "orders"}` the first open time of that
29
+ * table's slot limit at least that far ahead —
30
+ * its hours, closures and pauses, on its grid —
31
+ * on the next day it opens when today has none
20
32
  *
21
33
  * `{"@month": -2, "@dom": 14}` a date in the venue's own zone: that day of
22
34
  * the month so many months from this one; with
@@ -34,7 +46,13 @@
34
46
  * falls against the adding moment — more than half an hour before, within
35
47
  * half an hour, or later — so a sample day's statuses match the clock it is
36
48
  * added at. A set with `"@skip": true` leaves the row out (a payment for a
37
- * visit that has not happened yet).
49
+ * visit that has not happened yet). Or `@byStay` `{from, to, times?, before,
50
+ * during, after}`: by where the adding moment falls against the row's two
51
+ * times — its arrival and its departure (columns of the row, or `@day`s) —
52
+ * before the stay, during it, or after it; a date is read at `times.from` /
53
+ * `times.to` on its day (arriving from 15:00, leaving by 11:00), else at its
54
+ * midnight. So a stay's status (booked, in house, departed) matches the
55
+ * clock it is added at. A row takes one of the two.
38
56
  *
39
57
  * `"@onlyIfEmpty": true` is for a table that holds one row, the app's own
40
58
  * settings: the row is added only when the table has none, and otherwise its
@@ -50,14 +68,27 @@ const ISO_DURATION = /^P(?!$)(\d+W)?(\d+D)?(T(?=\d)(\d+H)?(\d+M)?(\d+(\.\d+)?S)?
50
68
  const directive = z.union([
51
69
  z.object({ '@ref': label }).strict(),
52
70
  z.object({ '@ago': z.string().regex(ISO_DURATION, 'an ISO-8601 duration such as PT19M') }).strict(),
71
+ z
72
+ .object({
73
+ '@in': z.string().regex(ISO_DURATION, 'an ISO-8601 duration such as PT20M'),
74
+ '@grid': z.number().int().min(1).max(1440).optional(),
75
+ '@slot': z.string().regex(/^[a-z][a-z0-9_]*$/, 'a table').optional(),
76
+ })
77
+ .strict()
78
+ .refine((d) => d['@grid'] === undefined || d['@slot'] === undefined, { message: 'a time on a slot limit takes its grid from the limit' }),
53
79
  z
54
80
  .object({
55
81
  '@day': z.number().int().min(-366).max(366),
56
82
  '@time': z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, 'a time such as 09:30'),
57
83
  '@workdays': z.literal(true).optional(),
84
+ '@week': z.literal(true).optional(),
58
85
  })
59
- .strict(),
60
- z.object({ '@day': z.number().int().min(-366).max(366), '@workdays': z.literal(true).optional() }).strict(),
86
+ .strict()
87
+ .refine((d) => d['@workdays'] === undefined || d['@week'] === undefined, { message: 'days count working days or from the week anchor, not both' }),
88
+ z
89
+ .object({ '@day': z.number().int().min(-366).max(366), '@workdays': z.literal(true).optional(), '@week': z.literal(true).optional() })
90
+ .strict()
91
+ .refine((d) => d['@workdays'] === undefined || d['@week'] === undefined, { message: 'days count working days or from the week anchor, not both' }),
61
92
  z
62
93
  .object({
63
94
  '@month': z.number().int().min(-120).max(0),
@@ -84,12 +115,30 @@ export const byClockSchema = z
84
115
  after: clockBranchSchema.optional(),
85
116
  })
86
117
  .strict();
118
+ const clockText = z.string().regex(/^([01]\d|2[0-3]):[0-5]\d$/, 'a time such as 15:00');
119
+ /** `@byStay`: a row's columns by where the adding moment falls against its two times — before, during or after its stay. */
120
+ export const byStaySchema = z
121
+ .object({
122
+ /** The arrival and the departure: columns of the row, or the times themselves. */
123
+ from: z.union([z.string().min(1), directive]),
124
+ to: z.union([z.string().min(1), directive]),
125
+ /** The wall times a date is read at: arriving from, leaving by. */
126
+ times: z.object({ from: clockText.optional(), to: clockText.optional() }).strict().optional(),
127
+ before: clockBranchSchema.optional(),
128
+ during: clockBranchSchema.optional(),
129
+ after: clockBranchSchema.optional(),
130
+ })
131
+ .strict();
87
132
  /** The keys of a row that are directives about the row, not columns. */
88
- export const ROW_DIRECTIVES = new Set(['@label', '@byClock', '@onlyIfEmpty']);
133
+ export const ROW_DIRECTIVES = new Set(['@label', '@byClock', '@byStay', '@onlyIfEmpty']);
134
+ /** The weekdays a bundle's week anchor names. */
135
+ export const SAMPLE_WEEKDAYS = ['mon', 'tue', 'wed', 'thu', 'fri', 'sat', 'sun'];
89
136
  export const sampleBundleSchema = z
90
137
  .object({
91
138
  format: z.literal(SAMPLE_FORMAT),
92
139
  app: z.string().min(1),
140
+ /** The weekday the sample's `@week` days count from (the day it was written for), in the week nearest the adding day. */
141
+ weekAnchor: z.enum(SAMPLE_WEEKDAYS).optional(),
93
142
  assets: z
94
143
  .record(label, z.object({ file: z.string().regex(/^seeds\/[a-z0-9][a-z0-9._/-]*$/), sha256: z.string().regex(/^[a-f0-9]{64}$/) }).strict())
95
144
  .default({}),
@@ -107,11 +156,19 @@ export function sampleDirective(value) {
107
156
  return { kind: 'ref', label: record['@ref'] };
108
157
  if (typeof record['@ago'] === 'string')
109
158
  return { kind: 'ago', duration: record['@ago'] };
159
+ if (typeof record['@in'] === 'string') {
160
+ return {
161
+ kind: 'in',
162
+ duration: record['@in'],
163
+ grid: typeof record['@grid'] === 'number' ? record['@grid'] : null,
164
+ slot: typeof record['@slot'] === 'string' ? record['@slot'] : null,
165
+ };
166
+ }
110
167
  if (typeof record['@day'] === 'number' && typeof record['@time'] === 'string') {
111
- return { kind: 'wall', day: record['@day'], time: record['@time'], workdays: record['@workdays'] === true };
168
+ return { kind: 'wall', day: record['@day'], time: record['@time'], workdays: record['@workdays'] === true, week: record['@week'] === true };
112
169
  }
113
170
  if (typeof record['@day'] === 'number')
114
- return { kind: 'date', day: record['@day'], workdays: record['@workdays'] === true };
171
+ return { kind: 'date', day: record['@day'], workdays: record['@workdays'] === true, week: record['@week'] === true };
115
172
  if (typeof record['@month'] === 'number' && typeof record['@dom'] === 'number') {
116
173
  return { kind: 'month', months: record['@month'], dom: record['@dom'], time: typeof record['@time'] === 'string' ? record['@time'] : null };
117
174
  }
@@ -135,6 +192,26 @@ export function isoDurationMs(duration) {
135
192
  const seconds = n(match[6]);
136
193
  return ((((weeks * 7 + days) * 24 + hours) * 60 + minutes) * 60 + seconds) * 1000;
137
194
  }
195
+ /**
196
+ * What a time directive needs of the bundle and the manifest: a `@week` day
197
+ * the bundle's week anchor, and a `@slot` time a table of the app with a slot
198
+ * limit to find its open times in.
199
+ */
200
+ function timeDirectiveIssues(found, path, bundle, declared) {
201
+ if (found === null)
202
+ return [];
203
+ if ((found.kind === 'wall' || found.kind === 'date') && found.week && bundle.weekAnchor === undefined) {
204
+ return [{ path, message: 'A `@week` day counts from the bundle’s week anchor: name it (`weekAnchor`).' }];
205
+ }
206
+ if (found.kind === 'in' && found.slot !== null) {
207
+ const capacity = declared.get(found.slot)?.capacity;
208
+ const rules = capacity === undefined ? [] : Array.isArray(capacity) ? capacity : [capacity];
209
+ if (!rules.some((rule) => (rule.kind ?? 'slot') === 'slot')) {
210
+ return [{ path, message: `"${found.slot}" keeps no slot limit, so it has no open times to find.` }];
211
+ }
212
+ }
213
+ return [];
214
+ }
138
215
  /**
139
216
  * Everything wrong with a bundle for this manifest: a table it does not
140
217
  * declare, a column the table does not have, a label used twice, a `@ref` to
@@ -155,6 +232,20 @@ export function sampleBundleIssues(bundle, manifest) {
155
232
  continue;
156
233
  }
157
234
  const columns = new Set(shape.columns.map((column) => column.ref));
235
+ // A row priced by the night is priced as it is written, from its rate and adjustment rows: those come first.
236
+ for (const column of shape.columns) {
237
+ const rule = column.rules?.perNight;
238
+ if (rule === undefined)
239
+ continue;
240
+ const rateTable = shape.columns.find((c) => c.ref === rule.rate.via)?.references;
241
+ for (const source of [rateTable, rule.adjust?.table]) {
242
+ if (source === undefined)
243
+ continue;
244
+ const listed = bundle.tables.findIndex((other) => other.ref === source);
245
+ if (listed >= t)
246
+ issues.push({ path: `tables.${String(t)}.ref`, message: `"${source}" must come before "${table.ref}": "${table.ref}" is priced from it.` });
247
+ }
248
+ }
158
249
  // A number Adminium gives without gaps: a sample row names it, empty, or the load numbers it into the real series.
159
250
  const gapless = shape.columns.filter((column) => column.rules?.sequence?.gapless === true).map((column) => column.ref);
160
251
  for (const [r, row] of table.rows.entries()) {
@@ -179,6 +270,40 @@ export function sampleBundleIssues(bundle, manifest) {
179
270
  issues.push({ path: `${at}.@onlyIfEmpty`, message: '"@onlyIfEmpty" is true, or absent.' });
180
271
  continue;
181
272
  }
273
+ if (column === '@byStay') {
274
+ if (row['@byClock'] !== undefined)
275
+ issues.push({ path: `${at}.@byStay`, message: 'A row takes @byClock or @byStay, not both.' });
276
+ const stay = byStaySchema.safeParse(value);
277
+ if (!stay.success) {
278
+ issues.push({ path: `${at}.@byStay`, message: '@byStay names its two times (`from`, `to`) and up to three sets: before, during, after.' });
279
+ continue;
280
+ }
281
+ for (const end of ['from', 'to']) {
282
+ const when = stay.data[end];
283
+ if (typeof when === 'string' && !(columns.has(when) && when in row)) {
284
+ issues.push({ path: `${at}.@byStay.${end}`, message: `"${when}" is not a column this row sets.` });
285
+ }
286
+ else if (typeof when !== 'string' && !['wall', 'date'].includes(sampleDirective(when)?.kind ?? '')) {
287
+ issues.push({ path: `${at}.@byStay.${end}`, message: 'A time is a column of the row or a `@day` (with a `@time`, or not).' });
288
+ }
289
+ }
290
+ for (const branch of ['before', 'during', 'after']) {
291
+ for (const [name, part] of Object.entries(stay.data[branch] ?? {})) {
292
+ if (name === '@skip') {
293
+ if (part !== true)
294
+ issues.push({ path: `${at}.@byStay.${branch}.@skip`, message: '"@skip" is true, or absent.' });
295
+ continue;
296
+ }
297
+ if (!columns.has(name))
298
+ issues.push({ path: `${at}.@byStay.${branch}.${name}`, message: `"${table.ref}" has no column "${name}".` });
299
+ const found = sampleDirective(part);
300
+ if (found?.kind === 'ref' && !seen.has(found.label)) {
301
+ issues.push({ path: `${at}.@byStay.${branch}.${name}`, message: `"${found.label}" is not an earlier row: a referenced row must come first.` });
302
+ }
303
+ }
304
+ }
305
+ continue;
306
+ }
182
307
  if (column === '@byClock') {
183
308
  const clock = byClockSchema.safeParse(value);
184
309
  if (!clock.success) {
@@ -233,6 +358,19 @@ export function sampleBundleIssues(bundle, manifest) {
233
358
  if (found?.kind === 'asset' && bundle.assets[found.label] === undefined) {
234
359
  issues.push({ path: `${at}.${column}`, message: `"${found.label}" is not one of the bundle’s assets.` });
235
360
  }
361
+ issues.push(...timeDirectiveIssues(found, `${at}.${column}`, bundle, declared));
362
+ }
363
+ // A time a row directive reads or sets obeys the same rules as a column's.
364
+ for (const rowDirective of ['@byClock', '@byStay']) {
365
+ const set = row[rowDirective];
366
+ if (typeof set !== 'object' || set === null)
367
+ continue;
368
+ for (const [key, part] of Object.entries(set)) {
369
+ const parts = typeof part === 'object' && part !== null && !Array.isArray(part) && sampleDirective(part) === null ? Object.entries(part) : [['', part]];
370
+ for (const [name, inner] of parts) {
371
+ issues.push(...timeDirectiveIssues(sampleDirective(inner), `${at}.${rowDirective}.${key}${name === '' ? '' : `.${name}`}`, bundle, declared));
372
+ }
373
+ }
236
374
  }
237
375
  // Labelled AFTER its own values are checked: a row cannot refer to itself.
238
376
  const own = row['@label'];