@systemfsoftware/effect-schema-vite 1.1.7 → 1.3.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/effect-schema-vite.d.ts +26 -0
- package/dist/index.mjs +44 -34
- package/package.json +5 -5
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import { Plugin as Plugin_2 } from 'vite';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* Vite plugin that walks the consumer's `src/` directory, finds every
|
|
5
|
+
* exported Effect `Schema`, and auto-injects `ruleOfSchemas` round-trip
|
|
6
|
+
* property tests for each one.
|
|
7
|
+
*
|
|
8
|
+
* @example
|
|
9
|
+
* ```ts
|
|
10
|
+
* // vitest.config.ts
|
|
11
|
+
* import { inlineSchemaTests } from '@systemfsoftware/effect-schema-vite'
|
|
12
|
+
*
|
|
13
|
+
* export default defineConfig({
|
|
14
|
+
* plugins: [inlineSchemaTests()],
|
|
15
|
+
* })
|
|
16
|
+
* ```
|
|
17
|
+
*/
|
|
18
|
+
export declare const inlineSchemaTests: (options?: InlineSchemaTestsOptions) => Plugin_2;
|
|
19
|
+
|
|
20
|
+
/** @since 0.1.0 */
|
|
21
|
+
export declare interface InlineSchemaTestsOptions {
|
|
22
|
+
/** Directory to scan for schema files, relative to Vite root. Default: `"src"`. */
|
|
23
|
+
dir?: string;
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
export { }
|
package/dist/index.mjs
CHANGED
|
@@ -45,7 +45,13 @@ function findExportedSchemaNames(source) {
|
|
|
45
45
|
for (const node of result.program.body) {
|
|
46
46
|
if (node.type !== "ExportNamedDeclaration") continue;
|
|
47
47
|
const decl = node.declaration;
|
|
48
|
-
if (!decl
|
|
48
|
+
if (!decl) continue;
|
|
49
|
+
if (decl.type === "ClassDeclaration") {
|
|
50
|
+
const className = decl.id?.name;
|
|
51
|
+
if (typeof className === "string" && !className.startsWith("_") && extendsSchemaClass(decl.superClass)) names.push(className);
|
|
52
|
+
continue;
|
|
53
|
+
}
|
|
54
|
+
if (decl.type !== "VariableDeclaration") continue;
|
|
49
55
|
for (const declarator of decl.declarations) {
|
|
50
56
|
const id = declarator.id;
|
|
51
57
|
if (id.type !== "Identifier") continue;
|
|
@@ -63,51 +69,55 @@ function findExportedSchemaNames(source) {
|
|
|
63
69
|
}
|
|
64
70
|
}
|
|
65
71
|
function typeRefContainsSchema(t) {
|
|
66
|
-
if (!t
|
|
67
|
-
|
|
68
|
-
if (
|
|
69
|
-
const tn = node.typeName;
|
|
70
|
-
if (tn.type === "Identifier" && typeof tn.name === "string" && tn.name.includes("Schema")) return true;
|
|
71
|
-
if (tn.type === "TSQualifiedName" && typeof tn.name === "string" && tn.name.includes("Schema")) return true;
|
|
72
|
-
}
|
|
73
|
-
if (node.typeParameters) {
|
|
74
|
-
const params = node.typeParameters;
|
|
75
|
-
if (Array.isArray(params.params)) {
|
|
76
|
-
for (const p of params.params) if (typeRefContainsSchema(p)) return true;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
if (node.types && Array.isArray(node.types)) {
|
|
80
|
-
for (const m of node.types) if (typeRefContainsSchema(m)) return true;
|
|
81
|
-
}
|
|
72
|
+
if (!t) return false;
|
|
73
|
+
if (t.type === "TSTypeReference" && t.typeName.type === "Identifier") return t.typeName.name.includes("Schema");
|
|
74
|
+
if (t.type === "TSUnionType" || t.type === "TSIntersectionType") return t.types.some((member) => typeRefContainsSchema(member));
|
|
82
75
|
return false;
|
|
83
76
|
}
|
|
84
77
|
function initRefersToSchema(expr) {
|
|
85
|
-
if (!expr
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
if (callee.type === "Identifier" && callee.name === "pipe") {
|
|
90
|
-
const args = node.arguments;
|
|
91
|
-
if (Array.isArray(args)) {
|
|
92
|
-
for (const arg of args) if (initRefersToSchema(arg)) return true;
|
|
93
|
-
}
|
|
94
|
-
return false;
|
|
95
|
-
}
|
|
78
|
+
if (!expr) return false;
|
|
79
|
+
if (expr.type === "CallExpression") {
|
|
80
|
+
const callee = expr.callee;
|
|
81
|
+
if (callee.type === "Identifier" && callee.name === "pipe") return expr.arguments.some((arg) => arg.type !== "SpreadElement" && initRefersToSchema(arg));
|
|
96
82
|
if (callee.type === "MemberExpression") return memberChainStartsWithS(callee);
|
|
97
|
-
if (callee.type === "Identifier"
|
|
83
|
+
if (callee.type === "Identifier") return callee.name.includes("Schema");
|
|
84
|
+
return false;
|
|
98
85
|
}
|
|
99
|
-
if (
|
|
86
|
+
if (expr.type === "MemberExpression") return memberChainStartsWithS(expr);
|
|
100
87
|
return false;
|
|
101
88
|
}
|
|
102
89
|
function memberChainStartsWithS(node) {
|
|
103
90
|
const obj = node.object;
|
|
104
|
-
if (
|
|
105
|
-
if (obj.type === "Identifier" && obj.name === "S") return true;
|
|
106
|
-
if (obj.type === "Identifier" && typeof obj.name === "string" && obj.name.includes("Schema")) return true;
|
|
91
|
+
if (obj.type === "Identifier") return obj.name === "S" || obj.name.includes("Schema");
|
|
107
92
|
if (obj.type === "MemberExpression") return memberChainStartsWithS(obj);
|
|
93
|
+
if (obj.type === "CallExpression") {
|
|
94
|
+
const callee = obj.callee;
|
|
95
|
+
if (callee.type === "MemberExpression") return memberChainStartsWithS(callee);
|
|
96
|
+
if (callee.type === "Identifier") return callee.name === "S" || callee.name.includes("Schema");
|
|
97
|
+
}
|
|
108
98
|
return false;
|
|
109
99
|
}
|
|
110
100
|
/**
|
|
101
|
+
* True when a class extends `Schema.Class(...)` or `Schema.TaggedClass(...)`.
|
|
102
|
+
* The constructor is curried — `Schema.Class<Foo>()({...})` is two nested
|
|
103
|
+
* CallExpressions wrapping one MemberExpression — so unwrap the call chain
|
|
104
|
+
* before inspecting the member.
|
|
105
|
+
*
|
|
106
|
+
* `Schema.TaggedError` is deliberately excluded: an error is a failure value,
|
|
107
|
+
* not a codec, so it is not subject to the round-trip laws (and its `cause`
|
|
108
|
+
* field is routinely `S.Unknown`, which does not round-trip).
|
|
109
|
+
*/
|
|
110
|
+
function extendsSchemaClass(superClass) {
|
|
111
|
+
if (!superClass) return false;
|
|
112
|
+
let callee = superClass;
|
|
113
|
+
while (callee.type === "CallExpression") callee = callee.callee;
|
|
114
|
+
if (callee.type !== "MemberExpression") return false;
|
|
115
|
+
if (callee.property.type !== "Identifier") return false;
|
|
116
|
+
const propName = callee.property.name;
|
|
117
|
+
if (propName !== "Class" && propName !== "TaggedClass") return false;
|
|
118
|
+
return memberChainStartsWithS(callee);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
111
121
|
* Vite plugin that walks the consumer's `src/` directory, finds every
|
|
112
122
|
* exported Effect `Schema`, and auto-injects `ruleOfSchemas` round-trip
|
|
113
123
|
* property tests for each one.
|
|
@@ -131,7 +141,7 @@ const inlineSchemaTests = (options) => {
|
|
|
131
141
|
config = c;
|
|
132
142
|
},
|
|
133
143
|
resolveId(id) {
|
|
134
|
-
|
|
144
|
+
return id === "virtual:@systemfsoftware/inline-schema-tests" ? "\0virtual:@systemfsoftware/inline-schema-tests" : void 0;
|
|
135
145
|
},
|
|
136
146
|
load(id) {
|
|
137
147
|
if (id !== "\0virtual:@systemfsoftware/inline-schema-tests") return;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@systemfsoftware/effect-schema-vite",
|
|
3
3
|
"license": "MIT",
|
|
4
|
-
"version": "1.
|
|
4
|
+
"version": "1.3.0",
|
|
5
5
|
"author": "Ryan Lee <drdgvhbh@gmail.com>",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -46,10 +46,10 @@
|
|
|
46
46
|
"vite": "^7",
|
|
47
47
|
"vitest": "^4",
|
|
48
48
|
"@systemfsoftware/arethetypeswrong-cli": "^1.0.7",
|
|
49
|
+
"@systemfsoftware/tsconfig": "^1.2.6",
|
|
49
50
|
"@systemfsoftware/oxlint-config": "^0.1.0",
|
|
50
|
-
"@systemfsoftware/
|
|
51
|
-
"@systemfsoftware/
|
|
52
|
-
"@systemfsoftware/vitest-config": "^0.1.0"
|
|
51
|
+
"@systemfsoftware/vitest-config": "^0.1.0",
|
|
52
|
+
"@systemfsoftware/effect-schema-law": "^0.5.0"
|
|
53
53
|
},
|
|
54
54
|
"peerDependencies": {
|
|
55
55
|
"@systemfsoftware/effect-schema-law": "*",
|
|
@@ -62,7 +62,7 @@
|
|
|
62
62
|
},
|
|
63
63
|
"scripts": {
|
|
64
64
|
"clean": "rimraf dist",
|
|
65
|
-
"build": "tsdown",
|
|
65
|
+
"build": "tsdown && pnpm api:check",
|
|
66
66
|
"typecheck": "tsc --noEmit --incremental",
|
|
67
67
|
"test": "vitest run",
|
|
68
68
|
"test:run": "vitest run",
|