@nerd-bible/valio 0.1.0 → 0.1.3
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/.github/workflows/publish.yml +4 -3
- package/README.md +2 -2
- package/package.json +6 -2
- package/src/containers.ts +47 -55
- package/tsconfig.json +1 -22
- package/publish.ts +0 -52
|
@@ -19,8 +19,9 @@ jobs:
|
|
|
19
19
|
fetch-depth: 0
|
|
20
20
|
- uses: actions/setup-node@v6
|
|
21
21
|
with:
|
|
22
|
-
node-version: lts/*
|
|
23
|
-
registry-url:
|
|
22
|
+
node-version: "lts/*"
|
|
23
|
+
registry-url: "https://registry.npmjs.org"
|
|
24
24
|
- run: npm install
|
|
25
25
|
- run: npm test
|
|
26
|
-
- run:
|
|
26
|
+
- run: npx -p @nerd-bible/config pkgWrite
|
|
27
|
+
- run: npm publish --verbose
|
package/README.md
CHANGED
|
@@ -35,8 +35,8 @@ const schema = v.number(); // Pipe<number, number>
|
|
|
35
35
|
|
|
36
36
|
expect(schema.decode(5)).toEqual({ success: true, output: 5 });
|
|
37
37
|
expect(schema.decodeAny("5")).toEqual({
|
|
38
|
-
|
|
39
|
-
|
|
38
|
+
success: false,
|
|
39
|
+
errors: { ".": [{ input: "5", message: "not type number" }] },
|
|
40
40
|
});
|
|
41
41
|
```
|
|
42
42
|
|
package/package.json
CHANGED
|
@@ -12,14 +12,18 @@
|
|
|
12
12
|
},
|
|
13
13
|
"scripts": {
|
|
14
14
|
"build": "tsc -p ./tsconfig.build.json",
|
|
15
|
-
"test": "node --test"
|
|
15
|
+
"test": "node --test",
|
|
16
|
+
"fmt": "prettier --check --ignore-path .gitignore .",
|
|
17
|
+
"fmt-fix": "npm run fmt -- --write"
|
|
16
18
|
},
|
|
19
|
+
"prettier": "@nerd-bible/config/prettier",
|
|
17
20
|
"devDependencies": {
|
|
21
|
+
"@nerd-bible/config": "^0.1.5",
|
|
18
22
|
"@types/node": "^25.3.3",
|
|
19
23
|
"expect": "^30.2.0",
|
|
20
24
|
"typescript": "^5.9.3"
|
|
21
25
|
},
|
|
22
|
-
"version": "0.1.
|
|
26
|
+
"version": "0.1.3",
|
|
23
27
|
"repository": {
|
|
24
28
|
"url": "https://github.com/nerd-bible/valio"
|
|
25
29
|
}
|
package/src/containers.ts
CHANGED
|
@@ -11,34 +11,32 @@ class ValioArray<T> extends p.Arrayish<any[], T[]> {
|
|
|
11
11
|
|
|
12
12
|
constructor(element: Pipe<any, T>) {
|
|
13
13
|
super(
|
|
14
|
-
new HalfPipe(
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
14
|
+
new HalfPipe("array", ValioArray.typeCheck, function parseAnyArr(
|
|
15
|
+
input: any[],
|
|
16
|
+
ctx: Context,
|
|
17
|
+
): Result<T[]> {
|
|
18
|
+
const output = new Array<T>(input.length);
|
|
19
|
+
let success = true;
|
|
20
20
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
21
|
+
const length = ctx.jsonPath.length;
|
|
22
|
+
for (let i = 0; i < input.length; i++) {
|
|
23
|
+
ctx.jsonPath[length] = i.toString();
|
|
24
|
+
const decoded = element.decode(input[i], ctx);
|
|
25
|
+
if (decoded.success) output[i] = decoded.output;
|
|
26
|
+
else success = false;
|
|
27
|
+
}
|
|
28
|
+
ctx.jsonPath.length = length;
|
|
29
29
|
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
},
|
|
41
|
-
),
|
|
30
|
+
if (!success) return { success, errors: ctx.errors };
|
|
31
|
+
return { success, output };
|
|
32
|
+
}),
|
|
33
|
+
new HalfPipe(`array<${element.o.name}>`, function isArrT(
|
|
34
|
+
v: any,
|
|
35
|
+
): v is T[] {
|
|
36
|
+
if (!ValioArray.typeCheck(v)) return false;
|
|
37
|
+
for (const e of v) if (!element.o.typeCheck(e)) return false;
|
|
38
|
+
return true;
|
|
39
|
+
}),
|
|
42
40
|
);
|
|
43
41
|
this.element = element;
|
|
44
42
|
}
|
|
@@ -60,37 +58,33 @@ class ValioRecord<K extends PropertyKey, V> extends Pipe<
|
|
|
60
58
|
|
|
61
59
|
constructor(keyPipe: Pipe<any, K>, valPipe: Pipe<any, V>) {
|
|
62
60
|
super(
|
|
63
|
-
new HalfPipe(
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
ctx: Context,
|
|
69
|
-
): Result<Record<K, V>> {
|
|
70
|
-
const output = {} as Record<K, V>;
|
|
61
|
+
new HalfPipe("object", ValioRecord.typeCheck, function anyToRecordKV(
|
|
62
|
+
input: Record<any, any>,
|
|
63
|
+
ctx: Context,
|
|
64
|
+
): Result<Record<K, V>> {
|
|
65
|
+
const output = {} as Record<K, V>;
|
|
71
66
|
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
} else {
|
|
82
|
-
success = false;
|
|
83
|
-
}
|
|
67
|
+
let success = true;
|
|
68
|
+
const length = ctx.jsonPath.length;
|
|
69
|
+
for (const key in input) {
|
|
70
|
+
ctx.jsonPath[length] = key;
|
|
71
|
+
const decodedKey = keyPipe.decode(key, ctx);
|
|
72
|
+
if (decodedKey.success) {
|
|
73
|
+
const decodedVal = valPipe.decode((input as any)[key], ctx);
|
|
74
|
+
if (decodedVal.success) {
|
|
75
|
+
output[decodedKey.output] = decodedVal.output;
|
|
84
76
|
} else {
|
|
85
77
|
success = false;
|
|
86
78
|
}
|
|
79
|
+
} else {
|
|
80
|
+
success = false;
|
|
87
81
|
}
|
|
88
|
-
|
|
82
|
+
}
|
|
83
|
+
ctx.jsonPath.length = length;
|
|
89
84
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
),
|
|
85
|
+
if (!success) return { success, errors: ctx.errors };
|
|
86
|
+
return { success, output };
|
|
87
|
+
}),
|
|
94
88
|
new HalfPipe(
|
|
95
89
|
`record<${keyPipe.o.name},${valPipe.o.name}>`,
|
|
96
90
|
function recordCheckV(v): v is Record<K, V> {
|
|
@@ -187,10 +181,8 @@ export class ValioObject<
|
|
|
187
181
|
|
|
188
182
|
constructor(shape: Shape, isLoose: boolean) {
|
|
189
183
|
super(
|
|
190
|
-
new HalfPipe(
|
|
191
|
-
|
|
192
|
-
ValioObject.typeCheck,
|
|
193
|
-
(data, ctx) => this.transformInput(data, ctx),
|
|
184
|
+
new HalfPipe("object", ValioObject.typeCheck, (data, ctx) =>
|
|
185
|
+
this.transformInput(data, ctx),
|
|
194
186
|
),
|
|
195
187
|
new HalfPipe(
|
|
196
188
|
`{${Object.entries(shape)
|
package/tsconfig.json
CHANGED
|
@@ -1,22 +1 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"rootDir": "${configDir}/src",
|
|
4
|
-
"outDir": "${configDir}/dist",
|
|
5
|
-
|
|
6
|
-
// Target bundlers and latest versions of Node
|
|
7
|
-
"target": "esnext",
|
|
8
|
-
"module": "esnext",
|
|
9
|
-
"moduleResolution": "bundler",
|
|
10
|
-
// Only drop imports with `type` modifier
|
|
11
|
-
"verbatimModuleSyntax": true,
|
|
12
|
-
|
|
13
|
-
// Best practices
|
|
14
|
-
"strict": true,
|
|
15
|
-
"skipLibCheck": true,
|
|
16
|
-
|
|
17
|
-
// Node supports TS now
|
|
18
|
-
"allowImportingTsExtensions": true,
|
|
19
|
-
"rewriteRelativeImportExtensions": true
|
|
20
|
-
},
|
|
21
|
-
"include": ["${configDir}/src/**/*"]
|
|
22
|
-
}
|
|
1
|
+
{ "extends": "@nerd-bible/config/tsconfig.json" }
|
package/publish.ts
DELETED
|
@@ -1,52 +0,0 @@
|
|
|
1
|
-
// This script allows using Git tags as the source of truth for versions rather
|
|
2
|
-
// than package.json.
|
|
3
|
-
import { execSync } from "node:child_process";
|
|
4
|
-
import { readFileSync, writeFileSync } from "node:fs";
|
|
5
|
-
|
|
6
|
-
const repoUrl = process.argv.slice(2).find((a) => !a.startsWith("--"));
|
|
7
|
-
if (!repoUrl) throw Error("Required arg: repo URL");
|
|
8
|
-
const dry = process.argv.includes("--dry");
|
|
9
|
-
|
|
10
|
-
function execGit(args: string, allowFailure = false) {
|
|
11
|
-
try {
|
|
12
|
-
return execSync(`git ${args}`, {
|
|
13
|
-
encoding: "utf8",
|
|
14
|
-
stdio: ["ignore", "pipe", "ignore"],
|
|
15
|
-
}).trim();
|
|
16
|
-
} catch (err) {
|
|
17
|
-
if (!allowFailure) throw err;
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
execGit("fetch --tags");
|
|
22
|
-
const tagCmd = "describe --tags --abbrev=0 --match='v[0-9]*.[0-9]*.[0-9]*'";
|
|
23
|
-
let version = execGit(`${tagCmd} --exact-match`, true);
|
|
24
|
-
|
|
25
|
-
if (!version) {
|
|
26
|
-
const lastVersion = execGit(tagCmd, true) ?? "v0.0.0";
|
|
27
|
-
console.log("No manual tag, bumping", lastVersion);
|
|
28
|
-
|
|
29
|
-
const split = lastVersion.split(".");
|
|
30
|
-
// Tags should only be missing for minor bumps.
|
|
31
|
-
const last = parseInt(split.pop()!) + 1;
|
|
32
|
-
version = [...split, last].join(".");
|
|
33
|
-
|
|
34
|
-
if (!dry) {
|
|
35
|
-
console.log("Tagging + pushing", version);
|
|
36
|
-
execGit(`tag ${version}`);
|
|
37
|
-
execGit("push --tags origin master");
|
|
38
|
-
}
|
|
39
|
-
} else {
|
|
40
|
-
console.log("Using manual tag", version);
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
if (!dry) {
|
|
44
|
-
console.log("Writing temporary package.json");
|
|
45
|
-
const pkg = JSON.parse(readFileSync("package.json", "utf8"));
|
|
46
|
-
pkg.version = version.substring(1);
|
|
47
|
-
pkg.repository = { url: repoUrl };
|
|
48
|
-
writeFileSync("package.json", JSON.stringify(pkg, null, 2));
|
|
49
|
-
|
|
50
|
-
console.log("Publishing to NPM", version);
|
|
51
|
-
execSync("npm publish --access public");
|
|
52
|
-
}
|