unikvs 0.0.10 → 0.0.13

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 (77) hide show
  1. package/README.md +3 -0
  2. package/dist/index.d.ts +1553 -0
  3. package/dist/index.d.ts.map +1 -0
  4. package/dist/index.js +4032 -0
  5. package/dist/index.js.map +1 -0
  6. package/package.json +35 -34
  7. package/src/_contexts.ts +1089 -0
  8. package/src/_logger.ts +5 -3
  9. package/src/_middleware.ts +207 -0
  10. package/src/_pipeline-graph.helpers.ts +183 -0
  11. package/src/_pipeline-graph.ts +1307 -0
  12. package/src/_pipeline-graph.types.ts +303 -0
  13. package/src/_pipeline-leaf-resolver.ts +70 -0
  14. package/src/_plugin-lifecycle.ts +201 -0
  15. package/src/_storage.ts +173 -96
  16. package/src/_streams.schemas.ts +21 -0
  17. package/src/_streams.ts +73 -0
  18. package/src/_to-value-stream.ts +22 -11
  19. package/src/_types.ts +237 -0
  20. package/src/_unikvs-branch.ts +94 -0
  21. package/src/_unikvs.schemas.ts +451 -0
  22. package/src/_valibot.ts +17 -3
  23. package/src/_value-schemas.ts +192 -0
  24. package/src/_value-validation.ts +57 -0
  25. package/src/errors.ts +446 -252
  26. package/src/index.ts +46 -26
  27. package/src/types.ts +13 -0
  28. package/src/unikvs-branch.ts +445 -0
  29. package/src/unikvs-builder.ts +706 -0
  30. package/src/unikvs.ts +1456 -971
  31. package/src/unikvs.types.ts +194 -0
  32. package/src/value-schemas.ts +98 -0
  33. package/dist/src/_logger.d.ts +0 -3
  34. package/dist/src/_logger.d.ts.map +0 -1
  35. package/dist/src/_logger.js +0 -3
  36. package/dist/src/_merge-context.d.ts +0 -13
  37. package/dist/src/_merge-context.d.ts.map +0 -1
  38. package/dist/src/_merge-context.js +0 -12
  39. package/dist/src/_storage.d.ts +0 -18
  40. package/dist/src/_storage.d.ts.map +0 -1
  41. package/dist/src/_storage.js +0 -94
  42. package/dist/src/_to-value-stream.d.ts +0 -12
  43. package/dist/src/_to-value-stream.d.ts.map +0 -1
  44. package/dist/src/_to-value-stream.js +0 -102
  45. package/dist/src/_transformer.d.ts +0 -13
  46. package/dist/src/_transformer.d.ts.map +0 -1
  47. package/dist/src/_transformer.js +0 -60
  48. package/dist/src/_valibot.d.ts +0 -15
  49. package/dist/src/_valibot.d.ts.map +0 -1
  50. package/dist/src/_valibot.js +0 -23
  51. package/dist/src/context.types.d.ts +0 -17
  52. package/dist/src/context.types.d.ts.map +0 -1
  53. package/dist/src/context.types.js +0 -1
  54. package/dist/src/errors.d.ts +0 -340
  55. package/dist/src/errors.d.ts.map +0 -1
  56. package/dist/src/errors.js +0 -250
  57. package/dist/src/index.d.ts +0 -10
  58. package/dist/src/index.d.ts.map +0 -1
  59. package/dist/src/index.js +0 -3
  60. package/dist/src/unikvs-config.d.ts +0 -255
  61. package/dist/src/unikvs-config.d.ts.map +0 -1
  62. package/dist/src/unikvs-config.js +0 -105
  63. package/dist/src/unikvs.d.ts +0 -354
  64. package/dist/src/unikvs.d.ts.map +0 -1
  65. package/dist/src/unikvs.js +0 -867
  66. package/dist/src/utils.types.d.ts +0 -7
  67. package/dist/src/utils.types.d.ts.map +0 -1
  68. package/dist/src/utils.types.js +0 -1
  69. package/dist/src/value-stream.types.d.ts +0 -16
  70. package/dist/src/value-stream.types.d.ts.map +0 -1
  71. package/dist/src/value-stream.types.js +0 -1
  72. package/src/_merge-context.ts +0 -19
  73. package/src/_transformer.ts +0 -89
  74. package/src/context.types.ts +0 -19
  75. package/src/unikvs-config.ts +0 -426
  76. package/src/utils.types.ts +0 -6
  77. package/src/value-stream.types.ts +0 -19
