1/**
2 * Defines schema-backed domain models with separate database and JSON shapes.
3 *
4 * A model keeps one field declaration as the source of truth and derives
5 * variants for selecting, inserting, updating, and JSON encoding. This is useful
6 * when the database shape is not exactly the same as the public API shape, such
7 * as generated ids, audit timestamps, nullable columns, private fields, or
8 * values that need different encodings at different boundaries. Each generated
9 * variant is its own schema, so callers can validate or encode the shape that
10 * matches the operation they are performing.
11 *
12 * @stability unstable
13 * @since 4.0.0
14 */
15import type { Brand } from "../Brand.ts"
16import * as DateTime from "../DateTime.ts"
17import * as Effect from "../Effect.ts"
18import * as Uuid from "../internal/uuid.ts"
19import * as Option from "../Option.ts"
20import * as Predicate from "../Predicate.ts"
21import * as Schema from "../Schema.ts"
22import * as SchemaGetter from "../SchemaGetter.ts"
23import * as SchemaTransformation from "../SchemaTransformation.ts"
24import * as UndefinedOr from "../UndefinedOr.ts"
25import * as VariantSchema from "./VariantSchema.ts"
26
27const {
28 Class,
29 Field,
30 FieldExcept,
31 FieldOnly,
32 Struct,
33 Union,
34 extract,
35 fieldEvolve
36} = VariantSchema.make({
37 variants: ["select", "insert", "update", "json", "jsonCreate", "jsonUpdate"],
38 defaultVariant: "select"
39})
40
41/**
42 * Base shape of a variant model schema, including its fields and the generated
43 * database and JSON variant schemas.
44 *
45 * @stability unstable
46 * @category models
47 * @since 4.0.0
48 */
49export type Any = Schema.Top & {
50 readonly fields: Schema.Struct.Fields
51 readonly insert: Schema.Top
52 readonly update: Schema.Top
53 readonly json: Schema.Top
54 readonly jsonCreate: Schema.Top
55 readonly jsonUpdate: Schema.Top
56}
57
58/**
59 * Database-facing variant names generated for model schemas.
60 *
61 * @stability unstable
62 * @category models
63 * @since 4.0.0
64 */
65export type VariantsDatabase = "select" | "insert" | "update"
66
67/**
68 * JSON API-facing variant names generated for model schemas.
69 *
70 * @stability unstable
71 * @category models
72 * @since 4.0.0
73 */
74export type VariantsJson = "json" | "jsonCreate" | "jsonUpdate"
75
76/**
77 * @stability unstable
78 */
79export {
80 /**
81 * Creates domain model schemas with common database and JSON API variants.
82 *
83 * **Example** (Defining a variant model class)
84 *
85 * ```ts import.meta.vitest
86 * import { Schema } from "effect"
87 * import { Model } from "effect/schema"
88 *
89 * export const GroupId = Schema.Number.pipe(Schema.brand("GroupId"))
90 *
91 * export class Group extends Model.Class<Group>("Group")({
92 * id: Model.GeneratedByDb(GroupId),
93 * name: Schema.String,
94 * createdAt: Model.DateTimeInsertFromDate,
95 * updatedAt: Model.DateTimeUpdateFromDate
96 * }) {}
97 *
98 * // schema used for selects
99 * Group
100 *
101 * // schema used for inserts
102 * Group.insert
103 *
104 * // schema used for updates
105 * Group.update
106 *
107 * // schema used for json api
108 * Group.json
109 * Group.jsonCreate
110 * Group.jsonUpdate
111 *
112 * // you can also turn them into classes
113 * class GroupJson extends Schema.Class<GroupJson>("GroupJson")(Group.json) {
114 * get upperName() {
115 * return this.name.toUpperCase()
116 * }
117 * }
118 *
119 * [Schema.isSchema(Group), Schema.isSchema(Group.insert), Schema.isSchema(Group.json)] // => [true, true, true]
120 * ```
121 *
122 * @stability unstable
123 * @category constructors
124 * @since 4.0.0
125 */
126 Class,
127 /**
128 * Extracts a generated variant schema from a model or variant struct.
129 *
130 * @stability unstable
131 * @category converting
132 * @since 4.0.0
133 */
134 extract,
135 /**
136 * Creates a variant field from schemas keyed by variant name.
137 *
138 * @stability unstable
139 * @category constructors
140 * @since 4.0.0
141 */
142 Field,
143 /**
144 * Transforms schemas inside a variant field or plain schema by variant name.
145 *
146 * @stability unstable
147 * @category transforming
148 * @since 4.0.0
149 */
150 fieldEvolve,
151 /**
152 * Creates a variant field that applies a schema to every variant except the
153 * supplied keys.
154 *
155 * @stability unstable
156 * @category constructors
157 * @since 4.0.0
158 */
159 FieldExcept,
160 /**
161 * Creates a variant field that applies a schema only to the supplied variants.
162 *
163 * @stability unstable
164 * @category constructors
165 * @since 4.0.0
166 */
167 FieldOnly,
168 /**
169 * Creates a variant struct from model field definitions.
170 *
171 * @stability unstable
172 * @category constructors
173 * @since 4.0.0
174 */
175 Struct,
176 /**
177 * Creates a union over the default and generated variant schemas of multiple
178 * variant structs.
179 *
180 * @stability unstable
181 * @category constructors
182 * @since 4.0.0
183 */
184 Union
185}
186
187/**
188 * Returns the variant field definitions stored on a model or variant struct.
189 *
190 * @stability unstable
191 * @category getters
192 * @since 4.0.0
193 */
194export const fields: <A extends VariantSchema.Struct<any>>(self: A) => A[typeof VariantSchema.TypeId] =
195 VariantSchema.fields
196
197/**
198 * Marks a value as an explicit override for fields that otherwise use an
199 * overrideable default.
200 *
201 * @stability unstable
202 * @category constructors
203 * @since 4.0.0
204 */
205export const Override: <A>(value: A) => A & Brand<"Override"> = VariantSchema.Override
206
207/**
208 * Variant field type for a database-generated column that is present in read
209 * variants only.
210 *
211 * **Details**
212 *
213 * The field is included in `select` and `json`, and omitted from `insert`,
214 * `update`, `jsonCreate`, and `jsonUpdate`.
215 *
216 * @see {@link Field} for generated columns that need a custom variant set, such
217 * as primary keys used in update payloads.
218 *
219 * @stability unstable
220 * @category schemas
221 * @since 4.0.0
222 */
223export interface GeneratedByDb<S extends Schema.Top> extends
224 VariantSchema.Field<{
225 readonly select: S
226 readonly json: S
227 }>
228{}
229
230/**
231 * Creates a variant field for a database-generated column available in read
232 * variants only.
233 *
234 * **Details**
235 *
236 * The field is included in `select` and `json`, and omitted from `insert`,
237 * `update`, `jsonCreate`, and `jsonUpdate`.
238 *
239 * @see {@link Field} for generated columns that need a custom variant set, such
240 * as primary keys used in update payloads.
241 *
242 * @stability unstable
243 * @category schemas
244 * @since 4.0.0
245 */
246export const GeneratedByDb = <S extends Schema.Top>(
247 schema: S
248): GeneratedByDb<S> =>
249 Field({
250 select: schema,
251 json: schema
252 })
253
254/**
255 * Variant field type for an application-generated value that is present in
256 * database variants and read JSON, but omitted from JSON create and update
257 * variants.
258 *
259 * @stability unstable
260 * @category schemas
261 * @since 4.0.0
262 */
263export interface GeneratedByApp<S extends Schema.Top> extends
264 VariantSchema.Field<{
265 readonly select: S
266 readonly insert: S
267 readonly update: S
268 readonly json: S
269 }>
270{}
271
272/**
273 * A field that represents a value generated by the application and present in database
274 * variants and the read JSON variant, but omitted from JSON create and update
275 * variants.
276 *
277 * @stability unstable
278 * @category schemas
279 * @since 4.0.0
280 */
281export const GeneratedByApp = <S extends Schema.Top>(schema: S): GeneratedByApp<S> =>
282 Field({
283 select: schema,
284 insert: schema,
285 update: schema,
286 json: schema
287 })
288
289/**
290 * Variant field type for a sensitive value that is available to database variants
291 * and omitted from all JSON variants.
292 *
293 * @stability unstable
294 * @category schemas
295 * @since 4.0.0
296 */
297export interface Sensitive<S extends Schema.Top> extends
298 VariantSchema.Field<{
299 readonly select: S
300 readonly insert: S
301 readonly update: S
302 }>
303{}
304
305/**
306 * A field that represents a sensitive value that should not be exposed in the
307 * JSON variants.
308 *
309 * @stability unstable
310 * @category schemas
311 * @since 4.0.0
312 */
313export const Sensitive = <S extends Schema.Top>(schema: S): Sensitive<S> =>
314 Field({
315 select: schema,
316 insert: schema,
317 update: schema
318 })
319
320/**
321 * Schema type for an optional object key whose encoded value may be missing or
322 * null and whose decoded value is an `Option`.
323 *
324 * @stability unstable
325 * @category schemas
326 * @since 4.0.0
327 */
328export interface optionalOption<S extends Schema.Constraint>
329 extends Schema.decodeTo<Schema.Option<Schema.toType<S>>, Schema.optionalKey<Schema.NullOr<S>>>
330{}
331
332/**
333 * Creates a schema for optional keys that decodes missing or null encoded values
334 * through `Option` and encodes `Option` values back to optional nullable keys.
335 *
336 * @stability unstable
337 * @category schemas
338 * @since 4.0.0
339 */
340export const optionalOption = <S extends Schema.Constraint>(schema: S): optionalOption<S> =>
341 Schema.optionalKey(Schema.NullOr(schema)).pipe(
342 Schema.decodeTo(
343 Schema.Option(Schema.toType(schema)),
344 SchemaTransformation.transformOptional<Option.Option<S["Type"]>, S["Type"] | null>({
345 decode: (oe) => oe.pipe(Option.filter(Predicate.isNotNull), Option.some),
346 encode: Option.flatten
347 }) as any
348 )
349 )
350
351/**
352 * Convert a field to one that is optional for all variants.
353 *
354 * **Details**
355 *
356 * For the database variants, it will accept `null`able values.
357 * For the JSON variants, it will also accept missing keys.
358 *
359 * @stability unstable
360 * @category schemas
361 * @since 4.0.0
362 */
363export interface FieldOption<S extends Schema.Top> extends
364 VariantSchema.Field<{
365 readonly select: Schema.OptionFromNullOr<S>
366 readonly insert: Schema.OptionFromNullOr<S>
367 readonly update: Schema.OptionFromNullOr<S>
368 readonly json: optionalOption<S>
369 readonly jsonCreate: optionalOption<S>
370 readonly jsonUpdate: optionalOption<S>
371 }>
372{}
373
374/**
375 * Converts a field to one that is optional for all variants.
376 *
377 * **Details**
378 *
379 * For the database variants, it will accept `null`able values.
380 * For the JSON variants, it will also accept missing keys.
381 *
382 * @stability unstable
383 * @category schemas
384 * @since 4.0.0
385 */
386export const FieldOption: <Field extends VariantSchema.Field<any> | Schema.Top>(
387 self: Field
388) => Field extends Schema.Top ? FieldOption<Field>
389 : Field extends VariantSchema.Field<infer S> ? VariantSchema.Field<
390 {
391 readonly [K in keyof S]: S[K] extends Schema.Top ? K extends VariantsDatabase ? Schema.OptionFromNullOr<S[K]> :
392 optionalOption<S[K]>
393 : never
394 }
395 > :
396 never = fieldEvolve({
397 select: UndefinedOr.map(Schema.OptionFromNullOr),
398 insert: UndefinedOr.map(Schema.OptionFromNullOr),
399 update: UndefinedOr.map(Schema.OptionFromNullOr),
400 json: UndefinedOr.map(optionalOption),
401 jsonCreate: UndefinedOr.map(optionalOption),
402 jsonUpdate: UndefinedOr.map(optionalOption)
403 } as any) as any
404
405/**
406 * Variant field type for SQLite booleans stored as `0 | 1` in database variants
407 * and exposed as `boolean` in JSON variants.
408 *
409 * @stability unstable
410 * @category schemas
411 * @since 4.0.0
412 */
413export interface BooleanSqlite extends
414 VariantSchema.Field<{
415 readonly select: Schema.BooleanFromBit
416 readonly insert: Schema.BooleanFromBit
417 readonly update: Schema.BooleanFromBit
418 readonly json: Schema.Boolean
419 readonly jsonCreate: Schema.Boolean
420 readonly jsonUpdate: Schema.Boolean
421 }>
422{}
423
424/**
425 * Schema for sqlite booleans that are represented as `0 | 1` in database
426 * variants and `boolean` in JSON variants.
427 *
428 * @stability unstable
429 * @category schemas
430 * @since 4.0.0
431 */
432export const BooleanSqlite: BooleanSqlite = Field({
433 select: Schema.BooleanFromBit,
434 insert: Schema.BooleanFromBit,
435 update: Schema.BooleanFromBit,
436 json: Schema.Boolean,
437 jsonCreate: Schema.Boolean,
438 jsonUpdate: Schema.Boolean
439})
440
441/**
442 * Schema type for a `DateTime.Utc` date-only value encoded as a `YYYY-MM-DD`
443 * string.
444 *
445 * @stability unstable
446 * @category schemas
447 * @since 4.0.0
448 */
449export interface Date extends Schema.decodeTo<Schema.instanceOf<DateTime.Utc>, Schema.String> {}
450
451/**
452 * Schema for a `DateTime.Utc` that is serialized as a date string in the
453 * format `YYYY-MM-DD`.
454 *
455 * @stability unstable
456 * @category schemas
457 * @since 4.0.0
458 */
459export const Date: Date = Schema.String.pipe(
460 Schema.decodeTo(Schema.DateTimeUtc, {
461 decode: SchemaGetter.map(SchemaGetter.dateTimeUtcFromInput(), DateTime.removeTime),
462 encode: SchemaGetter.transform(DateTime.formatIsoDate)
463 })
464)
465
466/**
467 * Schema for an overrideable UTC date-only field whose constructor default is
468 * the current date with the time component removed.
469 *
470 * @stability unstable
471 * @category schemas
472 * @since 4.0.0
473 */
474export const DateWithNow = VariantSchema.Overrideable(Date, {
475 defaultValue: Effect.map(DateTime.now, DateTime.removeTime)
476})
477
478/**
479 * Schema for an overrideable UTC date-time field encoded as a string and
480 * defaulted to the current `DateTime.Utc`.
481 *
482 * @stability unstable
483 * @category schemas
484 * @since 4.0.0
485 */
486export const DateTimeWithNow = VariantSchema.Overrideable(Schema.DateTimeUtcFromString, {
487 defaultValue: DateTime.now
488})
489
490/**
491 * Schema for an overrideable UTC date-time field encoded as a JavaScript `Date`
492 * and defaulted to the current `DateTime.Utc`.
493 *
494 * @stability unstable
495 * @category schemas
496 * @since 4.0.0
497 */
498export const DateTimeFromDateWithNow = VariantSchema.Overrideable(Schema.DateTimeUtcFromDate, {
499 defaultValue: DateTime.now
500})
501
502/**
503 * Schema for an overrideable UTC date-time field encoded as milliseconds and
504 * defaulted to the current `DateTime.Utc`.
505 *
506 * @stability unstable
507 * @category schemas
508 * @since 4.0.0
509 */
510export const DateTimeFromNumberWithNow = VariantSchema.Overrideable(Schema.DateTimeUtcFromMillis, {
511 defaultValue: DateTime.now
512})
513
514/**
515 * Variant field type for a UTC date-time stored as a string, defaulted to the
516 * current time on insert, available for selection, and omitted from updates.
517 *
518 * @stability unstable
519 * @category schemas
520 * @since 4.0.0
521 */
522export interface DateTimeInsert extends
523 VariantSchema.Field<{
524 readonly select: Schema.DateTimeUtcFromString
525 readonly insert: VariantSchema.Overrideable<Schema.DateTimeUtcFromString>
526 readonly json: Schema.DateTimeUtcFromString
527 }>
528{}
529
530/**
531 * A field that represents a date-time value that is inserted as the current
532 * `DateTime.Utc`. It is serialized as a string for the database.
533 *
534 * **Details**
535 *
536 * It is omitted from updates and is available for selection.
537 *
538 * @stability unstable
539 * @category schemas
540 * @since 4.0.0
541 */
542export const DateTimeInsert: DateTimeInsert = Field({
543 select: Schema.DateTimeUtcFromString,
544 insert: DateTimeWithNow,
545 json: Schema.DateTimeUtcFromString
546})
547
548/**
549 * Variant field type for a UTC date-time stored as a JavaScript `Date` in
550 * database variants, encoded as a string for JSON, and defaulted on insert.
551 *
552 * @stability unstable
553 * @category schemas
554 * @since 4.0.0
555 */
556export interface DateTimeInsertFromDate extends
557 VariantSchema.Field<{
558 readonly select: Schema.DateTimeUtcFromDate
559 readonly insert: VariantSchema.Overrideable<Schema.DateTimeUtcFromDate>
560 readonly json: Schema.DateTimeUtcFromString
561 }>
562{}
563
564/**
565 * A field that represents a date-time value that is inserted as the current
566 * `DateTime.Utc`. It is serialized as a `Date` for the database.
567 *
568 * **Details**
569 *
570 * It is omitted from updates and is available for selection.
571 *
572 * @stability unstable
573 * @category schemas
574 * @since 4.0.0
575 */
576export const DateTimeInsertFromDate: DateTimeInsertFromDate = Field({
577 select: Schema.DateTimeUtcFromDate,
578 insert: DateTimeFromDateWithNow,
579 json: Schema.DateTimeUtcFromString
580})
581
582/**
583 * Variant field type for a UTC date-time encoded as milliseconds and defaulted to
584 * the current time on insert.
585 *
586 * @stability unstable
587 * @category schemas
588 * @since 4.0.0
589 */
590export interface DateTimeInsertFromNumber extends
591 VariantSchema.Field<{
592 readonly select: Schema.DateTimeUtcFromMillis
593 readonly insert: VariantSchema.Overrideable<Schema.DateTimeUtcFromMillis>
594 readonly json: Schema.DateTimeUtcFromMillis
595 }>
596{}
597
598/**
599 * A field that represents a date-time value that is inserted as the current
600 * `DateTime.Utc`. It is serialized as a `number`.
601 *
602 * **Details**
603 *
604 * It is omitted from updates and is available for selection.
605 *
606 * @stability unstable
607 * @category schemas
608 * @since 4.0.0
609 */
610export const DateTimeInsertFromNumber: DateTimeInsertFromNumber = Field({
611 select: Schema.DateTimeUtcFromMillis,
612 insert: DateTimeFromNumberWithNow,
613 json: Schema.DateTimeUtcFromMillis
614})
615
616/**
617 * Variant field type for a UTC date-time stored as a string and defaulted to the
618 * current time on both inserts and updates.
619 *
620 * @stability unstable
621 * @category schemas
622 * @since 4.0.0
623 */
624export interface DateTimeUpdate extends
625 VariantSchema.Field<{
626 readonly select: Schema.DateTimeUtcFromString
627 readonly insert: VariantSchema.Overrideable<Schema.DateTimeUtcFromString>
628 readonly update: VariantSchema.Overrideable<Schema.DateTimeUtcFromString>
629 readonly json: Schema.DateTimeUtcFromString
630 }>
631{}
632
633/**
634 * A field that represents a date-time value that is updated as the current
635 * `DateTime.Utc`. It is serialized as a string for the database.
636 *
637 * **Details**
638 *
639 * It is set to the current `DateTime.Utc` on updates and inserts and is
640 * available for selection.
641 *
642 * @stability unstable
643 * @category schemas
644 * @since 4.0.0
645 */
646export const DateTimeUpdate: DateTimeUpdate = Field({
647 select: Schema.DateTimeUtcFromString,
648 insert: DateTimeWithNow,
649 update: DateTimeWithNow,
650 json: Schema.DateTimeUtcFromString
651})
652
653/**
654 * Variant field type for a UTC date-time stored as a JavaScript `Date` in
655 * database variants, encoded as a string for JSON, and defaulted on inserts and
656 * updates.
657 *
658 * @stability unstable
659 * @category schemas
660 * @since 4.0.0
661 */
662export interface DateTimeUpdateFromDate extends
663 VariantSchema.Field<{
664 readonly select: Schema.DateTimeUtcFromDate
665 readonly insert: VariantSchema.Overrideable<Schema.DateTimeUtcFromDate>
666 readonly update: VariantSchema.Overrideable<Schema.DateTimeUtcFromDate>
667 readonly json: Schema.DateTimeUtcFromString
668 }>
669{}
670
671/**
672 * A field that represents a date-time value that is updated as the current
673 * `DateTime.Utc`. It is serialized as a `Date` for the database.
674 *
675 * **Details**
676 *
677 * It is set to the current `DateTime.Utc` on updates and inserts and is
678 * available for selection.
679 *
680 * @stability unstable
681 * @category schemas
682 * @since 4.0.0
683 */
684export const DateTimeUpdateFromDate: DateTimeUpdateFromDate = Field({
685 select: Schema.DateTimeUtcFromDate,
686 insert: DateTimeFromDateWithNow,
687 update: DateTimeFromDateWithNow,
688 json: Schema.DateTimeUtcFromString
689})
690
691/**
692 * Variant field type for a UTC date-time encoded as milliseconds and defaulted to
693 * the current time on both inserts and updates.
694 *
695 * @stability unstable
696 * @category schemas
697 * @since 4.0.0
698 */
699export interface DateTimeUpdateFromNumber extends
700 VariantSchema.Field<{
701 readonly select: Schema.DateTimeUtcFromMillis
702 readonly insert: VariantSchema.Overrideable<Schema.DateTimeUtcFromMillis>
703 readonly update: VariantSchema.Overrideable<Schema.DateTimeUtcFromMillis>
704 readonly json: Schema.DateTimeUtcFromMillis
705 }>
706{}
707
708/**
709 * A field that represents a date-time value that is updated as the current
710 * `DateTime.Utc`. It is serialized as a `number`.
711 *
712 * **Details**
713 *
714 * It is set to the current `DateTime.Utc` on updates and inserts and is
715 * available for selection.
716 *
717 * @stability unstable
718 * @category schemas
719 * @since 4.0.0
720 */
721export const DateTimeUpdateFromNumber: DateTimeUpdateFromNumber = Field({
722 select: Schema.DateTimeUtcFromMillis,
723 insert: DateTimeFromNumberWithNow,
724 update: DateTimeFromNumberWithNow,
725 json: Schema.DateTimeUtcFromMillis
726})
727
728/**
729 * Variant field type for a JSON value stored as text in database variants and
730 * exposed through the supplied schema in JSON variants.
731 *
732 * @stability unstable
733 * @category schemas
734 * @since 4.0.0
735 */
736export interface JsonFromString<S extends Schema.Top> extends
737 VariantSchema.Field<{
738 readonly select: Schema.fromJsonString<S>
739 readonly insert: Schema.fromJsonString<S>
740 readonly update: Schema.fromJsonString<S>
741 readonly json: S
742 readonly jsonCreate: S
743 readonly jsonUpdate: S
744 }>
745{}
746
747/**
748 * A field that represents a JSON value stored as text in the database.
749 *
750 * **Details**
751 *
752 * The "json" variants will use the object schema directly.
753 *
754 * @stability unstable
755 * @category schemas
756 * @since 4.0.0
757 */
758export const JsonFromString = <S extends Schema.Top>(
759 schema: S
760): JsonFromString<S> => {
761 const parsed = Schema.fromJsonString(Schema.toCodecJson(schema)) as any
762 return Field({
763 select: parsed,
764 insert: parsed,
765 update: parsed,
766 json: schema,
767 jsonCreate: schema,
768 jsonUpdate: schema
769 })
770}
771
772/**
773 * Variant field type for a branded binary UUID v4 value whose insert variant
774 * generates a UUID by default.
775 *
776 * @stability unstable
777 * @category schemas
778 * @since 4.0.0
779 */
780export interface UuidV4BytesInsert<B extends string> extends
781 VariantSchema.Field<{
782 readonly select: Schema.brand<Schema.instanceOf<Uint8Array<ArrayBuffer>>, B>
783 readonly insert: Schema.withConstructorDefault<Schema.brand<Schema.instanceOf<Uint8Array<ArrayBuffer>>, B>>
784 readonly update: Schema.brand<Schema.instanceOf<Uint8Array<ArrayBuffer>>, B>
785 readonly json: Schema.brand<Schema.instanceOf<Uint8Array<ArrayBuffer>>, B>
786 }>
787{}
788
789/**
790 * Schema for binary `Uint8Array` values backed by an `ArrayBuffer`.
791 *
792 * @stability unstable
793 * @category schemas
794 * @since 4.0.0
795 */
796export const Uint8Array: Schema.instanceOf<Uint8Array<ArrayBuffer>> = Schema.Uint8Array as Schema.instanceOf<
797 globalThis.Uint8Array<ArrayBuffer>
798>
799
800/**
801 * Adds a constructor default that generates a binary UUID v4 for a branded
802 * `Uint8Array` schema.
803 *
804 * @stability unstable
805 * @category schemas
806 * @since 4.0.0
807 */
808export const UuidV4BytesWithGenerate = <B extends string>(
809 schema: Schema.brand<Schema.instanceOf<Uint8Array<ArrayBuffer>>, B>
810): Schema.withConstructorDefault<Schema.brand<Schema.instanceOf<Uint8Array<ArrayBuffer>>, B>> =>
811 schema.pipe(Schema.withConstructorDefault(Effect.sync(() => Uuid.v4Bytes())))
812
813/**
814 * A field that represents a binary UUID v4 that is generated on inserts.
815 *
816 * @stability unstable
817 * @category schemas
818 * @since 4.0.0
819 */
820export const UuidV4BytesInsert = <const B extends string>(
821 schema: Schema.brand<Schema.instanceOf<Uint8Array<ArrayBuffer>>, B>
822): UuidV4BytesInsert<B> =>
823 Field({
824 select: schema,
825 insert: UuidV4BytesWithGenerate(schema),
826 update: schema,
827 json: schema
828 })
829
830/**
831 * Variant field type for a branded string UUID v4 value whose insert variant
832 * generates a UUID by default.
833 *
834 * @stability unstable
835 * @category schemas
836 * @since 4.0.0
837 */
838export interface UuidV4Insert<B extends string> extends
839 VariantSchema.Field<{
840 readonly select: Schema.brand<Schema.String, B>
841 readonly insert: Schema.withConstructorDefault<Schema.brand<Schema.String, B>>
842 readonly update: Schema.brand<Schema.String, B>
843 readonly json: Schema.brand<Schema.String, B>
844 }>
845{}
846
847/**
848 * Adds a constructor default that generates a string UUID v4.
849 *
850 * @stability unstable
851 * @category schemas
852 * @since 4.0.0
853 */
854export const UuidV4WithGenerate = <B extends string>(
855 schema: Schema.brand<Schema.String, B>
856): Schema.withConstructorDefault<Schema.brand<Schema.String, B>> =>
857 schema.pipe(Schema.withConstructorDefault(Effect.sync(Uuid.v4String)))
858
859/**
860 * A field that represents a string UUID v4 that is generated on inserts.
861 *
862 * @stability unstable
863 * @category schemas
864 * @since 4.0.0
865 */
866export const UuidV4Insert = <const B extends string>(
867 schema: Schema.brand<Schema.String, B>
868): UuidV4Insert<B> =>
869 Field({
870 select: schema,
871 insert: UuidV4WithGenerate(schema),
872 update: schema,
873 json: schema
874 })
875
876/**
877 * Variant field type for a branded string UUID v7 value whose insert variant
878 * generates a UUID by default.
879 *
880 * @stability unstable
881 * @category schemas
882 * @since 4.0.0
883 */
884export interface UuidV7Insert<B extends string> extends
885 VariantSchema.Field<{
886 readonly select: Schema.brand<Schema.String, B>
887 readonly insert: Schema.withConstructorDefault<Schema.brand<Schema.String, B>>
888 readonly update: Schema.brand<Schema.String, B>
889 readonly json: Schema.brand<Schema.String, B>
890 }>
891{}
892
893/**
894 * Adds a constructor default that generates a string UUID v7.
895 *
896 * @stability unstable
897 * @category schemas
898 * @since 4.0.0
899 */
900export const UuidV7WithGenerate = <B extends string>(
901 schema: Schema.brand<Schema.String, B>
902): Schema.withConstructorDefault<Schema.brand<Schema.String, B>> =>
903 schema.pipe(
904 Schema.withConstructorDefault(
905 Effect.clockWith((clock) => Effect.succeed(Uuid.v7String(clock.currentTimeMillisUnsafe())))
906 )
907 )
908
909/**
910 * A field that represents a string UUID v7 that is generated on inserts.
911 *
912 * @stability unstable
913 * @category schemas
914 * @since 4.0.0
915 */
916export const UuidV7Insert = <const B extends string>(
917 schema: Schema.brand<Schema.String, B>
918): UuidV7Insert<B> =>
919 Field({
920 select: schema,
921 insert: UuidV7WithGenerate(schema),
922 update: schema,
923 json: schema
924 })