Skip to content

Commit ba4ca78

Browse files
authored
Merge pull request #3 from traversable/v0.0.1
✨(schema): adds support for setting config options globally
2 parents 664c509 + f8fd82f commit ba4ca78

29 files changed

+873
-1488
lines changed

.changeset/dirty-cars-chew.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@traversable/schema": patch
3+
---
4+
5+
✨(schema): implements `eq` combinator to support JSON schema `const` and `enum` nodes

.changeset/free-fans-stare.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@traversable/schema": patch
3+
---
4+
5+
✨(schema): adds support for setting configuration globally

.changeset/sharp-tips-sniff.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@traversable/schema": patch
3+
---
4+
5+
✨(schema): adds `Json.Functor`, `Json.is`, `Json.toString`

.changeset/twelve-apples-nail.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@traversable/schema": patch
3+
---
4+
5+
🐛(schema): fixes circular dependency, missing export

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
"describe:project": "./bin/describe.ts",
2525
"docs": "pnpm dlx tsx ./bin/docs.ts",
2626
"reboot": "./bin/reboot.ts",
27-
"test": "vitest run -- --skipTypes",
27+
"test": "vitest run -- --skipTypes && tsc -b tsconfig.json",
2828
"test:watch": "vitest watch",
2929
"workspace:new": "./bin/workspace-create.ts",
3030
"workspace:rm": "./bin/workspace-cleanup.ts"