@@ -0,0 +1,451 @@
1
+ import type { TupleSchema, ObjectSchema } from "@tai-kun/valibot-extra-lab";
2
+ import type {
3
+ StringSchema,
4
+ BooleanSchema,
5
+ GenericSchema,
6
+ UnknownSchema,
7
+ InstanceSchema,
8
+ OptionalSchema,
9
+ } from "valibot";
10
+
11
+ import type { VariablesEntry } from "./_contexts.js";
12
+ import {
13
+ omit,
14
+ pipe,
15
+ tuple,
16
+ union,
17
+ custom,
18
+ object,
19
+ record,
20
+ string,
21
+ boolean,
22
+ unknown,
23
+ instance,
24
+ optional,
25
+ transform,
26
+ } from "./_valibot.js";
27
+
28
+ export const VariablesKeySchema: StringSchema<undefined> = string();
29
+
30
+ export const VariablesInitSchema: GenericSchema<any, readonly VariablesEntry[]> = pipe(
31
+ union([
32
+ custom<Iterable<VariablesEntry>>(
33
+ // 各アイテムの検証は今後の課題です。
34
+ (input) => typeof input === "object" && input !== null && Symbol.iterator in input,
35
+ "Expected a Iterable object",
36
+ ),
37
+ record(VariablesKeySchema, unknown()),
38
+ ]),
39
+ transform(
40
+ (input: Iterable<VariablesEntry> | Record<string, unknown>): readonly VariablesEntry[] => {
41
+ if (Symbol.iterator in input) {
42
+ return [...input];
43
+ }
44
+
45
+ return Object.entries(input);
46
+ },
47
+ ),
48
+ );
49
+
50
+ export const VariablesArgsSchema: TupleSchema<[typeof VariablesInitSchema], undefined> = tuple([
51
+ VariablesInitSchema,
52
+ ]);
53
+
54
+ export const OpenOptionsSchema: ObjectSchema<
55
+ {
56
+ readonly vars: OptionalSchema<typeof VariablesInitSchema, undefined>;
57
+ readonly signal: OptionalSchema<InstanceSchema<typeof AbortSignal, undefined>, undefined>;
58
+ },
59
+ undefined
60
+ > = object({
61
+ /**
62
+ * 処理の中断を通知するためのシグナルです。
63
+ */
64
+ signal: optional(instance(AbortSignal)),
65
+
66
+ /**
67
+ * 実行時の変数です。
68
+ */
69
+ vars: optional(VariablesInitSchema),
70
+ });
71
+
72
+ export const OpenArgsSchema: TupleSchema<
73
+ [OptionalSchema<typeof OpenOptionsSchema, undefined>],
74
+ undefined
75
+ > = tuple([optional(OpenOptionsSchema)]);
76
+
77
+ export const CloseOptionsSchema: ObjectSchema<
78
+ {
79
+ readonly vars: OptionalSchema<typeof VariablesInitSchema, undefined>;
80
+ readonly signal: OptionalSchema<InstanceSchema<typeof AbortSignal, undefined>, undefined>;
81
+ },
82
+ undefined
83
+ > = object({
84
+ /**
85
+ * 処理の中断を通知するためのシグナルです。
86
+ */
87
+ signal: optional(instance(AbortSignal)),
88
+
89
+ /**
90
+ * 実行時の変数です。
91
+ */
92
+ vars: optional(VariablesInitSchema),
93
+ });
94
+
95
+ export const CloseArgsSchema: TupleSchema<
96
+ [OptionalSchema<typeof CloseOptionsSchema, undefined>],
97
+ undefined
98
+ > = tuple([optional(CloseOptionsSchema)]);
99
+
100
+ export const SetOptionsSchema: ObjectSchema<
101
+ {
102
+ readonly key: StringSchema<undefined>;
103
+ readonly vars: OptionalSchema<typeof VariablesInitSchema, undefined>;
104
+ readonly value: UnknownSchema;
105
+ readonly signal: OptionalSchema<InstanceSchema<typeof AbortSignal, undefined>, undefined>;
106
+ },
107
+ undefined
108
+ > = object({
109
+ key: string(),
110
+ vars: optional(VariablesInitSchema),
111
+ value: unknown(),
112
+ signal: optional(instance(AbortSignal)),
113
+ });
114
+
115
+ export const SetArgsSchema: GenericSchema<
116
+ any,
117
+ | readonly [
118
+ {
119
+ readonly key: string;
120
+ readonly vars?: readonly VariablesEntry[] | undefined;
121
+ readonly value: unknown;
122
+ readonly signal?: AbortSignal | undefined;
123
+ },
124
+ ]
125
+ | readonly [
126
+ {
127
+ readonly key: string;
128
+ readonly vars?: readonly VariablesEntry[] | undefined;
129
+ readonly value: unknown;
130
+ readonly signal?: AbortSignal | undefined;
131
+ },
132
+ ]
133
+ > = union([
134
+ tuple([SetOptionsSchema]),
135
+ pipe(
136
+ tuple([
137
+ SetOptionsSchema.entries.key,
138
+ SetOptionsSchema.entries.value,
139
+ optional(omit(SetOptionsSchema, ["key", "value"])),
140
+ ]),
141
+ transform(
142
+ ([key, value, options]: [
143
+ string,
144
+ unknown,
145
+ (
146
+ | {
147
+ vars?: readonly VariablesEntry[] | undefined;
148
+ signal?: AbortSignal | undefined;
149
+ }
150
+ | undefined
151
+ ),
152
+ ]): [
153
+ {
154
+ key: string;
155
+ vars?: readonly VariablesEntry[] | undefined;
156
+ value: unknown;
157
+ signal?: AbortSignal | undefined;
158
+ },
159
+ ] => [
160
+ {
161
+ ...options,
162
+ key,
163
+ value,
164
+ },
165
+ ],
166
+ ),
167
+ ),
168
+ ]);
169
+
170
+ export const GetOptionsSchema: ObjectSchema<
171
+ {
172
+ readonly key: StringSchema<undefined>;
173
+ readonly vars: OptionalSchema<typeof VariablesInitSchema, undefined>;
174
+ readonly repair: OptionalSchema<BooleanSchema<undefined>, undefined>;
175
+ readonly signal: OptionalSchema<InstanceSchema<typeof AbortSignal, undefined>, undefined>;
176
+ readonly throwOnRepairDenied: OptionalSchema<BooleanSchema<undefined>, undefined>;
177
+ },
178
+ undefined
179
+ > = object({
180
+ key: string(),
181
+ vars: optional(VariablesInitSchema),
182
+ repair: optional(boolean()),
183
+ signal: optional(instance(AbortSignal)),
184
+ throwOnRepairDenied: optional(boolean()),
185
+ });
186
+
187
+ export const GetArgsSchema: GenericSchema<
188
+ any,
189
+ | readonly [
190
+ {
191
+ readonly key: string;
192
+ readonly vars?: readonly VariablesEntry[] | undefined;
193
+ readonly repair?: boolean | undefined;
194
+ readonly signal?: AbortSignal | undefined;
195
+ readonly throwOnRepairDenied?: boolean | undefined;
196
+ },
197
+ ]
198
+ | readonly [
199
+ {
200
+ readonly key: string;
201
+ readonly vars?: readonly VariablesEntry[] | undefined;
202
+ readonly repair?: boolean | undefined;
203
+ readonly signal?: AbortSignal | undefined;
204
+ readonly throwOnRepairDenied?: boolean | undefined;
205
+ },
206
+ ]
207
+ > = union([
208
+ tuple([GetOptionsSchema]),
209
+ pipe(
210
+ tuple([GetOptionsSchema.entries.key, optional(omit(GetOptionsSchema, ["key"]))]),
211
+ transform(
212
+ ([key, options]: [
213
+ string,
214
+ (
215
+ | {
216
+ vars?: readonly VariablesEntry[] | undefined;
217
+ repair?: boolean | undefined;
218
+ signal?: AbortSignal | undefined;
219
+ throwOnRepairDenied?: boolean | undefined;
220
+ }
221
+ | undefined
222
+ ),
223
+ ]): [
224
+ {
225
+ key: string;
226
+ vars?: readonly VariablesEntry[] | undefined;
227
+ repair?: boolean | undefined;
228
+ signal?: AbortSignal | undefined;
229
+ throwOnRepairDenied?: boolean | undefined;
230
+ },
231
+ ] => [
232
+ {
233
+ ...options,
234
+ key,
235
+ },
236
+ ],
237
+ ),
238
+ ),
239
+ ]);
240
+
241
+ export const StreamOptionsSchema: ObjectSchema<
242
+ {
243
+ readonly key: StringSchema<undefined>;
244
+ readonly vars: OptionalSchema<typeof VariablesInitSchema, undefined>;
245
+ readonly repair: OptionalSchema<BooleanSchema<undefined>, undefined>;
246
+ readonly signal: OptionalSchema<InstanceSchema<typeof AbortSignal, undefined>, undefined>;
247
+ readonly throwOnRepairDenied: OptionalSchema<BooleanSchema<undefined>, undefined>;
248
+ },
249
+ undefined
250
+ > = object({
251
+ key: string(),
252
+ vars: optional(VariablesInitSchema),
253
+ repair: optional(boolean()),
254
+ signal: optional(instance(AbortSignal)),
255
+ throwOnRepairDenied: optional(boolean()),
256
+ });
257
+
258
+ export const StreamArgsSchema: GenericSchema<
259
+ any,
260
+ | readonly [
261
+ {
262
+ readonly key: string;
263
+ readonly vars?: readonly VariablesEntry[] | undefined;
264
+ readonly repair?: boolean | undefined;
265
+ readonly signal?: AbortSignal | undefined;
266
+ readonly throwOnRepairDenied?: boolean | undefined;
267
+ },
268
+ ]
269
+ | readonly [
270
+ {
271
+ readonly key: string;
272
+ readonly vars?: readonly VariablesEntry[] | undefined;
273
+ readonly repair?: boolean | undefined;
274
+ readonly signal?: AbortSignal | undefined;
275
+ readonly throwOnRepairDenied?: boolean | undefined;
276
+ },
277
+ ]
278
+ > = union([
279
+ tuple([StreamOptionsSchema]),
280
+ pipe(
281
+ tuple([StreamOptionsSchema.entries.key, optional(omit(StreamOptionsSchema, ["key"]))]),
282
+ transform(
283
+ ([key, options]: [
284
+ string,
285
+ (
286
+ | {
287
+ vars?: readonly VariablesEntry[] | undefined;
288
+ repair?: boolean | undefined;
289
+ signal?: AbortSignal | undefined;
290
+ throwOnRepairDenied?: boolean | undefined;
291
+ }
292
+ | undefined
293
+ ),
294
+ ]): [
295
+ {
296
+ key: string;
297
+ vars?: readonly VariablesEntry[] | undefined;
298
+ repair?: boolean | undefined;
299
+ signal?: AbortSignal | undefined;
300
+ throwOnRepairDenied?: boolean | undefined;
301
+ },
302
+ ] => [
303
+ {
304
+ ...options,
305
+ key,
306
+ },
307
+ ],
308
+ ),
309
+ ),
310
+ ]);
311
+
312
+ export const HasOptionsSchema: ObjectSchema<
313
+ {
314
+ readonly key: StringSchema<undefined>;
315
+ readonly vars: OptionalSchema<typeof VariablesInitSchema, undefined>;
316
+ readonly signal: OptionalSchema<InstanceSchema<typeof AbortSignal, undefined>, undefined>;
317
+ },
318
+ undefined
319
+ > = object({
320
+ key: string(),
321
+ vars: optional(VariablesInitSchema),
322
+ signal: optional(instance(AbortSignal)),
323
+ });
324
+
325
+ export const HasArgsSchema: GenericSchema<
326
+ any,
327
+ | readonly [
328
+ {
329
+ readonly key: string;
330
+ readonly vars?: readonly VariablesEntry[] | undefined;
331
+ readonly signal?: AbortSignal | undefined;
332
+ },
333
+ ]
334
+ | readonly [
335
+ {
336
+ readonly key: string;
337
+ readonly vars?: readonly VariablesEntry[] | undefined;
338
+ readonly signal?: AbortSignal | undefined;
339
+ },
340
+ ]
341
+ > = union([
342
+ tuple([HasOptionsSchema]),
343
+ pipe(
344
+ tuple([HasOptionsSchema.entries.key, optional(omit(HasOptionsSchema, ["key"]))]),
345
+ transform(
346
+ ([key, options]: [
347
+ string,
348
+ (
349
+ | {
350
+ vars?: readonly VariablesEntry[] | undefined;
351
+ signal?: AbortSignal | undefined;
352
+ }
353
+ | undefined
354
+ ),
355
+ ]): [
356
+ {
357
+ key: string;
358
+ vars?: readonly VariablesEntry[] | undefined;
359
+ signal?: AbortSignal | undefined;
360
+ },
361
+ ] => [
362
+ {
363
+ ...options,
364
+ key,
365
+ },
366
+ ],
367
+ ),
368
+ ),
369
+ ]);
370
+
371
+ export const DeleteOptionsSchema: ObjectSchema<
372
+ {
373
+ readonly key: StringSchema<undefined>;
374
+ readonly vars: OptionalSchema<typeof VariablesInitSchema, undefined>;
375
+ readonly signal: OptionalSchema<InstanceSchema<typeof AbortSignal, undefined>, undefined>;
376
+ },
377
+ undefined
378
+ > = object({
379
+ key: string(),
380
+ vars: optional(VariablesInitSchema),
381
+ signal: optional(instance(AbortSignal)),
382
+ });
383
+
384
+ export const DeleteArgsSchema: GenericSchema<
385
+ any,
386
+ | readonly [
387
+ {
388
+ readonly key: string;
389
+ readonly vars?: readonly VariablesEntry[] | undefined;
390
+ readonly signal?: AbortSignal | undefined;
391
+ },
392
+ ]
393
+ | readonly [
394
+ {
395
+ readonly key: string;
396
+ readonly vars?: readonly VariablesEntry[] | undefined;
397
+ readonly signal?: AbortSignal | undefined;
398
+ },
399
+ ]
400
+ > = union([
401
+ tuple([DeleteOptionsSchema]),
402
+ pipe(
403
+ tuple([DeleteOptionsSchema.entries.key, optional(omit(DeleteOptionsSchema, ["key"]))]),
404
+ transform(
405
+ ([key, options]: [
406
+ string,
407
+ (
408
+ | {
409
+ vars?: readonly VariablesEntry[] | undefined;
410
+ signal?: AbortSignal | undefined;
411
+ }
412
+ | undefined
413
+ ),
414
+ ]): [
415
+ {
416
+ key: string;
417
+ vars?: readonly VariablesEntry[] | undefined;
418
+ signal?: AbortSignal | undefined;
419
+ },
420
+ ] => [
421
+ {
422
+ ...options,
423
+ key,
424
+ },
425
+ ],
426
+ ),
427
+ ),
428
+ ]);
429
+
430
+ export const ClearOptionsSchema: ObjectSchema<
431
+ {
432
+ readonly vars: OptionalSchema<typeof VariablesInitSchema, undefined>;
433
+ readonly signal: OptionalSchema<InstanceSchema<typeof AbortSignal, undefined>, undefined>;
434
+ },
435
+ undefined
436
+ > = object({
437
+ /**
438
+ * 処理の中断を通知するためのシグナルです。
439
+ */
440
+ signal: optional(instance(AbortSignal)),
441
+
442
+ /**
443
+ * 実行時の変数です。
444
+ */
445
+ vars: optional(VariablesInitSchema),
446
+ });
447
+
448
+ export const ClearArgsSchema: TupleSchema<
449
+ [OptionalSchema<typeof ClearOptionsSchema, undefined>],
450
+ undefined
451
+ > = tuple([optional(ClearOptionsSchema)]);
package/src/_valibot.ts CHANGED
@@ -8,19 +8,23 @@ import {
8
8
  InvalidOutputError,
9
9
  } from "./errors.js";
