counterfact 0.35.0 → 0.37.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/README.md +1 -1
- package/bin/counterfact.js +0 -5
- package/dist/client/index.html.hbs +1 -1
- package/dist/server/code-generator.js +12 -2
- package/dist/server/config.js +1 -1
- package/dist/server/context-registry.js +9 -9
- package/dist/server/module-loader.js +19 -7
- package/dist/typescript-generator/context-file-token.js +1 -0
- package/dist/typescript-generator/generate.js +3 -4
- package/dist/typescript-generator/operation-type-coder.js +2 -2
- package/dist/typescript-generator/repository.js +52 -3
- package/dist/util/wait-for-event.js +23 -0
- package/package.json +15 -15
- package/dist/migrations/0.27.js +0 -39
- package/dist/typescript-generator/context-coder.js +0 -41
- package/dist/typescript-generator/context-type-coder.js +0 -32
package/README.md
CHANGED
|
@@ -62,4 +62,4 @@ If your mocking needs are relatively simple and you're shopping for someone who
|
|
|
62
62
|
|
|
63
63
|
We value _all_ of your feedback and contributions, including 💌 love letters , 💡 feature requests, 🐞 bug reports, and ✍️ grammatical nit-picks in the docs. Please [create an issue](https://github.com/pmcelhaney/counterfact/issues/new), open a pull request, or reach out to <pmcelhaney@gmail.com>.
|
|
64
64
|
|
|
65
|
-
**
|
|
65
|
+
**Welcome to the bottom of the README club! Since you've come this far, go ahead and smash that like and subsc… er, uh, give this project a ⭐️ on GitHub!** 🙏🏼
|
package/bin/counterfact.js
CHANGED
|
@@ -8,7 +8,6 @@ import { program } from "commander";
|
|
|
8
8
|
import createDebug from "debug";
|
|
9
9
|
import open from "open";
|
|
10
10
|
|
|
11
|
-
import { migrate } from "../dist/migrations/0.27.js";
|
|
12
11
|
import { counterfact } from "../dist/server/app.js";
|
|
13
12
|
|
|
14
13
|
const taglinesFile = await readFile(
|
|
@@ -44,10 +43,6 @@ async function main(source, destination) {
|
|
|
44
43
|
.join(process.cwd(), destination)
|
|
45
44
|
.replaceAll("\\", "/");
|
|
46
45
|
|
|
47
|
-
debug("migrating code from before 0.27.0");
|
|
48
|
-
migrate(destinationPath);
|
|
49
|
-
debug("done with migration");
|
|
50
|
-
|
|
51
46
|
const basePath = nodePath.resolve(destinationPath).replaceAll("\\", "/");
|
|
52
47
|
|
|
53
48
|
debug("options: %o", options);
|
|
@@ -132,7 +132,7 @@ it up later. In the mean time, I welcome pull requests. :)
|
|
|
132
132
|
<a href="./swagger" class="button" target="_blank">Swagger UI</a>
|
|
133
133
|
<a href="{{openApiHref}}" class="button" target="_blank">OpenAPI</a>
|
|
134
134
|
<a href="https://counterfact.dev/docs/usage.html" target="_blank">Usage Guide</a>
|
|
135
|
-
<a href="https://github.com/pmcelhaney/counterfact" target="_blank">
|
|
135
|
+
<a href="https://github.com/pmcelhaney/counterfact" target="_blank">GitHub</a>
|
|
136
136
|
</div>
|
|
137
137
|
|
|
138
138
|
|
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
import { watch } from "chokidar";
|
|
2
2
|
import { generate } from "../typescript-generator/generate.js";
|
|
3
|
-
|
|
3
|
+
import { waitForEvent } from "../util/wait-for-event.js";
|
|
4
|
+
export class CodeGenerator extends EventTarget {
|
|
4
5
|
openapiPath;
|
|
5
6
|
destination;
|
|
6
7
|
watcher;
|
|
7
8
|
constructor(openApiPath, destination) {
|
|
9
|
+
super();
|
|
8
10
|
this.openapiPath = openApiPath;
|
|
9
11
|
this.destination = destination;
|
|
10
12
|
}
|
|
@@ -14,8 +16,16 @@ export class CodeGenerator {
|
|
|
14
16
|
return;
|
|
15
17
|
}
|
|
16
18
|
this.watcher = watch(this.openapiPath).on("change", () => {
|
|
17
|
-
|
|
19
|
+
// eslint-disable-next-line promise/prefer-await-to-then
|
|
20
|
+
void generate(this.openapiPath, this.destination).then(() => {
|
|
21
|
+
this.dispatchEvent(new Event("generate"));
|
|
22
|
+
return true;
|
|
23
|
+
}, () => {
|
|
24
|
+
this.dispatchEvent(new Event("failed"));
|
|
25
|
+
return false;
|
|
26
|
+
});
|
|
18
27
|
});
|
|
28
|
+
await waitForEvent(this.watcher, "ready");
|
|
19
29
|
}
|
|
20
30
|
async stopWatching() {
|
|
21
31
|
await this.watcher?.close();
|
package/dist/server/config.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export
|
|
1
|
+
export const DUMMY_EXPORT_FOR_TEST_COVERAGE = 1;
|
|
@@ -1,20 +1,20 @@
|
|
|
1
|
+
// eslint-disable-next-line max-classes-per-file
|
|
2
|
+
export class Context {
|
|
3
|
+
// eslint-disable-next-line @typescript-eslint/no-useless-constructor, @typescript-eslint/no-empty-function
|
|
4
|
+
constructor() { }
|
|
5
|
+
}
|
|
1
6
|
export function parentPath(path) {
|
|
2
7
|
return String(path.split("/").slice(0, -1).join("/")) || "/";
|
|
3
8
|
}
|
|
4
9
|
export class ContextRegistry {
|
|
5
10
|
entries = new Map();
|
|
11
|
+
cache = new Map();
|
|
6
12
|
constructor() {
|
|
7
13
|
this.add("/", {});
|
|
8
14
|
}
|
|
9
15
|
add(path, context) {
|
|
10
|
-
if (context === undefined) {
|
|
11
|
-
// If $.context.ts exists but only exports a type, then the context object will be undefined here.
|
|
12
|
-
// This should be handled upstream, so that add() is not called in the first place.
|
|
13
|
-
// But module-loader.ts needs to be refactored a bit using type guards and the is operator
|
|
14
|
-
// before that can be done cleanly.
|
|
15
|
-
return;
|
|
16
|
-
}
|
|
17
16
|
this.entries.set(path, context);
|
|
17
|
+
this.cache.set(path, structuredClone(context));
|
|
18
18
|
}
|
|
19
19
|
find(path) {
|
|
20
20
|
return this.entries.get(path) ?? this.find(parentPath(path));
|
|
@@ -25,12 +25,12 @@ export class ContextRegistry {
|
|
|
25
25
|
}
|
|
26
26
|
const context = this.find(path);
|
|
27
27
|
for (const property in updatedContext) {
|
|
28
|
-
if (
|
|
29
|
-
!Object.prototype.hasOwnProperty.call(context, property)) {
|
|
28
|
+
if (updatedContext[property] !== this.cache.get(path)?.[property]) {
|
|
30
29
|
context[property] = updatedContext[property];
|
|
31
30
|
}
|
|
32
31
|
}
|
|
33
32
|
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
34
33
|
Object.setPrototypeOf(context, Object.getPrototypeOf(updatedContext));
|
|
34
|
+
this.cache.set(path, structuredClone(updatedContext));
|
|
35
35
|
}
|
|
36
36
|
}
|
|
@@ -7,6 +7,9 @@ import { watch } from "chokidar";
|
|
|
7
7
|
import createDebug from "debug";
|
|
8
8
|
import { ContextRegistry } from "./context-registry.js";
|
|
9
9
|
const debug = createDebug("counterfact:typescript-generator:module-loader");
|
|
10
|
+
function isContextModule(module) {
|
|
11
|
+
return "Context" in module && typeof module.Context === "function";
|
|
12
|
+
}
|
|
10
13
|
function reportLoadError(error, fileUrl) {
|
|
11
14
|
if (String(error) ===
|
|
12
15
|
"SyntaxError: Identifier 'Context' has already been declared") {
|
|
@@ -31,6 +34,10 @@ export class ModuleLoader extends EventTarget {
|
|
|
31
34
|
// eslint-disable-next-line max-statements
|
|
32
35
|
(eventName, pathNameOriginal) => {
|
|
33
36
|
const pathName = pathNameOriginal.replaceAll("\\", "/");
|
|
37
|
+
if (pathName.includes("$.context") && eventName === "add") {
|
|
38
|
+
process.stdout.write(`\n\n!!! The file at ${pathName} needs a minor update.\n See https://github.com/pmcelhaney/counterfact/blob/main/docs/context-change.md\n\n\n`);
|
|
39
|
+
return;
|
|
40
|
+
}
|
|
34
41
|
if (!["add", "change", "unlink"].includes(eventName)) {
|
|
35
42
|
return;
|
|
36
43
|
}
|
|
@@ -49,10 +56,11 @@ export class ModuleLoader extends EventTarget {
|
|
|
49
56
|
// eslint-disable-next-line promise/prefer-await-to-then
|
|
50
57
|
.then((endpoint) => {
|
|
51
58
|
this.dispatchEvent(new Event(eventName));
|
|
52
|
-
if (pathName.includes("
|
|
59
|
+
if (pathName.includes("_.context")) {
|
|
53
60
|
this.contextRegistry.update(parts.dir,
|
|
54
|
-
//
|
|
55
|
-
|
|
61
|
+
// @ts-expect-error TS says Context has no constructable signatures but that's not true?
|
|
62
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument, @typescript-eslint/consistent-type-assertions
|
|
63
|
+
new endpoint.Context());
|
|
56
64
|
return "context";
|
|
57
65
|
}
|
|
58
66
|
// eslint-disable-next-line @typescript-eslint/consistent-type-assertions
|
|
@@ -92,15 +100,19 @@ export class ModuleLoader extends EventTarget {
|
|
|
92
100
|
});
|
|
93
101
|
await Promise.all(imports);
|
|
94
102
|
}
|
|
103
|
+
// eslint-disable-next-line max-statements
|
|
95
104
|
async loadEndpoint(fullPath, directory, file) {
|
|
96
105
|
const fileUrl = `${pathToFileURL(fullPath).toString()}?cacheBust=${Date.now()}`;
|
|
97
106
|
try {
|
|
98
107
|
// eslint-disable-next-line import/no-dynamic-require, no-unsanitized/method, @typescript-eslint/consistent-type-assertions
|
|
99
108
|
const endpoint = (await import(fileUrl));
|
|
100
|
-
if (file.name.includes("
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
109
|
+
if (file.name.includes("_.context")) {
|
|
110
|
+
if (isContextModule(endpoint)) {
|
|
111
|
+
this.contextRegistry.add(`/${directory.replaceAll("\\", "/")}`,
|
|
112
|
+
// @ts-expect-error TS says Context has no constructable signatures but that's not true?
|
|
113
|
+
// eslint-disable-next-line @typescript-eslint/no-unsafe-argument
|
|
114
|
+
new endpoint.Context());
|
|
115
|
+
}
|
|
104
116
|
}
|
|
105
117
|
else {
|
|
106
118
|
const url = `/${nodePath.join(directory, nodePath.parse(file.name).name)}`
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const CONTEXT_FILE_TOKEN = "@@CONTEXT_FILE_TOKEN@@";
|
|
@@ -3,7 +3,6 @@ import fs from "node:fs/promises";
|
|
|
3
3
|
import nodePath from "node:path";
|
|
4
4
|
import createDebug from "debug";
|
|
5
5
|
import { ensureDirectoryExists } from "../util/ensure-directory-exists.js";
|
|
6
|
-
import { ContextCoder } from "./context-coder.js";
|
|
7
6
|
import { OperationCoder } from "./operation-coder.js";
|
|
8
7
|
import { Repository } from "./repository.js";
|
|
9
8
|
import { Specification } from "./specification.js";
|
|
@@ -29,11 +28,11 @@ async function buildCacheDirectory(destination) {
|
|
|
29
28
|
}
|
|
30
29
|
async function getPathsFromSpecification(specification) {
|
|
31
30
|
try {
|
|
32
|
-
return await specification.requirementAt("#/paths");
|
|
31
|
+
return (await specification.requirementAt("#/paths")) ?? new Set();
|
|
33
32
|
}
|
|
34
33
|
catch (error) {
|
|
35
34
|
process.stderr.write(`Could not find #/paths in the specification.\n${error}\n`);
|
|
36
|
-
return
|
|
35
|
+
return new Set();
|
|
37
36
|
}
|
|
38
37
|
}
|
|
39
38
|
// eslint-disable-next-line max-statements
|
|
@@ -54,7 +53,7 @@ export async function generate(source, destination, repository = new Repository(
|
|
|
54
53
|
repository.get(`paths${key}.ts`).export(new OperationCoder(operation));
|
|
55
54
|
});
|
|
56
55
|
});
|
|
57
|
-
repository.get("paths/$.context.ts").exportDefault(new ContextCoder(paths));
|
|
56
|
+
// repository.get("paths/$.context.ts").exportDefault(new ContextCoder(paths));
|
|
58
57
|
debug("telling the repository to write the files to %s", destination);
|
|
59
58
|
await repository.writeFiles(destination);
|
|
60
59
|
debug("finished writing the files");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import nodePath from "node:path";
|
|
2
2
|
import { Coder } from "./coder.js";
|
|
3
|
-
import {
|
|
3
|
+
import { CONTEXT_FILE_TOKEN } from "./context-file-token.js";
|
|
4
4
|
import { ParametersTypeCoder } from "./parameters-type-coder.js";
|
|
5
5
|
import { ResponseTypeCoder } from "./response-type-coder.js";
|
|
6
6
|
import { SchemaTypeCoder } from "./schema-type-coder.js";
|
|
@@ -49,7 +49,7 @@ export class OperationTypeCoder extends Coder {
|
|
|
49
49
|
.replaceAll("\\", "/")}.types.ts`;
|
|
50
50
|
}
|
|
51
51
|
write(script) {
|
|
52
|
-
const contextTypeImportName = script.
|
|
52
|
+
const contextTypeImportName = script.importExternalType("Context", CONTEXT_FILE_TOKEN);
|
|
53
53
|
const parameters = this.requirement.get("parameters");
|
|
54
54
|
const queryType = parameters === undefined
|
|
55
55
|
? "never"
|
|
@@ -1,8 +1,10 @@
|
|
|
1
|
+
import { existsSync } from "node:fs";
|
|
1
2
|
import fs from "node:fs/promises";
|
|
2
3
|
import nodePath, { dirname } from "node:path";
|
|
3
4
|
import { fileURLToPath } from "node:url";
|
|
4
5
|
import createDebug from "debug";
|
|
5
6
|
import { ensureDirectoryExists } from "../util/ensure-directory-exists.js";
|
|
7
|
+
import { CONTEXT_FILE_TOKEN } from "./context-file-token.js";
|
|
6
8
|
import { Script } from "./script.js";
|
|
7
9
|
const debug = createDebug("counterfact:server:repository");
|
|
8
10
|
// eslint-disable-next-line no-underscore-dangle
|
|
@@ -30,10 +32,20 @@ export class Repository {
|
|
|
30
32
|
await Promise.all(Array.from(this.scripts.values(), (script) => script.finished()));
|
|
31
33
|
}
|
|
32
34
|
}
|
|
33
|
-
copyCoreFiles(destination) {
|
|
35
|
+
async copyCoreFiles(destination) {
|
|
36
|
+
const sourcePath = nodePath
|
|
37
|
+
.join(__dirname, "../../dist/server/types.d.ts")
|
|
38
|
+
.replaceAll("\\", "/");
|
|
39
|
+
if (!existsSync(sourcePath)) {
|
|
40
|
+
return false;
|
|
41
|
+
}
|
|
42
|
+
const destinationPath = nodePath
|
|
43
|
+
.join(destination, "types.d.ts")
|
|
44
|
+
.replaceAll("\\", "/");
|
|
45
|
+
await ensureDirectoryExists(destination);
|
|
34
46
|
return fs.copyFile(nodePath
|
|
35
47
|
.join(__dirname, "../../dist/server/types.d.ts")
|
|
36
|
-
.replaceAll("\\", "/"),
|
|
48
|
+
.replaceAll("\\", "/"), destinationPath);
|
|
37
49
|
}
|
|
38
50
|
async writeFiles(destination) {
|
|
39
51
|
debug("waiting for %i or more scripts to finish before writing files", this.scripts.size);
|
|
@@ -52,10 +64,47 @@ export class Repository {
|
|
|
52
64
|
return;
|
|
53
65
|
}
|
|
54
66
|
debug("about to write", fullPath);
|
|
55
|
-
await fs.writeFile(fullPath, contents);
|
|
67
|
+
await fs.writeFile(fullPath, contents.replaceAll(CONTEXT_FILE_TOKEN, this.findContextPath(destination, path)));
|
|
56
68
|
debug("did write", fullPath);
|
|
57
69
|
});
|
|
58
70
|
await Promise.all(writeFiles);
|
|
59
71
|
await this.copyCoreFiles(destination);
|
|
72
|
+
await this.createDefaultContextFile(destination);
|
|
73
|
+
}
|
|
74
|
+
async createDefaultContextFile(destination) {
|
|
75
|
+
const contextFilePath = nodePath.join(destination, "paths", "_.context.ts");
|
|
76
|
+
if (existsSync(contextFilePath)) {
|
|
77
|
+
return;
|
|
78
|
+
}
|
|
79
|
+
await ensureDirectoryExists(contextFilePath);
|
|
80
|
+
await fs.writeFile(contextFilePath, `/**
|
|
81
|
+
* This is the default context for Counterfact.
|
|
82
|
+
*
|
|
83
|
+
* It defines the context object in the REPL
|
|
84
|
+
* and the $.context object in the code.
|
|
85
|
+
*
|
|
86
|
+
* Add properties and methods to suit your needs.
|
|
87
|
+
*
|
|
88
|
+
* See https://counterfact.dev/docs/usage.html#working-with-state-the-codecontextcode-object-and-codecontexttscode
|
|
89
|
+
*/
|
|
90
|
+
export class Context {
|
|
91
|
+
|
|
92
|
+
}
|
|
93
|
+
`);
|
|
94
|
+
}
|
|
95
|
+
findContextPath(destination, path) {
|
|
96
|
+
return nodePath.relative(nodePath.join(destination, nodePath.dirname(path)), this.nearestContextFile(destination, path));
|
|
97
|
+
}
|
|
98
|
+
nearestContextFile(destination, path) {
|
|
99
|
+
const directory = nodePath.dirname(path).replace("path-types", "paths");
|
|
100
|
+
const candidate = nodePath.join(destination, directory, "_.context.ts");
|
|
101
|
+
if (directory.length <= 1) {
|
|
102
|
+
// No _context.ts was found so import the one that should be in the root
|
|
103
|
+
return nodePath.join(destination, "paths", "_.context.ts");
|
|
104
|
+
}
|
|
105
|
+
if (existsSync(candidate)) {
|
|
106
|
+
return candidate;
|
|
107
|
+
}
|
|
108
|
+
return this.nearestContextFile(destination, nodePath.join(path, ".."));
|
|
60
109
|
}
|
|
61
110
|
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Creates a promise that resolves when a specified event is fired on the given EventTarget.
|
|
3
|
+
* @param {EventTarget | EventEmitter} target - The target to listen for the event on.
|
|
4
|
+
* @param {string} eventName - The name of the event to listen for.
|
|
5
|
+
* @returns {Promise<Event>} A promise that resolves with the event object when the event is fired.
|
|
6
|
+
*/
|
|
7
|
+
export async function waitForEvent(target, eventName) {
|
|
8
|
+
// eslint-disable-next-line promise/avoid-new
|
|
9
|
+
return await new Promise((resolve) => {
|
|
10
|
+
const handler = (event) => {
|
|
11
|
+
if (target instanceof EventTarget) {
|
|
12
|
+
target.removeEventListener(eventName, handler);
|
|
13
|
+
}
|
|
14
|
+
resolve(event);
|
|
15
|
+
};
|
|
16
|
+
if (target instanceof EventTarget) {
|
|
17
|
+
target.addEventListener(eventName, handler);
|
|
18
|
+
}
|
|
19
|
+
else {
|
|
20
|
+
target.once(eventName, handler);
|
|
21
|
+
}
|
|
22
|
+
});
|
|
23
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "counterfact",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.37.0",
|
|
4
4
|
"description": "a library for building a fake REST API for testing",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/server/counterfact.js",
|
|
@@ -18,7 +18,7 @@
|
|
|
18
18
|
"testing"
|
|
19
19
|
],
|
|
20
20
|
"engines": {
|
|
21
|
-
"node": ">=
|
|
21
|
+
"node": ">=17.0.0"
|
|
22
22
|
},
|
|
23
23
|
"bin": {
|
|
24
24
|
"counterfact": "./bin/counterfact.js"
|
|
@@ -28,7 +28,7 @@
|
|
|
28
28
|
"dist"
|
|
29
29
|
],
|
|
30
30
|
"scripts": {
|
|
31
|
-
"test": "yarn node --experimental-vm-modules ./node_modules/jest-cli/bin/jest --testPathIgnorePatterns=black-box
|
|
31
|
+
"test": "yarn node --experimental-vm-modules ./node_modules/jest-cli/bin/jest --testPathIgnorePatterns=black-box",
|
|
32
32
|
"test:black-box": "rimraf dist && rimraf out && yarn build && yarn node --experimental-vm-modules ./node_modules/jest-cli/bin/jest black-box --forceExit --coverage=false",
|
|
33
33
|
"test:mutants": "stryker run stryker.config.json",
|
|
34
34
|
"build": "tsc && copyfiles -f \"src/client/**\" dist/client && copyfiles -f \"src/server/*.d.ts\" dist/server",
|
|
@@ -44,13 +44,13 @@
|
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@changesets/cli": "2.27.1",
|
|
47
|
-
"@stryker-mutator/core": "8.
|
|
48
|
-
"@stryker-mutator/jest-runner": "8.
|
|
49
|
-
"@stryker-mutator/typescript-checker": "8.
|
|
50
|
-
"@swc/core": "1.
|
|
51
|
-
"@swc/jest": "0.2.
|
|
47
|
+
"@stryker-mutator/core": "8.2.3",
|
|
48
|
+
"@stryker-mutator/jest-runner": "8.2.3",
|
|
49
|
+
"@stryker-mutator/typescript-checker": "8.2.3",
|
|
50
|
+
"@swc/core": "1.4.0",
|
|
51
|
+
"@swc/jest": "0.2.36",
|
|
52
52
|
"@testing-library/dom": "9.3.4",
|
|
53
|
-
"@types/jest": "29.5.
|
|
53
|
+
"@types/jest": "29.5.12",
|
|
54
54
|
"@types/js-yaml": "4.0.9",
|
|
55
55
|
"@types/koa": "2.14.0",
|
|
56
56
|
"@types/koa-bodyparser": "4.3.12",
|
|
@@ -68,21 +68,21 @@
|
|
|
68
68
|
"eslint-plugin-jest-dom": "5.1.0",
|
|
69
69
|
"eslint-plugin-no-explicit-type-exports": "0.12.1",
|
|
70
70
|
"eslint-plugin-unused-imports": "3.0.0",
|
|
71
|
-
"husky": "
|
|
71
|
+
"husky": "9.0.10",
|
|
72
72
|
"jest": "29.7.0",
|
|
73
73
|
"node-mocks-http": "1.14.1",
|
|
74
|
-
"nodemon": "3.0.
|
|
74
|
+
"nodemon": "3.0.3",
|
|
75
75
|
"patch-package": "8.0.0",
|
|
76
76
|
"rimraf": "5.0.5",
|
|
77
77
|
"stryker-cli": "1.0.2",
|
|
78
78
|
"supertest": "6.3.4",
|
|
79
|
-
"using-temporary-files": "2.1.
|
|
79
|
+
"using-temporary-files": "2.1.1"
|
|
80
80
|
},
|
|
81
81
|
"dependencies": {
|
|
82
82
|
"@hapi/accept": "6.0.3",
|
|
83
83
|
"@types/json-schema": "7.0.15",
|
|
84
|
-
"chokidar": "3.
|
|
85
|
-
"commander": "
|
|
84
|
+
"chokidar": "3.6.0",
|
|
85
|
+
"commander": "12.0.0",
|
|
86
86
|
"debug": "4.3.4",
|
|
87
87
|
"fetch": "1.1.0",
|
|
88
88
|
"fs-extra": "11.2.0",
|
|
@@ -98,7 +98,7 @@
|
|
|
98
98
|
"koa2-swagger-ui": "5.10.0",
|
|
99
99
|
"node-fetch": "3.3.2",
|
|
100
100
|
"open": "10.0.3",
|
|
101
|
-
"prettier": "3.2.
|
|
101
|
+
"prettier": "3.2.5",
|
|
102
102
|
"typescript": "5.3.3"
|
|
103
103
|
}
|
|
104
104
|
}
|
package/dist/migrations/0.27.js
DELETED
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import { existsSync, readdirSync, readFileSync, statSync, writeFileSync, } from "node:fs";
|
|
2
|
-
import { join } from "node:path";
|
|
3
|
-
function processFile(filePath) {
|
|
4
|
-
const content = readFileSync(filePath, "utf8");
|
|
5
|
-
if (content.includes("export type ContextType =") ||
|
|
6
|
-
content.includes("export type { ContextType }")) {
|
|
7
|
-
return;
|
|
8
|
-
}
|
|
9
|
-
if (content.includes("export default new Context")) {
|
|
10
|
-
writeFileSync(filePath, "export type ContextType = Context;\n", {
|
|
11
|
-
flag: "a",
|
|
12
|
-
});
|
|
13
|
-
}
|
|
14
|
-
else {
|
|
15
|
-
writeFileSync(filePath, 'export type { ContextType } from "../$.context";\n');
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
function migrateContextFiles(path) {
|
|
19
|
-
if (!existsSync(path)) {
|
|
20
|
-
return;
|
|
21
|
-
}
|
|
22
|
-
const items = readdirSync(path);
|
|
23
|
-
for (const item of items) {
|
|
24
|
-
const itemPath = join(path, item);
|
|
25
|
-
const stats = statSync(itemPath);
|
|
26
|
-
if (stats.isDirectory()) {
|
|
27
|
-
migrateContextFiles(itemPath);
|
|
28
|
-
}
|
|
29
|
-
if (stats.isFile() && item === "$.context.ts") {
|
|
30
|
-
processFile(itemPath);
|
|
31
|
-
}
|
|
32
|
-
}
|
|
33
|
-
}
|
|
34
|
-
export function migrate(rootPath) {
|
|
35
|
-
if (!existsSync(rootPath)) {
|
|
36
|
-
return;
|
|
37
|
-
}
|
|
38
|
-
migrateContextFiles(join(rootPath, "paths"));
|
|
39
|
-
}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import nodePath from "node:path";
|
|
2
|
-
import { Coder } from "./coder.js";
|
|
3
|
-
export class ContextCoder extends Coder {
|
|
4
|
-
pathString() {
|
|
5
|
-
return this.requirement.url
|
|
6
|
-
.split("/")
|
|
7
|
-
.at(-2)
|
|
8
|
-
.replaceAll("~1", "/")
|
|
9
|
-
.replaceAll("~0", "~");
|
|
10
|
-
}
|
|
11
|
-
get id() {
|
|
12
|
-
return "ContextCoder";
|
|
13
|
-
}
|
|
14
|
-
names() {
|
|
15
|
-
return super.names("Context");
|
|
16
|
-
}
|
|
17
|
-
beforeExport(path) {
|
|
18
|
-
return `/**
|
|
19
|
-
* This is the default context for Counterfact.
|
|
20
|
-
* Change the code to suit your needs.
|
|
21
|
-
*/
|
|
22
|
-
class Context {
|
|
23
|
-
// delete this line to make the class type safe
|
|
24
|
-
[key: string]: any;
|
|
25
|
-
|
|
26
|
-
// A helper when you accessing the context object via the REPL. You can delete it if you like.
|
|
27
|
-
[Symbol.for('nodejs.util.inspect.custom')](depth, options, inspect) {
|
|
28
|
-
return inspect(this, { ...options, customInspect: false }) + "\\n\\n ^ This is the default context object. You can edit its definition at ${path}";
|
|
29
|
-
}
|
|
30
|
-
}
|
|
31
|
-
`;
|
|
32
|
-
}
|
|
33
|
-
write() {
|
|
34
|
-
return "new Context()";
|
|
35
|
-
}
|
|
36
|
-
modulePath() {
|
|
37
|
-
return nodePath
|
|
38
|
-
.join("paths", nodePath.dirname(this.pathString()), "$.context.ts")
|
|
39
|
-
.replaceAll("\\", "/");
|
|
40
|
-
}
|
|
41
|
-
}
|
|
@@ -1,32 +0,0 @@
|
|
|
1
|
-
import nodePath from "node:path";
|
|
2
|
-
import { Coder } from "./coder.js";
|
|
3
|
-
export class ContextTypeCoder extends Coder {
|
|
4
|
-
constructor(requirement, isRoot) {
|
|
5
|
-
super(requirement);
|
|
6
|
-
this.isRoot = isRoot;
|
|
7
|
-
}
|
|
8
|
-
pathString() {
|
|
9
|
-
return this.requirement.url
|
|
10
|
-
.split("/")
|
|
11
|
-
.at(-2)
|
|
12
|
-
.replaceAll("~1", "/")
|
|
13
|
-
.replaceAll("~0", "~");
|
|
14
|
-
}
|
|
15
|
-
get id() {
|
|
16
|
-
return "ContextTypeCoder";
|
|
17
|
-
}
|
|
18
|
-
names() {
|
|
19
|
-
return super.names("ContextType");
|
|
20
|
-
}
|
|
21
|
-
write(script) {
|
|
22
|
-
if (script.path === "paths/$.context.ts") {
|
|
23
|
-
return "Context";
|
|
24
|
-
}
|
|
25
|
-
return { raw: 'export type { ContextType } from "../$.context"' };
|
|
26
|
-
}
|
|
27
|
-
modulePath() {
|
|
28
|
-
return nodePath
|
|
29
|
-
.join("paths", nodePath.dirname(this.pathString()), "$.context.ts")
|
|
30
|
-
.replaceAll("\\", "/");
|
|
31
|
-
}
|
|
32
|
-
}
|