@systemfsoftware/effect-schema-vite 1.3.0 → 1.5.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 +27 -0
- package/dist/index.d.ts +27 -2
- package/dist/index.mjs +48 -20
- package/package.json +5 -4
|
@@ -1,10 +1,29 @@
|
|
|
1
1
|
import { Plugin as Plugin_2 } from 'vite';
|
|
2
2
|
|
|
3
|
+
/**
|
|
4
|
+
* Build the law-suite body injected into a consumer's `schema-laws.test.ts`.
|
|
5
|
+
*
|
|
6
|
+
* Import specifiers are relative to `lawFilePath`, never to the Vite root: the
|
|
7
|
+
* file being rewritten lives in `src/`, so a root-relative specifier resolves
|
|
8
|
+
* to `src/src/…` and yields a suite that silently imports nothing.
|
|
9
|
+
*
|
|
10
|
+
* @since 1.4.0
|
|
11
|
+
*/
|
|
12
|
+
export declare const generateSchemaLaws: (lawFilePath: string, srcDir: string) => string;
|
|
13
|
+
|
|
3
14
|
/**
|
|
4
15
|
* Vite plugin that walks the consumer's `src/` directory, finds every
|
|
5
16
|
* exported Effect `Schema`, and auto-injects `ruleOfSchemas` round-trip
|
|
6
17
|
* property tests for each one.
|
|
7
18
|
*
|
|
19
|
+
* The laws are injected by rewriting the consumer's own
|
|
20
|
+
* `src/schema-laws.test.ts` — the one test filename the placement taxonomy
|
|
21
|
+
* whitelists by name. It is deliberately NOT a virtual module: the generated
|
|
22
|
+
* body carries real `import` edges to each schema file, so vitest's
|
|
23
|
+
* related-file walk reaches them. A virtual module breaks that walk (its id
|
|
24
|
+
* has no path on disk), which silently drops every generated law from
|
|
25
|
+
* `stryker --related` runs and reports the survivors as coverage gaps.
|
|
26
|
+
*
|
|
8
27
|
* @example
|
|
9
28
|
* ```ts
|
|
10
29
|
* // vitest.config.ts
|
|
@@ -23,4 +42,12 @@ export declare interface InlineSchemaTestsOptions {
|
|
|
23
42
|
dir?: string;
|
|
24
43
|
}
|
|
25
44
|
|
|
45
|
+
/**
|
|
46
|
+
* The one test filename the placement taxonomy whitelists by name. The plugin
|
|
47
|
+
* rewrites this file in the consumer's `src/`; nothing else is touched.
|
|
48
|
+
*
|
|
49
|
+
* @since 1.4.0
|
|
50
|
+
*/
|
|
51
|
+
export declare const LAW_FILE_BASENAME: 'schema-laws.test.ts';
|
|
52
|
+
|
|
26
53
|
export { }
|
package/dist/index.d.ts
CHANGED
|
@@ -1,15 +1,40 @@
|
|
|
1
1
|
import { Plugin } from "vite";
|
|
2
|
-
//#region src/
|
|
2
|
+
//#region src/mod.d.ts
|
|
3
3
|
/** @since 0.1.0 */
|
|
4
4
|
interface InlineSchemaTestsOptions {
|
|
5
5
|
/** Directory to scan for schema files, relative to Vite root. Default: `"src"`. */
|
|
6
6
|
dir?: string;
|
|
7
7
|
}
|
|
8
|
+
/**
|
|
9
|
+
* The one test filename the placement taxonomy whitelists by name. The plugin
|
|
10
|
+
* rewrites this file in the consumer's `src/`; nothing else is touched.
|
|
11
|
+
*
|
|
12
|
+
* @since 1.4.0
|
|
13
|
+
*/
|
|
14
|
+
declare const LAW_FILE_BASENAME: 'schema-laws.test.ts';
|
|
15
|
+
/**
|
|
16
|
+
* Build the law-suite body injected into a consumer's `schema-laws.test.ts`.
|
|
17
|
+
*
|
|
18
|
+
* Import specifiers are relative to `lawFilePath`, never to the Vite root: the
|
|
19
|
+
* file being rewritten lives in `src/`, so a root-relative specifier resolves
|
|
20
|
+
* to `src/src/…` and yields a suite that silently imports nothing.
|
|
21
|
+
*
|
|
22
|
+
* @since 1.4.0
|
|
23
|
+
*/
|
|
24
|
+
declare const generateSchemaLaws: (lawFilePath: string, srcDir: string) => string;
|
|
8
25
|
/**
|
|
9
26
|
* Vite plugin that walks the consumer's `src/` directory, finds every
|
|
10
27
|
* exported Effect `Schema`, and auto-injects `ruleOfSchemas` round-trip
|
|
11
28
|
* property tests for each one.
|
|
12
29
|
*
|
|
30
|
+
* The laws are injected by rewriting the consumer's own
|
|
31
|
+
* `src/schema-laws.test.ts` — the one test filename the placement taxonomy
|
|
32
|
+
* whitelists by name. It is deliberately NOT a virtual module: the generated
|
|
33
|
+
* body carries real `import` edges to each schema file, so vitest's
|
|
34
|
+
* related-file walk reaches them. A virtual module breaks that walk (its id
|
|
35
|
+
* has no path on disk), which silently drops every generated law from
|
|
36
|
+
* `stryker --related` runs and reports the survivors as coverage gaps.
|
|
37
|
+
*
|
|
13
38
|
* @example
|
|
14
39
|
* ```ts
|
|
15
40
|
* // vitest.config.ts
|
|
@@ -22,4 +47,4 @@ interface InlineSchemaTestsOptions {
|
|
|
22
47
|
*/
|
|
23
48
|
declare const inlineSchemaTests: (options?: InlineSchemaTestsOptions) => Plugin;
|
|
24
49
|
//#endregion
|
|
25
|
-
export {
|
|
50
|
+
export { InlineSchemaTestsOptions, LAW_FILE_BASENAME, generateSchemaLaws, inlineSchemaTests };
|
package/dist/index.mjs
CHANGED
|
@@ -1,12 +1,19 @@
|
|
|
1
1
|
import { readFileSync, readdirSync, statSync } from "node:fs";
|
|
2
|
-
import { extname, join, relative, resolve } from "node:path";
|
|
2
|
+
import { dirname, extname, join, relative, resolve } from "node:path";
|
|
3
3
|
import { parseSync } from "oxc-parser";
|
|
4
|
-
//#region src/
|
|
4
|
+
//#region src/mod.ts
|
|
5
|
+
/**
|
|
6
|
+
* The one test filename the placement taxonomy whitelists by name. The plugin
|
|
7
|
+
* rewrites this file in the consumer's `src/`; nothing else is touched.
|
|
8
|
+
*
|
|
9
|
+
* @since 1.4.0
|
|
10
|
+
*/
|
|
11
|
+
const LAW_FILE_BASENAME = "schema-laws.test.ts";
|
|
5
12
|
/**
|
|
6
13
|
* Walk a directory and return every exported const whose type annotation
|
|
7
14
|
* or initialiser references Effect Schema APIs.
|
|
8
15
|
*/
|
|
9
|
-
function findExportedSchemas(
|
|
16
|
+
function findExportedSchemas(dir) {
|
|
10
17
|
const schemas = [];
|
|
11
18
|
function walk(current) {
|
|
12
19
|
let entries;
|
|
@@ -30,7 +37,7 @@ function findExportedSchemas(root, dir) {
|
|
|
30
37
|
const names = findExportedSchemaNames(readFileSync(full, "utf-8"));
|
|
31
38
|
for (const name of names) schemas.push({
|
|
32
39
|
name,
|
|
33
|
-
|
|
40
|
+
filePath: full
|
|
34
41
|
});
|
|
35
42
|
}
|
|
36
43
|
}
|
|
@@ -118,10 +125,41 @@ function extendsSchemaClass(superClass) {
|
|
|
118
125
|
return memberChainStartsWithS(callee);
|
|
119
126
|
}
|
|
120
127
|
/**
|
|
128
|
+
* Build the law-suite body injected into a consumer's `schema-laws.test.ts`.
|
|
129
|
+
*
|
|
130
|
+
* Import specifiers are relative to `lawFilePath`, never to the Vite root: the
|
|
131
|
+
* file being rewritten lives in `src/`, so a root-relative specifier resolves
|
|
132
|
+
* to `src/src/…` and yields a suite that silently imports nothing.
|
|
133
|
+
*
|
|
134
|
+
* @since 1.4.0
|
|
135
|
+
*/
|
|
136
|
+
const generateSchemaLaws = (lawFilePath, srcDir) => {
|
|
137
|
+
const schemas = findExportedSchemas(srcDir);
|
|
138
|
+
if (schemas.length === 0) return "// no schemas found\nexport {}\n";
|
|
139
|
+
const specifierOf = (filePath) => {
|
|
140
|
+
const rel = relative(dirname(lawFilePath), filePath).replace(/\.ts$/, "");
|
|
141
|
+
return rel.startsWith(".") ? rel : `./${rel}`;
|
|
142
|
+
};
|
|
143
|
+
return [
|
|
144
|
+
`import { ruleOfSchemas } from '@systemfsoftware/effect-schema-law'`,
|
|
145
|
+
schemas.map((s) => `import { ${s.name} } from '${specifierOf(s.filePath)}'`).join("\n"),
|
|
146
|
+
"",
|
|
147
|
+
schemas.map((s) => `ruleOfSchemas('${s.name}', ${s.name})`).join("\n")
|
|
148
|
+
].join("\n");
|
|
149
|
+
};
|
|
150
|
+
/**
|
|
121
151
|
* Vite plugin that walks the consumer's `src/` directory, finds every
|
|
122
152
|
* exported Effect `Schema`, and auto-injects `ruleOfSchemas` round-trip
|
|
123
153
|
* property tests for each one.
|
|
124
154
|
*
|
|
155
|
+
* The laws are injected by rewriting the consumer's own
|
|
156
|
+
* `src/schema-laws.test.ts` — the one test filename the placement taxonomy
|
|
157
|
+
* whitelists by name. It is deliberately NOT a virtual module: the generated
|
|
158
|
+
* body carries real `import` edges to each schema file, so vitest's
|
|
159
|
+
* related-file walk reaches them. A virtual module breaks that walk (its id
|
|
160
|
+
* has no path on disk), which silently drops every generated law from
|
|
161
|
+
* `stryker --related` runs and reports the survivors as coverage gaps.
|
|
162
|
+
*
|
|
125
163
|
* @example
|
|
126
164
|
* ```ts
|
|
127
165
|
* // vitest.config.ts
|
|
@@ -135,27 +173,17 @@ function extendsSchemaClass(superClass) {
|
|
|
135
173
|
const inlineSchemaTests = (options) => {
|
|
136
174
|
let config;
|
|
137
175
|
return {
|
|
138
|
-
name: "@systemfsoftware/
|
|
176
|
+
name: "@systemfsoftware/schema-laws",
|
|
139
177
|
enforce: "pre",
|
|
140
178
|
configResolved(c) {
|
|
141
179
|
config = c;
|
|
142
180
|
},
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
if (id !== "\0virtual:@systemfsoftware/inline-schema-tests") return;
|
|
148
|
-
const srcDir = resolve(config.root, options?.dir ?? "src");
|
|
149
|
-
const schemas = findExportedSchemas(config.root, srcDir);
|
|
150
|
-
if (schemas.length === 0) return "// no schemas found";
|
|
151
|
-
return [
|
|
152
|
-
`import { ruleOfSchemas } from '@systemfsoftware/effect-schema-law'`,
|
|
153
|
-
schemas.map((s) => `import { ${s.name} } from '${s.importPath}'`).join("\n"),
|
|
154
|
-
"",
|
|
155
|
-
schemas.map((s) => `ruleOfSchemas('${s.name}', ${s.name})`).join("\n")
|
|
156
|
-
].join("\n");
|
|
181
|
+
transform(_code, id) {
|
|
182
|
+
const lawFile = id.split("?")[0];
|
|
183
|
+
if (lawFile === void 0 || !lawFile.endsWith(`/schema-laws.test.ts`)) return;
|
|
184
|
+
return generateSchemaLaws(lawFile, resolve(config.root, options?.dir ?? "src"));
|
|
157
185
|
}
|
|
158
186
|
};
|
|
159
187
|
};
|
|
160
188
|
//#endregion
|
|
161
|
-
export { inlineSchemaTests };
|
|
189
|
+
export { LAW_FILE_BASENAME, generateSchemaLaws, inlineSchemaTests };
|
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.5.0",
|
|
5
5
|
"author": "Ryan Lee <drdgvhbh@gmail.com>",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -45,11 +45,12 @@
|
|
|
45
45
|
"tsdown": "^0.22.9",
|
|
46
46
|
"vite": "^7",
|
|
47
47
|
"vitest": "^4",
|
|
48
|
-
"@systemfsoftware/
|
|
48
|
+
"@systemfsoftware/effect-gherkin-spec": "^0.5.0",
|
|
49
|
+
"@systemfsoftware/arethetypeswrong-cli": "^1.1.0",
|
|
50
|
+
"@systemfsoftware/effect-schema-law": "^0.6.0",
|
|
49
51
|
"@systemfsoftware/tsconfig": "^1.2.6",
|
|
50
52
|
"@systemfsoftware/oxlint-config": "^0.1.0",
|
|
51
|
-
"@systemfsoftware/vitest-config": "^0.1.0"
|
|
52
|
-
"@systemfsoftware/effect-schema-law": "^0.5.0"
|
|
53
|
+
"@systemfsoftware/vitest-config": "^0.1.0"
|
|
53
54
|
},
|
|
54
55
|
"peerDependencies": {
|
|
55
56
|
"@systemfsoftware/effect-schema-law": "*",
|