packages/schema/src/_internal.ts

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
import * as T from './types.js'
2+
import * as fn from './function.js'
3+
import { function as isFunction } from './predicates.js'
4+
import { URI } from './uri.js'
5+
6+
export {
7+
never_ as never,
8+
unknown_ as unknown,
9+
any_ as any,
10+
void_ as void,
11+
null_ as null,
12+
undefined_ as undefined,
13+
bigint_ as bigint,
14+
symbol_ as symbol,
15+
boolean_ as boolean,
16+
number_ as number,
17+
string_ as string,
18+
//
19+
eq,
20+
array,
21+
record,
22+
optional,
23+
object_ as object,
24+
tuple,
25+
union,
26+
intersect,
27+
//
28+
type Leaf,
29+
type Free,
30+
type F,
31+
leafTags,
32+
Leaves,
33+
isLeaf,
34+
Functor,
35+
fold,
36+
unfold,
37+
}
38+
39+
interface never_ { tag: URI.never, def: never }
40+
interface unknown_ { tag: URI.unknown, def: unknown }
41+
interface any_ { tag: URI.any, def: any }
42+
interface void_ { tag: URI.void, def: void }
43+
interface null_ { tag: URI.null, def: null }
44+
interface undefined_ { tag: URI.undefined, def: undefined }
45+
interface bigint_ { tag: URI.bigint, def: bigint }
46+
interface symbol_ { tag: URI.symbol_, def: symbol }
47+
interface boolean_ { tag: URI.boolean, def: boolean }
48+
interface number_ { tag: URI.number, def: number }
49+
interface string_ { tag: URI.string, def: string }
50+
interface eq<T = unknown> { tag: URI.eq, def: T }
51+
interface array<T = unknown> { tag: URI.array, def: T }
52+
interface record<T = unknown> { tag: URI.record, def: T }
53+
interface optional<T = unknown> { tag: URI.optional, def: T }
54+
interface object_<T = unknown> { tag: URI.object, def: T }
55+
interface tuple<T = unknown> { tag: URI.tuple, def: T }
56+
interface union<T = unknown> { tag: URI.union, def: T }
57+
interface intersect<T = unknown> { tag: URI.intersect, def: T }
58+
59+
type Leaf = typeof Leaves[number]
60+
interface Free extends T.HKT { [-1]: F<this[0]> }
61+
62+
type F<_>
63+
= Leaf
64+
| eq<_>
65+
| array<_>
66+
| record<_>
67+
| optional<_>
68+
| object_<{ [x: string]: _ }>
69+
| tuple<readonly _[]>
70+
| union<readonly _[]>
71+
| intersect<readonly _[]>
72+
;
73+
74+
/**
75+
* ### {@link Fixpoint `AST.Fixpoint`}
76+
*
77+
*
78+
*/
79+
type Fixpoint
80+
= Leaf
81+
| eq<Fixpoint>
82+
| array<Fixpoint>
83+
| record<Fixpoint>
84+
| optional<Fixpoint>
85+
| object_<{ [x: string]: Fixpoint }>
86+
| tuple<readonly Fixpoint[]>
87+
| union<readonly Fixpoint[]>
88+
| intersect<readonly Fixpoint[]>
89+
;
90+
91+
const unknown_: unknown_ = { tag: URI.unknown, def: void 0 as unknown }
92+
const never_: never_ = { tag: URI.never, def: void 0 as never }
93+
const any_: any_ = { tag: URI.any, def: void 0 as any }
94+
const void_: void_ = { tag: URI.void, def: void 0 as void }
95+
const null_: null_ = { tag: URI.null, def: null }
96+
const undefined_: undefined_ = { tag: URI.undefined, def: void 0 as never }
97+
const symbol_: symbol_ = { tag: URI.symbol_, def: globalThis.Symbol() }
98+
const boolean_: boolean_ = { tag: URI.boolean, def: false }
99+
const number_: number_ = { tag: URI.number, def: 0 }
100+
const bigint_: bigint_ = { tag: URI.bigint, def: 0n }
101+
const string_: string_ = { tag: URI.string, def: '' }
102+
function eq<T>(x: T): eq<T> { return { tag: URI.eq, def: x } }
103+
function array<T>(x: T): array<T> { return { tag: URI.array, def: x } }
104+
function record<T>(x: T): record<T> { return { tag: URI.record, def: x } }
105+
function optional<T>(x: T): optional<T> { return { tag: URI.optional, def: x } }
106+
function tuple<T>(xs: T): tuple<T> { return { tag: URI.tuple, def: xs } }
107+
function object_<T>(xs: T): object_<T> { return { tag: URI.object, def: xs } }
108+
function union<T>(x: T): union<T> { return { tag: URI.union, def: x } }
109+
function intersect<T>(x: T): intersect<T> { return { tag: URI.intersect, def: x } }
110+
111+
const Leaves = [
112+
unknown_,
113+
never_,
114+
any_,
115+
void_,
116+
null_,
117+
undefined_,
118+
symbol_,
119+
boolean_,
120+
number_,
121+
bigint_,
122+
string_,
123+
]
124+
125+
const leafTags = Leaves.map((l) => l.tag)
126+
127+
const isLeaf = (u: unknown): u is Leaf =>
128+
isFunction(u) &&
129+
'tag' in u &&
130+
typeof u.tag === 'string' &&
131+
(<string[]>leafTags).includes(u.tag)
132+
133+
134+
const Functor: T.Functor<Free, Fixpoint> = {
135+
map(f) {
136+
return (x) => {
137+
switch (true) {
138+
default: return fn.exhaustive(x)
139+
case isLeaf(x): return x
140+
case x.tag === URI.eq: return eq(f(x.def))
141+
case x.tag === URI.array: return array(f(x.def))
142+
case x.tag === URI.record: return record(f(x.def))
143+
case x.tag === URI.optional: return optional(f(x.def))
144+
case x.tag === URI.object: return object_(fn.map(x.def, f))
145+
case x.tag === URI.tuple: return tuple(fn.map(x.def, f))
146+
case x.tag === URI.union: return union(fn.map(x.def, f))
147+
case x.tag === URI.intersect: return intersect(fn.map(x.def, f))
148+
}
149+
}
150+
}
151+
}
152+
153+
const fold = fn.cata(Functor)
154+
const unfold = fn.ana(Functor)

0 commit comments

Comments
 (0)