10
10
 
11
- export type { InferInput, InferOutput } from "valibot";
11
+ export type { InferInput, InferOutput, GenericSchema } from "valibot";
12
12
  export {
13
13
  any,
14
14
  omit,
15
15
  pipe,
16
+ check,
16
17
  union,
18
+ custom,
17
19
  number,
18
20
  string,
19
21
  symbol,
22
+ boolean,
20
23
  unknown,
21
24
  instance,
22
25
  minValue,
23
26
  optional,
27
+ safeParse,
24
28
  safeInteger,
25
29
  } from "valibot";
26
30
 
@@ -38,12 +42,17 @@ export function parseInput<const TSchema extends BaseSchema>(
38
42
  Error: IParseInputErrorConstructor = InvalidInputError,
39
43
  ): InferOutput<TSchema> {
40
44
  const result = safeParse(schema, value);
45
+
41
46
  if (result.success) {
42
47
  return result.output;
43
48
  }
44
49
 
45
- const error = new Error({ value, issues: result.issues });
50
+ const error = new Error({
51
+ value,
52
+ issues: result.issues,
53
+ });
46
54
  tryCaptureStackTrace(error, parseInput);
55
+
47
56
  throw error;
48
57
  }
49
58
 
@@ -57,11 +66,16 @@ export function parseOutput<const TSchema extends BaseSchema>(
57
66
  Error: ParseOutputErrorConstructor = InvalidOutputError,
58
67
  ): InferOutput<TSchema> {
59
68
  const result = safeParse(schema, value);
69
+
60
70
  if (result.success) {
61
71
  return result.output;
62
72
  }
63
73
 
64
- const error = new Error({ value, issues: result.issues });
74
+ const error = new Error({
75
+ value,
76
+ issues: result.issues,
77
+ });
65
78
  tryCaptureStackTrace(error, parseOutput);
79
+
66
80
  throw error;
67
81
  }
