@valbuild/core 0.18.0 → 0.20.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.
- package/dist/declarations/src/index.d.ts +4 -1
- package/dist/declarations/src/initSchema.d.ts +2 -2
- package/dist/declarations/src/patch/deref.d.ts +2 -1
- package/dist/declarations/src/patch/operation.d.ts +8 -0
- package/dist/declarations/src/schema/richtext.d.ts +7 -6
- package/dist/declarations/src/schema/string.d.ts +6 -3
- package/dist/declarations/src/selector/future/index.d.ts +3 -3
- package/dist/declarations/src/selector/index.d.ts +3 -3
- package/dist/declarations/src/source/future/remote.d.ts +2 -2
- package/dist/declarations/src/source/index.d.ts +3 -3
- package/dist/declarations/src/source/richtext.d.ts +70 -54
- package/dist/{index-4abf3a1f.esm.js → index-5d1ab97c.esm.js} +1 -1
- package/dist/{index-a9235737.esm.js → index-bccf1907.esm.js} +1 -1
- package/dist/{ops-a2a295f8.esm.js → ops-22b624eb.esm.js} +107 -35
- package/dist/{ops-f3015423.cjs.dev.js → ops-b0a33248.cjs.dev.js} +106 -33
- package/dist/{ops-0d09f8ee.cjs.prod.js → ops-def81fc3.cjs.prod.js} +106 -33
- package/dist/valbuild-core.cjs.dev.js +202 -104
- package/dist/valbuild-core.cjs.prod.js +202 -104
- package/dist/valbuild-core.esm.js +184 -106
- package/expr/dist/valbuild-core-expr.esm.js +2 -2
- package/package.json +4 -1
- package/patch/dist/valbuild-core-patch.cjs.dev.js +6 -1
- package/patch/dist/valbuild-core-patch.cjs.prod.js +6 -1
- package/patch/dist/valbuild-core-patch.esm.js +8 -3
- package/src/getSha256.ts +8 -0
- package/src/index.ts +21 -5
- package/src/module.ts +33 -2
- package/src/patch/deref.ts +14 -1
- package/src/patch/operation.ts +10 -0
- package/src/patch/parse.ts +1 -0
- package/src/patch/patch.ts +3 -0
- package/src/schema/richtext.ts +19 -73
- package/src/schema/string.ts +14 -4
- package/src/schema/validation.test.ts +2 -2
- package/src/selector/future/index.ts +8 -4
- package/src/selector/index.ts +4 -4
- package/src/source/future/remote.ts +2 -2
- package/src/source/index.ts +2 -2
- package/src/source/richtext.test.ts +178 -0
- package/src/source/richtext.ts +295 -89
- package/tsconfig.json +2 -1
package/src/schema/richtext.ts
CHANGED
@@ -1,98 +1,44 @@
|
|
1
1
|
/* eslint-disable @typescript-eslint/no-unused-vars */
|
2
2
|
import { Schema, SerializedSchema } from ".";
|
3
|
-
import {
|
4
|
-
import { RichTextSource } from "../source/richtext";
|
3
|
+
import { RichTextSource, RichTextOptions } from "../source/richtext";
|
5
4
|
import { SourcePath } from "../val";
|
6
|
-
import {
|
7
|
-
ValidationError,
|
8
|
-
ValidationErrors,
|
9
|
-
} from "./validation/ValidationError";
|
5
|
+
import { ValidationErrors } from "./validation/ValidationError";
|
10
6
|
|
11
|
-
export type SerializedRichTextSchema = {
|
7
|
+
export type SerializedRichTextSchema = RichTextOptions & {
|
12
8
|
type: "richtext";
|
13
9
|
opt: boolean;
|
14
10
|
};
|
15
11
|
|
16
12
|
export class RichTextSchema<
|
17
|
-
|
13
|
+
O extends RichTextOptions,
|
14
|
+
Src extends RichTextSource<O> | null
|
18
15
|
> extends Schema<Src> {
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
}
|
23
|
-
if (src === null || src === undefined) {
|
24
|
-
return {
|
25
|
-
[path]: [
|
26
|
-
{ message: `Expected non-nullable got '${src}'` } as ValidationError,
|
27
|
-
],
|
28
|
-
} as ValidationErrors;
|
29
|
-
}
|
30
|
-
|
31
|
-
if (typeof src !== "object" && !Array.isArray(src)) {
|
32
|
-
return {
|
33
|
-
[path]: [
|
34
|
-
{
|
35
|
-
message: `Expected 'object' (that is not of an array) or 'string', got '${typeof src}'`,
|
36
|
-
value: src,
|
37
|
-
} as ValidationError,
|
38
|
-
],
|
39
|
-
} as ValidationErrors;
|
40
|
-
}
|
41
|
-
|
42
|
-
if (src[VAL_EXTENSION] !== "richtext") {
|
43
|
-
return {
|
44
|
-
[path]: [
|
45
|
-
{
|
46
|
-
message: `Expected _type key with value 'richtext' got '${src[VAL_EXTENSION]}'`,
|
47
|
-
value: src,
|
48
|
-
} as ValidationError,
|
49
|
-
],
|
50
|
-
} as ValidationErrors;
|
51
|
-
}
|
52
|
-
|
53
|
-
if (src.type !== "root") {
|
54
|
-
return {
|
55
|
-
[path]: [
|
56
|
-
{
|
57
|
-
message: `Expected type key with value 'root' got '${src.type}'`,
|
58
|
-
value: src,
|
59
|
-
} as ValidationError,
|
60
|
-
],
|
61
|
-
} as ValidationErrors;
|
62
|
-
}
|
63
|
-
|
64
|
-
if (typeof src.children !== "object" && !Array.isArray(src.children)) {
|
65
|
-
return {
|
66
|
-
[path]: [
|
67
|
-
{
|
68
|
-
message: `Expected children to be an array, but got '${src.type}'`,
|
69
|
-
value: src,
|
70
|
-
} as ValidationError,
|
71
|
-
],
|
72
|
-
} as ValidationErrors;
|
73
|
-
}
|
16
|
+
constructor(readonly options: O, readonly opt: boolean = false) {
|
17
|
+
super();
|
18
|
+
}
|
74
19
|
|
75
|
-
|
20
|
+
validate(path: SourcePath, src: Src): ValidationErrors {
|
21
|
+
return false; //TODO
|
76
22
|
}
|
23
|
+
|
77
24
|
assert(src: Src): boolean {
|
78
|
-
// TODO
|
79
|
-
return true;
|
25
|
+
return true; // TODO
|
80
26
|
}
|
81
27
|
|
82
|
-
optional(): Schema<RichTextSource | null> {
|
83
|
-
return new RichTextSchema(true);
|
28
|
+
optional(): Schema<RichTextSource<O> | null> {
|
29
|
+
return new RichTextSchema(this.options, true);
|
84
30
|
}
|
31
|
+
|
85
32
|
serialize(): SerializedSchema {
|
86
33
|
return {
|
87
34
|
type: "richtext",
|
88
35
|
opt: this.opt,
|
89
36
|
};
|
90
37
|
}
|
91
|
-
constructor(readonly opt: boolean = false) {
|
92
|
-
super();
|
93
|
-
}
|
94
38
|
}
|
95
39
|
|
96
|
-
export const richtext =
|
97
|
-
|
40
|
+
export const richtext = <O extends RichTextOptions>(
|
41
|
+
options?: O
|
42
|
+
): Schema<RichTextSource<O>> => {
|
43
|
+
return new RichTextSchema<O, RichTextSource<O>>(options ?? ({} as O));
|
98
44
|
};
|
package/src/schema/string.ts
CHANGED
@@ -12,10 +12,15 @@ export type SerializedStringSchema = {
|
|
12
12
|
type: "string";
|
13
13
|
options?: StringOptions;
|
14
14
|
opt: boolean;
|
15
|
+
raw: boolean;
|
15
16
|
};
|
16
17
|
|
17
18
|
export class StringSchema<Src extends string | null> extends Schema<Src> {
|
18
|
-
constructor(
|
19
|
+
constructor(
|
20
|
+
readonly options?: StringOptions,
|
21
|
+
readonly opt: boolean = false,
|
22
|
+
private readonly isRaw: boolean = false
|
23
|
+
) {
|
19
24
|
super();
|
20
25
|
}
|
21
26
|
|
@@ -40,8 +45,12 @@ export class StringSchema<Src extends string | null> extends Schema<Src> {
|
|
40
45
|
return typeof src === "string";
|
41
46
|
}
|
42
47
|
|
43
|
-
optional():
|
44
|
-
return new StringSchema<Src | null>(this.options, true);
|
48
|
+
optional(): StringSchema<Src | null> {
|
49
|
+
return new StringSchema<Src | null>(this.options, true, this.isRaw);
|
50
|
+
}
|
51
|
+
|
52
|
+
raw(): StringSchema<Src> {
|
53
|
+
return new StringSchema<Src>(this.options, this.opt, true);
|
45
54
|
}
|
46
55
|
|
47
56
|
serialize(): SerializedSchema {
|
@@ -49,12 +58,13 @@ export class StringSchema<Src extends string | null> extends Schema<Src> {
|
|
49
58
|
type: "string",
|
50
59
|
options: this.options,
|
51
60
|
opt: this.opt,
|
61
|
+
raw: this.isRaw,
|
52
62
|
};
|
53
63
|
}
|
54
64
|
}
|
55
65
|
|
56
66
|
export const string = <T extends string>(
|
57
67
|
options?: StringOptions
|
58
|
-
):
|
68
|
+
): StringSchema<T> => {
|
59
69
|
return new StringSchema(options);
|
60
70
|
};
|
@@ -254,9 +254,9 @@ const ValidationTestCases: {
|
|
254
254
|
// richtext
|
255
255
|
{
|
256
256
|
description: "basic richtext",
|
257
|
-
input: richtextVal
|
257
|
+
input: richtextVal`test`,
|
258
258
|
expected: false,
|
259
|
-
schema: richtext(),
|
259
|
+
schema: richtext({ bold: true }),
|
260
260
|
},
|
261
261
|
// TODO: more richtext cases
|
262
262
|
// TODO: union
|
@@ -24,7 +24,11 @@ import {
|
|
24
24
|
RemoteSource,
|
25
25
|
} from "../../source/future/remote";
|
26
26
|
import { FileSource } from "../../source/file";
|
27
|
-
import {
|
27
|
+
import {
|
28
|
+
AnyRichTextOptions,
|
29
|
+
RichText,
|
30
|
+
RichTextSource,
|
31
|
+
} from "../../source/richtext";
|
28
32
|
|
29
33
|
/**
|
30
34
|
* Selectors can be used to select parts of a Val module.
|
@@ -57,8 +61,8 @@ export type Selector<T extends Source> = Source extends T
|
|
57
61
|
: GenericSelector<Source, "Could not determine remote source">
|
58
62
|
: T extends FileSource
|
59
63
|
? FileSelector
|
60
|
-
: T extends RichTextSource
|
61
|
-
? RichText
|
64
|
+
: T extends RichTextSource<infer O>
|
65
|
+
? RichText<O>
|
62
66
|
: T extends SourceObject
|
63
67
|
? ObjectSelector<T>
|
64
68
|
: T extends SourceArray
|
@@ -83,7 +87,7 @@ export type SelectorSource =
|
|
83
87
|
| I18nSource<readonly string[], I18nCompatibleSource>
|
84
88
|
| RemoteSource<RemoteCompatibleSource>
|
85
89
|
| FileSource
|
86
|
-
| RichTextSource
|
90
|
+
| RichTextSource<AnyRichTextOptions>
|
87
91
|
| GenericSelector<Source>;
|
88
92
|
|
89
93
|
/**
|
package/src/selector/index.ts
CHANGED
@@ -10,14 +10,14 @@ import { Source, SourceArray, SourceObject, SourcePrimitive } from "../source";
|
|
10
10
|
import { Schema } from "../schema";
|
11
11
|
import type { A } from "ts-toolbelt";
|
12
12
|
import { FileSource } from "../source/file";
|
13
|
-
import { RichText, RichTextSource } from "../source/richtext";
|
13
|
+
import { RichText, RichTextOptions, RichTextSource } from "../source/richtext";
|
14
14
|
|
15
15
|
export type Selector<T extends Source> = Source extends T
|
16
16
|
? GenericSelector<T>
|
17
17
|
: T extends FileSource
|
18
18
|
? FileSelector
|
19
|
-
: T extends RichTextSource
|
20
|
-
? RichText
|
19
|
+
: T extends RichTextSource<infer O>
|
20
|
+
? RichText<O>
|
21
21
|
: T extends SourceObject
|
22
22
|
? ObjectSelector<T>
|
23
23
|
: T extends SourceArray
|
@@ -40,7 +40,7 @@ export type SelectorSource =
|
|
40
40
|
[key: string]: SelectorSource;
|
41
41
|
}
|
42
42
|
| FileSource
|
43
|
-
| RichTextSource
|
43
|
+
| RichTextSource<RichTextOptions>
|
44
44
|
| GenericSelector<Source>;
|
45
45
|
|
46
46
|
/**
|
@@ -1,7 +1,7 @@
|
|
1
1
|
import { SourcePrimitive, VAL_EXTENSION, PhantomType } from "..";
|
2
2
|
import { FileSource } from "../file";
|
3
3
|
import { I18nCompatibleSource, I18nSource } from "./i18n";
|
4
|
-
import { RichTextSource } from "../richtext";
|
4
|
+
import { AnyRichTextOptions, RichTextSource } from "../richtext";
|
5
5
|
|
6
6
|
/**
|
7
7
|
* Remote sources cannot include other remote sources.
|
@@ -10,7 +10,7 @@ export type RemoteCompatibleSource =
|
|
10
10
|
| SourcePrimitive
|
11
11
|
| RemoteObject
|
12
12
|
| RemoteArray
|
13
|
-
| RichTextSource
|
13
|
+
| RichTextSource<AnyRichTextOptions>
|
14
14
|
| FileSource
|
15
15
|
| I18nSource<string[], I18nCompatibleSource>;
|
16
16
|
export type RemoteObject = { [key in string]: RemoteCompatibleSource };
|
package/src/source/index.ts
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
import { FileSource } from "./file";
|
2
2
|
import { I18nSource, I18nCompatibleSource } from "./future/i18n";
|
3
3
|
import { RemoteSource, RemoteCompatibleSource } from "./future/remote";
|
4
|
-
import { RichTextSource } from "./richtext";
|
4
|
+
import { RichTextOptions, RichTextSource } from "./richtext";
|
5
5
|
|
6
6
|
export type Source =
|
7
7
|
| SourcePrimitive
|
@@ -10,7 +10,7 @@ export type Source =
|
|
10
10
|
| I18nSource<string[], I18nCompatibleSource>
|
11
11
|
| RemoteSource<RemoteCompatibleSource>
|
12
12
|
| FileSource
|
13
|
-
| RichTextSource
|
13
|
+
| RichTextSource<RichTextOptions>;
|
14
14
|
|
15
15
|
export type SourceObject = { [key in string]: Source } & {
|
16
16
|
// TODO: update these restricted parameters:
|
@@ -0,0 +1,178 @@
|
|
1
|
+
import { file } from "../source/file";
|
2
|
+
import { richtext } from "./richtext";
|
3
|
+
|
4
|
+
//MD to HTML
|
5
|
+
describe("richtext", () => {
|
6
|
+
test("basic h1", () => {
|
7
|
+
const r = richtext`# Title 1`;
|
8
|
+
expect(r.children).toStrictEqual([{ tag: "h1", children: ["Title 1"] }]);
|
9
|
+
});
|
10
|
+
|
11
|
+
test("basic complete", () => {
|
12
|
+
const r = richtext`# Title 1
|
13
|
+
## Title 2
|
14
|
+
|
15
|
+
Paragraph 1 2 3 4 5. Words *italic* **bold**
|
16
|
+
`;
|
17
|
+
expect(r.children).toStrictEqual([
|
18
|
+
{ tag: "h1", children: ["Title 1"] },
|
19
|
+
{ tag: "h2", children: ["Title 2"] },
|
20
|
+
{
|
21
|
+
tag: "p",
|
22
|
+
children: [
|
23
|
+
"Paragraph 1 2 3 4 5. Words ",
|
24
|
+
{ tag: "span", classes: ["italic"], children: ["italic"] },
|
25
|
+
" ",
|
26
|
+
{ tag: "span", classes: ["bold"], children: ["bold"] },
|
27
|
+
],
|
28
|
+
},
|
29
|
+
]);
|
30
|
+
});
|
31
|
+
|
32
|
+
test.skip("strong and emphasis merged spans", () => {
|
33
|
+
// TODO: currently we do not merge
|
34
|
+
const r = richtext`Which classes?
|
35
|
+
***All of them!***
|
36
|
+
`;
|
37
|
+
expect(r.children).toStrictEqual([
|
38
|
+
{
|
39
|
+
tag: "p",
|
40
|
+
children: [
|
41
|
+
"Which classes?\n",
|
42
|
+
{
|
43
|
+
tag: "span",
|
44
|
+
classes: ["italic", "bold"],
|
45
|
+
children: ["All of them!"],
|
46
|
+
},
|
47
|
+
],
|
48
|
+
},
|
49
|
+
]);
|
50
|
+
});
|
51
|
+
|
52
|
+
test("line through", () => {
|
53
|
+
// TODO: currently we do not merge
|
54
|
+
const r = richtext`~~line through~~`;
|
55
|
+
expect(r.children).toStrictEqual([
|
56
|
+
{
|
57
|
+
tag: "p",
|
58
|
+
children: [
|
59
|
+
{
|
60
|
+
tag: "span",
|
61
|
+
classes: ["line-through"],
|
62
|
+
children: ["line through"],
|
63
|
+
},
|
64
|
+
],
|
65
|
+
},
|
66
|
+
]);
|
67
|
+
});
|
68
|
+
|
69
|
+
test("2 paragraphs", () => {
|
70
|
+
const r = richtext`# Title 1
|
71
|
+
|
72
|
+
First paragraph
|
73
|
+
|
74
|
+
Second paragraph
|
75
|
+
`;
|
76
|
+
expect(r.children).toStrictEqual([
|
77
|
+
{ tag: "h1", children: ["Title 1"] },
|
78
|
+
{ tag: "p", children: ["First paragraph"] },
|
79
|
+
{ tag: "p", children: ["Second paragraph"] },
|
80
|
+
]);
|
81
|
+
});
|
82
|
+
|
83
|
+
test("lists", () => {
|
84
|
+
const r = richtext`# Title 1
|
85
|
+
|
86
|
+
A paragraph
|
87
|
+
|
88
|
+
A bullet list:
|
89
|
+
- bullet 1
|
90
|
+
- bullet 2
|
91
|
+
|
92
|
+
A numbered list:
|
93
|
+
1. number 1
|
94
|
+
2. number 2
|
95
|
+
|
96
|
+
A nested list:
|
97
|
+
- bullet 1:
|
98
|
+
1. number 1.1
|
99
|
+
2. number 1.2
|
100
|
+
- bullet 2:
|
101
|
+
- bullet 2.1
|
102
|
+
- bullet 2.2
|
103
|
+
`;
|
104
|
+
expect(r.children).toStrictEqual([
|
105
|
+
{ tag: "h1", children: ["Title 1"] },
|
106
|
+
{ tag: "p", children: ["A paragraph"] },
|
107
|
+
{ tag: "p", children: ["A bullet list:"] },
|
108
|
+
{
|
109
|
+
tag: "ul",
|
110
|
+
children: [
|
111
|
+
{ tag: "li", children: ["bullet 1"] },
|
112
|
+
{ tag: "li", children: ["bullet 2"] },
|
113
|
+
],
|
114
|
+
},
|
115
|
+
{ tag: "p", children: ["A numbered list:"] },
|
116
|
+
{
|
117
|
+
tag: "ol",
|
118
|
+
children: [
|
119
|
+
{ tag: "li", children: ["number 1"] },
|
120
|
+
{ tag: "li", children: ["number 2"] },
|
121
|
+
],
|
122
|
+
},
|
123
|
+
{ tag: "p", children: ["A nested list:"] },
|
124
|
+
{
|
125
|
+
tag: "ul",
|
126
|
+
children: [
|
127
|
+
{
|
128
|
+
tag: "li",
|
129
|
+
children: [
|
130
|
+
"bullet 1:",
|
131
|
+
{
|
132
|
+
tag: "ol",
|
133
|
+
children: [
|
134
|
+
{ tag: "li", children: ["number 1.1"] },
|
135
|
+
{ tag: "li", children: ["number 1.2"] },
|
136
|
+
],
|
137
|
+
},
|
138
|
+
],
|
139
|
+
},
|
140
|
+
{
|
141
|
+
tag: "li",
|
142
|
+
children: [
|
143
|
+
"bullet 2:",
|
144
|
+
{
|
145
|
+
tag: "ul",
|
146
|
+
children: [
|
147
|
+
{ tag: "li", children: ["bullet 2.1"] },
|
148
|
+
{ tag: "li", children: ["bullet 2.2"] },
|
149
|
+
],
|
150
|
+
},
|
151
|
+
],
|
152
|
+
},
|
153
|
+
],
|
154
|
+
},
|
155
|
+
]);
|
156
|
+
});
|
157
|
+
|
158
|
+
test("image", () => {
|
159
|
+
const r = richtext`# Title 1
|
160
|
+
|
161
|
+
Below we have an image block:
|
162
|
+
|
163
|
+
${file("/public/foo.png", {
|
164
|
+
width: 100,
|
165
|
+
height: 100,
|
166
|
+
sha256: "123",
|
167
|
+
})}`;
|
168
|
+
expect(r.children).toStrictEqual([
|
169
|
+
{ tag: "h1", children: ["Title 1"] },
|
170
|
+
{ tag: "p", children: ["Below we have an image block:"] },
|
171
|
+
{
|
172
|
+
_ref: "/public/foo.png",
|
173
|
+
_type: "file",
|
174
|
+
metadata: { width: 100, height: 100, sha256: "123" },
|
175
|
+
},
|
176
|
+
]);
|
177
|
+
});
|
178
|
+
});
|