@@ -0,0 +1,192 @@
1
+ import type { GenericSchema } from "./_valibot.js";
2
+ import { union, safeParse } from "./_valibot.js";
3
+ import { InvalidInputError } from "./errors.js";
4
+ import type { PlainValue, StreamValue } from "./value-schemas.js";
5
+
6
+ // -------------------------------------------------------------------------------------------------。
7
+ //
8
+ // 値の型。
9
+ //
10
+ // -------------------------------------------------------------------------------------------------。
11
+
12
+ /**
13
+ * PlainValue 型から内部のデータ型を抽出します。
14
+ *
15
+ * @template TPlainValue 対象となる PlainValue 型です。
16
+ */
17
+ export type $InferPlainValueData<TPlainValue> =
18
+ TPlainValue extends PlainValue<infer TData, any> ? TData : never;
19
+
20
+ /**
21
+ * PlainValue 型から入力データの型を抽出します。
22
+ *
23
+ * @template TPlainValue 対象となる PlainValue 型です。
24
+ */
25
+ export type $InferPlainValueInput<TPlainValue> =
26
+ TPlainValue extends PlainValue<any, infer TInput> ? TInput : never;
27
+
28
+ /**
29
+ * StreamValue 型から内部のチャンクデータ型を抽出します。
30
+ *
31
+ * @template TStreamValue 対象となる StreamValue 型です。
32
+ */
33
+ export type $InferStreamValueChunkData<TStreamValue> =
34
+ TStreamValue extends StreamValue<infer TChunkData, any> ? TChunkData : never;
35
+
36
+ /**
37
+ * StreamValue 型から入力チャンクデータの型を抽出します。
38
+ *
39
+ * @template TStreamValue 対象となる StreamValue 型です。
40
+ */
41
+ export type $InferStreamValueChunkInput<TStreamValue> =
42
+ TStreamValue extends StreamValue<any, infer TChunkInput> ? TChunkInput : never;
43
+
44
+ /**
45
+ * スキーマ付きの値であることを識別するためのブランドです。
46
+ *
47
+ * 同じライブラリーが複数読み込まれた環境でも認識できるようにグローバルシンボルを使用します。
48
+ */
49
+ export const VALUE_SCHEMA_BRAND: unique symbol = /* #__PURE__ */ Symbol.for(
50
+ "unikvs:VALUE_SCHEMA_BRAND",
51
+ );
52
+
53
+ /**
54
+ * スキーマ付きの値が扱うデータの種類です。
55
+ *
56
+ * - `"plain"`: プレーンな値のみを扱います。
57
+ * - `"stream"`: ストリーム形式の値のみを扱います。
58
+ * - `"any"`: プレーンな値とストリーム形式の値のどちらも扱います。
59
+ */
60
+ export type ValueSchemaKind = "plain" | "stream" | "any";
61
+
62
+ /**
63
+ * キーに対応する値のスキーマ情報です。
64
+ */
65
+ export type ValueSchemaInfo = {
66
+ /**
67
+ * 扱うデータの種類です。
68
+ */
69
+ readonly kind: ValueSchemaKind;
70
+
71
+ /**
72
+ * データの検証に使用するスキーマです。
73
+ */
74
+ readonly schema: GenericSchema;
75
+ };
76
+
77
+ // -------------------------------------------------------------------------------------------------。
78
+ //
79
+ // スキーマ定義。
80
+ //
81
+ // -------------------------------------------------------------------------------------------------。
82
+
83
+ /**
84
+ * 検証済みのオブジェクト形式のスキーマ定義です。
85
+ */
86
+ type UniKvsSchemaInfoRecord = Readonly<Record<string, ValueSchemaInfo>>;
87
+
88
+ /**
89
+ * 検証済みの配列形式のスキーマ定義です。
90
+ */
91
+ type UniKvsSchemaInfoEntries = readonly (readonly [GenericSchema, ValueSchemaInfo])[];
92
+
93
+ /**
94
+ * 検証済みのスキーマ定義です。
95
+ */
96
+ type UniKvsSchemaInfo = UniKvsSchemaInfoRecord | UniKvsSchemaInfoEntries;
97
+
98
+ // -------------------------------------------------------------------------------------------------。
99
+ //
100
+ // スキーマリゾルバー。
101
+ //
102
+ // -------------------------------------------------------------------------------------------------。
103
+
104
+ /**
105
+ * キーに対応する値のスキーマ情報を解決するインターフェースです。
106
+ */
107
+ export interface IValueSchemaResolver {
108
+ /**
109
+ * キーに対応する値のスキーマ情報を返します。
110
+ *
111
+ * @param key 解決するキーです。
112
+ *
113
+ * @returns 対応するスキーマ情報を返します。対応する定義がない場合は `undefined` を返します。
114
+ *
115
+ * @throws キーがどのキースキーマにも一致しない場合に `InvalidInputError` を投げます。
116
+ */
117
+ resolve(key: string): ValueSchemaInfo | undefined;
118
+ }
119
+
120
+ /**
121
+ * オブジェクト形式のスキーマ定義からスキーマ情報を解決します。
122
+ */
123
+ class RecordValueSchemaResolver implements IValueSchemaResolver {
124
+ readonly #entries: Map<string, ValueSchemaInfo>;
125
+
126
+ public constructor(entries: UniKvsSchemaInfoRecord) {
127
+ this.#entries = new Map(Object.entries(entries));
128
+ }
129
+
130
+ public resolve(key: string): ValueSchemaInfo | undefined {
131
+ return this.#entries.get(key);
132
+ }
133
+ }
134
+
135
+ /**
136
+ * 配列形式のスキーマ定義からスキーマ情報を解決します。
137
+ *
138
+ * キースキーマに最初に一致した定義を採用します。
139
+ */
140
+ class EntriesValueSchemaResolver implements IValueSchemaResolver {
141
+ readonly #entries: UniKvsSchemaInfoEntries;
142
+
143
+ readonly #keySchema: GenericSchema | undefined;
144
+
145
+ public constructor(entries: UniKvsSchemaInfoEntries) {
146
+ this.#entries = entries;
147
+ if (entries.length > 0) {
148
+ this.#keySchema = union(entries.map(([keySchema]) => keySchema));
149
+ }
150
+ }
151
+
152
+ public resolve(key: string): ValueSchemaInfo | undefined {
153
+ let resolved: ValueSchemaInfo | undefined;
154
+
155
+ for (const [keySchema, valueSchema] of this.#entries) {
156
+ const result = safeParse(keySchema, key);
157
+
158
+ if (result.success) {
159
+ resolved = valueSchema;
160
+ break;
161
+ }
162
+ }
163
+
164
+ if (resolved === undefined && this.#keySchema) {
165
+ const result = safeParse(this.#keySchema, key);
166
+
167
+ if (!result.success) {
168
+ throw new InvalidInputError({
169
+ value: key,
170
+ issues: result.issues,
171
+ });
172
+ }
173
+ }
174
+
175
+ return resolved;
176
+ }
177
+ }
178
+
179
+ /**
180
+ * 検証済みのスキーマ定義からスキーマリゾルバーを生成します。
181
+ *
182
+ * @param schema 検証済みのスキーマ定義です。
183
+ *
184
+ * @returns スキーマリゾルバーを返します。
185
+ */
186
+ export function createValueSchemaResolver(schema: UniKvsSchemaInfo): IValueSchemaResolver {
187
+ if (Array.isArray(schema)) {
188
+ return new EntriesValueSchemaResolver(schema);
189
+ }
190
+
191
+ return new RecordValueSchemaResolver(schema);
192
+ }