counterfact 2.5.1 → 2.7.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 +103 -140
- package/bin/README.md +25 -4
- package/bin/counterfact.js +208 -24
- package/bin/register-ts-loader.mjs +17 -0
- package/bin/ts-loader.mjs +31 -0
- package/dist/app.js +31 -21
- package/dist/counterfact-types/cookie-options.js +1 -0
- package/dist/counterfact-types/counterfact-response.js +7 -0
- package/dist/counterfact-types/example-names.js +1 -0
- package/dist/counterfact-types/example.js +1 -0
- package/dist/counterfact-types/generic-response-builder.js +1 -0
- package/dist/counterfact-types/http-status-code.js +1 -0
- package/dist/counterfact-types/if-has-key.js +1 -0
- package/dist/counterfact-types/index.js +0 -1
- package/dist/counterfact-types/maybe-promise.js +1 -0
- package/dist/counterfact-types/media-type.js +1 -0
- package/dist/counterfact-types/omit-all.js +1 -0
- package/dist/counterfact-types/omit-value-when-never.js +1 -0
- package/dist/counterfact-types/open-api-content.js +1 -0
- package/dist/counterfact-types/open-api-operation.js +1 -0
- package/dist/counterfact-types/open-api-parameters.js +1 -0
- package/dist/counterfact-types/open-api-response.js +1 -0
- package/dist/counterfact-types/random-function.js +1 -0
- package/dist/counterfact-types/response-builder-factory.js +1 -0
- package/dist/counterfact-types/response-builder.js +1 -0
- package/dist/counterfact-types/wide-operation-argument.js +1 -0
- package/dist/counterfact-types/wide-response-builder.js +1 -0
- package/dist/migrate/update-route-types.js +30 -10
- package/dist/repl/raw-http-client.js +14 -14
- package/dist/repl/repl.js +119 -4
- package/dist/repl/route-builder.js +270 -0
- package/dist/server/config.js +1 -1
- package/dist/server/context-registry.js +44 -4
- package/dist/server/counterfact-types/cookie-options.ts +14 -0
- package/dist/server/counterfact-types/counterfact-response.ts +15 -0
- package/dist/server/counterfact-types/example-names.ts +13 -0
- package/dist/server/counterfact-types/example.ts +10 -0
- package/dist/server/counterfact-types/generic-response-builder.ts +164 -0
- package/dist/server/counterfact-types/http-status-code.ts +62 -0
- package/dist/server/counterfact-types/if-has-key.ts +19 -0
- package/dist/server/counterfact-types/index.ts +20 -328
- package/dist/server/counterfact-types/maybe-promise.ts +6 -0
- package/dist/server/counterfact-types/media-type.ts +6 -0
- package/dist/server/counterfact-types/omit-all.ts +11 -0
- package/dist/server/counterfact-types/omit-value-when-never.ts +11 -0
- package/dist/server/counterfact-types/open-api-content.ts +8 -0
- package/dist/server/counterfact-types/open-api-operation.ts +36 -0
- package/dist/server/counterfact-types/open-api-parameters.ts +16 -0
- package/dist/server/counterfact-types/open-api-response.ts +22 -0
- package/dist/server/counterfact-types/random-function.ts +9 -0
- package/dist/server/counterfact-types/response-builder-factory.ts +16 -0
- package/dist/server/counterfact-types/response-builder.ts +31 -0
- package/dist/server/counterfact-types/wide-operation-argument.ts +17 -0
- package/dist/server/counterfact-types/wide-response-builder.ts +26 -0
- package/dist/server/create-koa-app.js +1 -20
- package/dist/server/determine-module-kind.js +1 -1
- package/dist/server/dispatcher.js +39 -15
- package/dist/server/file-discovery.js +34 -0
- package/dist/server/json-to-xml.js +1 -1
- package/dist/server/koa-middleware.js +7 -1
- package/dist/server/load-openapi-document.js +13 -0
- package/dist/server/middleware-detector.js +8 -0
- package/dist/server/module-dependency-graph.js +4 -1
- package/dist/server/module-loader.js +81 -33
- package/dist/server/module-tree.js +26 -23
- package/dist/server/openapi-middleware.js +2 -2
- package/dist/server/openapi-watcher.js +35 -0
- package/dist/server/registry.js +2 -2
- package/dist/server/request-validator.js +57 -0
- package/dist/server/response-builder.js +3 -0
- package/dist/server/response-validator.js +58 -0
- package/dist/server/scenario-registry.js +29 -0
- package/dist/server/tools.js +2 -2
- package/dist/server/transpiler.js +13 -5
- package/dist/typescript-generator/coder.js +7 -2
- package/dist/typescript-generator/generate.js +155 -0
- package/dist/typescript-generator/jsdoc.js +45 -0
- package/dist/typescript-generator/operation-coder.js +1 -1
- package/dist/typescript-generator/operation-type-coder.js +5 -49
- package/dist/typescript-generator/parameters-type-coder.js +5 -1
- package/dist/typescript-generator/prune.js +2 -1
- package/dist/typescript-generator/read-only-comments.js +1 -1
- package/dist/typescript-generator/requirement.js +8 -1
- package/dist/typescript-generator/reserved-words.js +50 -0
- package/dist/typescript-generator/schema-type-coder.js +7 -1
- package/dist/typescript-generator/script.js +5 -3
- package/dist/typescript-generator/specification.js +7 -1
- package/dist/util/load-config-file.js +44 -0
- package/dist/util/runtime-can-execute-erasable-ts.js +22 -0
- package/package.json +12 -12
- package/dist/client/README.md +0 -14
- package/dist/client/index.html.hbs +0 -244
- package/dist/client/rapi-doc.html.hbs +0 -36
- package/dist/server/page-middleware.js +0 -23
|
@@ -1,61 +1,14 @@
|
|
|
1
1
|
import nodePath from "node:path";
|
|
2
2
|
import { CONTEXT_FILE_TOKEN } from "./context-file-token.js";
|
|
3
|
+
import { buildJsDoc } from "./jsdoc.js";
|
|
3
4
|
import { ParameterExportTypeCoder } from "./parameter-export-type-coder.js";
|
|
4
5
|
import { ParametersTypeCoder } from "./parameters-type-coder.js";
|
|
5
6
|
import { READ_ONLY_COMMENTS } from "./read-only-comments.js";
|
|
7
|
+
import { RESERVED_WORDS } from "./reserved-words.js";
|
|
6
8
|
import { ResponsesTypeCoder } from "./responses-type-coder.js";
|
|
7
9
|
import { SchemaTypeCoder } from "./schema-type-coder.js";
|
|
8
10
|
import { TypeCoder } from "./type-coder.js";
|
|
9
11
|
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words
|
|
10
|
-
const RESERVED_WORDS = new Set([
|
|
11
|
-
"break",
|
|
12
|
-
"case",
|
|
13
|
-
"catch",
|
|
14
|
-
"class",
|
|
15
|
-
"const",
|
|
16
|
-
"continue",
|
|
17
|
-
"debugger",
|
|
18
|
-
"default",
|
|
19
|
-
"delete",
|
|
20
|
-
"do",
|
|
21
|
-
"else",
|
|
22
|
-
"export",
|
|
23
|
-
"extends",
|
|
24
|
-
"false",
|
|
25
|
-
"finally",
|
|
26
|
-
"for",
|
|
27
|
-
"function",
|
|
28
|
-
"if",
|
|
29
|
-
"import",
|
|
30
|
-
"in",
|
|
31
|
-
"instanceof",
|
|
32
|
-
"new",
|
|
33
|
-
"null",
|
|
34
|
-
"return",
|
|
35
|
-
"static",
|
|
36
|
-
"super",
|
|
37
|
-
"switch",
|
|
38
|
-
"this",
|
|
39
|
-
"throw",
|
|
40
|
-
"true",
|
|
41
|
-
"try",
|
|
42
|
-
"typeof",
|
|
43
|
-
"var",
|
|
44
|
-
"void",
|
|
45
|
-
"while",
|
|
46
|
-
"with",
|
|
47
|
-
"yield",
|
|
48
|
-
"await",
|
|
49
|
-
"enum",
|
|
50
|
-
"implements",
|
|
51
|
-
"interface",
|
|
52
|
-
"let",
|
|
53
|
-
"package",
|
|
54
|
-
"private",
|
|
55
|
-
"protected",
|
|
56
|
-
"public",
|
|
57
|
-
"type",
|
|
58
|
-
]);
|
|
59
12
|
function sanitizeIdentifier(value) {
|
|
60
13
|
// Treat any run of non-identifier characters as a camelCase separator
|
|
61
14
|
let result = value.replaceAll(/[^\w$]+(?<next>.)/gu, (_, char) => char.toUpperCase());
|
|
@@ -88,6 +41,9 @@ export class OperationTypeCoder extends TypeCoder {
|
|
|
88
41
|
? sanitizeIdentifier(operationId)
|
|
89
42
|
: `HTTP_${this.requestMethod.toUpperCase()}`;
|
|
90
43
|
}
|
|
44
|
+
jsdoc() {
|
|
45
|
+
return buildJsDoc(this.requirement.data);
|
|
46
|
+
}
|
|
91
47
|
names() {
|
|
92
48
|
return super.names(this.getOperationBaseName());
|
|
93
49
|
}
|
|
@@ -1,4 +1,5 @@
|
|
|
1
1
|
import nodePath from "node:path";
|
|
2
|
+
import { buildJsDoc } from "./jsdoc.js";
|
|
2
3
|
import { SchemaTypeCoder } from "./schema-type-coder.js";
|
|
3
4
|
import { TypeCoder } from "./type-coder.js";
|
|
4
5
|
export class ParametersTypeCoder extends TypeCoder {
|
|
@@ -23,7 +24,10 @@ export class ParametersTypeCoder extends TypeCoder {
|
|
|
23
24
|
const schema = parameter.has("schema")
|
|
24
25
|
? parameter.get("schema")
|
|
25
26
|
: parameter;
|
|
26
|
-
|
|
27
|
+
const comment = buildJsDoc(parameter.data);
|
|
28
|
+
const commentPrefix = comment ? `\n${comment}` : "";
|
|
29
|
+
const typeString = new SchemaTypeCoder(schema).write(script);
|
|
30
|
+
return `${commentPrefix}"${name}"${optionalFlag}: ${typeString}`;
|
|
27
31
|
});
|
|
28
32
|
if (typeDefinitions.length === 0) {
|
|
29
33
|
return "never";
|
|
@@ -45,7 +45,8 @@ async function removeEmptyDirectories(dir, rootDir) {
|
|
|
45
45
|
try {
|
|
46
46
|
entries = await fs.readdir(dir, { withFileTypes: true });
|
|
47
47
|
}
|
|
48
|
-
catch {
|
|
48
|
+
catch (error) {
|
|
49
|
+
debug("could not read directory %s: %o", dir, error);
|
|
49
50
|
return;
|
|
50
51
|
}
|
|
51
52
|
for (const entry of entries) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
export const READ_ONLY_COMMENTS = [
|
|
2
2
|
"This code was automatically generated from an OpenAPI description.",
|
|
3
3
|
"Do not edit this file. Edit the OpenAPI file instead.",
|
|
4
|
-
"For more information, see https://github.com/pmcelhaney/counterfact/blob/main/docs/faq
|
|
4
|
+
"For more information, see https://github.com/pmcelhaney/counterfact/blob/main/docs/faq.md",
|
|
5
5
|
];
|
|
@@ -36,7 +36,14 @@ export class Requirement {
|
|
|
36
36
|
// Unescape URL encoded characters (e.g. %20 -> " ")
|
|
37
37
|
// Technically we should not be unescaping, but it came up in https://github.com/pmcelhaney/counterfact/issues/1083
|
|
38
38
|
// and I can't think of a reason anyone would intentionally put a % in a key name.
|
|
39
|
-
.map(
|
|
39
|
+
.map((part) => {
|
|
40
|
+
try {
|
|
41
|
+
return decodeURIComponent(part);
|
|
42
|
+
}
|
|
43
|
+
catch {
|
|
44
|
+
return part;
|
|
45
|
+
}
|
|
46
|
+
});
|
|
40
47
|
// eslint-disable-next-line @typescript-eslint/no-this-alias
|
|
41
48
|
let result = this;
|
|
42
49
|
for (const part of parts) {
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Lexical_grammar#reserved_words
|
|
2
|
+
export const RESERVED_WORDS = new Set([
|
|
3
|
+
"break",
|
|
4
|
+
"case",
|
|
5
|
+
"catch",
|
|
6
|
+
"class",
|
|
7
|
+
"const",
|
|
8
|
+
"continue",
|
|
9
|
+
"debugger",
|
|
10
|
+
"default",
|
|
11
|
+
"delete",
|
|
12
|
+
"do",
|
|
13
|
+
"else",
|
|
14
|
+
"export",
|
|
15
|
+
"extends",
|
|
16
|
+
"false",
|
|
17
|
+
"finally",
|
|
18
|
+
"for",
|
|
19
|
+
"function",
|
|
20
|
+
"if",
|
|
21
|
+
"import",
|
|
22
|
+
"in",
|
|
23
|
+
"instanceof",
|
|
24
|
+
"new",
|
|
25
|
+
"null",
|
|
26
|
+
"return",
|
|
27
|
+
"static",
|
|
28
|
+
"super",
|
|
29
|
+
"switch",
|
|
30
|
+
"this",
|
|
31
|
+
"throw",
|
|
32
|
+
"true",
|
|
33
|
+
"try",
|
|
34
|
+
"typeof",
|
|
35
|
+
"var",
|
|
36
|
+
"void",
|
|
37
|
+
"while",
|
|
38
|
+
"with",
|
|
39
|
+
"yield",
|
|
40
|
+
"await",
|
|
41
|
+
"enum",
|
|
42
|
+
"implements",
|
|
43
|
+
"interface",
|
|
44
|
+
"let",
|
|
45
|
+
"package",
|
|
46
|
+
"private",
|
|
47
|
+
"protected",
|
|
48
|
+
"public",
|
|
49
|
+
"type",
|
|
50
|
+
]);
|
|
@@ -1,8 +1,12 @@
|
|
|
1
|
+
import { buildJsDoc } from "./jsdoc.js";
|
|
1
2
|
import { TypeCoder } from "./type-coder.js";
|
|
2
3
|
export class SchemaTypeCoder extends TypeCoder {
|
|
3
4
|
names() {
|
|
4
5
|
return super.names(this.requirement.data["$ref"]?.split("/").at(-1));
|
|
5
6
|
}
|
|
7
|
+
jsdoc() {
|
|
8
|
+
return buildJsDoc(this.requirement.data);
|
|
9
|
+
}
|
|
6
10
|
additionalPropertiesType(script) {
|
|
7
11
|
const { additionalProperties, properties } = this.requirement.data;
|
|
8
12
|
if (!additionalProperties.type) {
|
|
@@ -22,7 +26,9 @@ export class SchemaTypeCoder extends TypeCoder {
|
|
|
22
26
|
const propertyData = property.data;
|
|
23
27
|
const isRequired = typedData.required?.includes(name) || propertyData.required === true;
|
|
24
28
|
const optionalFlag = isRequired ? "" : "?";
|
|
25
|
-
|
|
29
|
+
const comment = buildJsDoc(property.data);
|
|
30
|
+
const commentPrefix = comment ? `\n${comment}` : "";
|
|
31
|
+
return `${commentPrefix}"${name}"${optionalFlag}: ${new SchemaTypeCoder(property).write(script)}`;
|
|
26
32
|
});
|
|
27
33
|
if (typedData.additionalProperties) {
|
|
28
34
|
properties.push(`[key: string]: ${this.additionalPropertiesType(script)}`);
|
|
@@ -50,6 +50,7 @@ export class Script {
|
|
|
50
50
|
id: coder.id,
|
|
51
51
|
isDefault,
|
|
52
52
|
isType,
|
|
53
|
+
jsdoc: "",
|
|
53
54
|
typeDeclaration: coder.typeDeclaration(this.exports, this),
|
|
54
55
|
};
|
|
55
56
|
exportStatement.promise = coder
|
|
@@ -57,6 +58,7 @@ export class Script {
|
|
|
57
58
|
.then((availableCoder) => {
|
|
58
59
|
exportStatement.name = name;
|
|
59
60
|
exportStatement.code = availableCoder.write(this);
|
|
61
|
+
exportStatement.jsdoc = availableCoder.jsdoc();
|
|
60
62
|
return availableCoder;
|
|
61
63
|
})
|
|
62
64
|
.catch((error) => {
|
|
@@ -134,18 +136,18 @@ export class Script {
|
|
|
134
136
|
});
|
|
135
137
|
}
|
|
136
138
|
exportStatements() {
|
|
137
|
-
return Array.from(this.exports.values(), ({ beforeExport, code, isDefault, isType, name, typeDeclaration }) => {
|
|
139
|
+
return Array.from(this.exports.values(), ({ beforeExport, code, isDefault, isType, jsdoc, name, typeDeclaration, }) => {
|
|
138
140
|
if (typeof code === "object" && code !== null && "raw" in code) {
|
|
139
141
|
return code.raw;
|
|
140
142
|
}
|
|
141
143
|
if (isDefault) {
|
|
142
|
-
return `${beforeExport}export default ${code};`;
|
|
144
|
+
return `${jsdoc}${beforeExport}export default ${code};`;
|
|
143
145
|
}
|
|
144
146
|
const keyword = isType ? "type" : "const";
|
|
145
147
|
const typeAnnotation = (typeDeclaration ?? "").length === 0
|
|
146
148
|
? ""
|
|
147
149
|
: `:${typeDeclaration ?? ""}`;
|
|
148
|
-
return `${beforeExport}export ${keyword} ${name ?? ""}${typeAnnotation} = ${code};`;
|
|
150
|
+
return `${jsdoc}${beforeExport}export ${keyword} ${name ?? ""}${typeAnnotation} = ${code};`;
|
|
149
151
|
});
|
|
150
152
|
}
|
|
151
153
|
contents() {
|
|
@@ -21,6 +21,12 @@ export class Specification {
|
|
|
21
21
|
return this.rootRequirement.select(url.slice(2));
|
|
22
22
|
}
|
|
23
23
|
async load(urlOrPath) {
|
|
24
|
-
|
|
24
|
+
try {
|
|
25
|
+
this.rootRequirement = new Requirement((await bundle(urlOrPath)), urlOrPath, this);
|
|
26
|
+
}
|
|
27
|
+
catch (error) {
|
|
28
|
+
const details = error instanceof Error ? error.message : String(error);
|
|
29
|
+
throw new Error(`Could not load the OpenAPI spec from "${urlOrPath}".\n${details}`, { cause: error });
|
|
30
|
+
}
|
|
25
31
|
}
|
|
26
32
|
}
|
|
@@ -0,0 +1,44 @@
|
|
|
1
|
+
import { readFile } from "node:fs/promises";
|
|
2
|
+
import { load as loadYaml } from "js-yaml";
|
|
3
|
+
function kebabToCamel(str) {
|
|
4
|
+
return str.replace(/-([a-z])/g, (_, letter) => letter.toUpperCase());
|
|
5
|
+
}
|
|
6
|
+
function normalizeKeys(obj) {
|
|
7
|
+
return Object.fromEntries(Object.entries(obj).map(([key, value]) => [kebabToCamel(key), value]));
|
|
8
|
+
}
|
|
9
|
+
/**
|
|
10
|
+
* Loads and parses a counterfact YAML config file.
|
|
11
|
+
*
|
|
12
|
+
* @param configPath - Absolute or relative path to the config file.
|
|
13
|
+
* @param required - When true, throws if the file does not exist.
|
|
14
|
+
* When false (default), returns an empty object for missing files.
|
|
15
|
+
* @returns A plain object of config keys (camelCase) to values.
|
|
16
|
+
*/
|
|
17
|
+
export async function loadConfigFile(configPath, required = false) {
|
|
18
|
+
let content;
|
|
19
|
+
try {
|
|
20
|
+
content = await readFile(configPath, "utf8");
|
|
21
|
+
}
|
|
22
|
+
catch (error) {
|
|
23
|
+
if (typeof error === "object" &&
|
|
24
|
+
error !== null &&
|
|
25
|
+
"code" in error &&
|
|
26
|
+
error.code === "ENOENT") {
|
|
27
|
+
if (required) {
|
|
28
|
+
throw new Error(`Config file not found: ${configPath}`, {
|
|
29
|
+
cause: error,
|
|
30
|
+
});
|
|
31
|
+
}
|
|
32
|
+
return {};
|
|
33
|
+
}
|
|
34
|
+
throw error;
|
|
35
|
+
}
|
|
36
|
+
const parsed = loadYaml(content);
|
|
37
|
+
if (parsed === null || parsed === undefined) {
|
|
38
|
+
return {};
|
|
39
|
+
}
|
|
40
|
+
if (typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
41
|
+
throw new Error(`Config file must be a YAML object (mapping): ${configPath}`);
|
|
42
|
+
}
|
|
43
|
+
return normalizeKeys(parsed);
|
|
44
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import { mkdtempSync, writeFileSync, rmSync } from "node:fs";
|
|
2
|
+
import { tmpdir } from "node:os";
|
|
3
|
+
import { join } from "node:path";
|
|
4
|
+
import { pathToFileURL } from "node:url";
|
|
5
|
+
export async function runtimeCanExecuteErasableTs() {
|
|
6
|
+
const dir = mkdtempSync(join(tmpdir(), "ts-probe-"));
|
|
7
|
+
// helper.ts is imported via .js extension — the TypeScript convention used
|
|
8
|
+
// throughout this codebase. If the runtime resolves helper.js → helper.ts,
|
|
9
|
+
// it is fully capable of running the TypeScript source tree.
|
|
10
|
+
writeFileSync(join(dir, "helper.ts"), 'export const value: string = "ok";\n', "utf8");
|
|
11
|
+
writeFileSync(join(dir, "main.ts"), 'import { value } from "./helper.js"; export default value;\n', "utf8");
|
|
12
|
+
try {
|
|
13
|
+
const mod = await import(pathToFileURL(join(dir, "main.ts")).href);
|
|
14
|
+
return mod?.default === "ok";
|
|
15
|
+
}
|
|
16
|
+
catch {
|
|
17
|
+
return false;
|
|
18
|
+
}
|
|
19
|
+
finally {
|
|
20
|
+
rmSync(dir, { recursive: true, force: true });
|
|
21
|
+
}
|
|
22
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "counterfact",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.7.0",
|
|
4
4
|
"description": "Generate a TypeScript-based mock server from an OpenAPI spec in seconds — with stateful routes, hot reload, and REPL support.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/app.js",
|
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
"license": "MIT",
|
|
22
22
|
"repository": {
|
|
23
23
|
"type": "git",
|
|
24
|
-
"url": "https://github.com/pmcelhaney/counterfact.git"
|
|
24
|
+
"url": "git+https://github.com/pmcelhaney/counterfact.git"
|
|
25
25
|
},
|
|
26
26
|
"bugs": "https://github.com/pmcelhaney/counterfact/issues",
|
|
27
27
|
"homepage": "https://counterfact.dev",
|
|
@@ -56,7 +56,7 @@
|
|
|
56
56
|
"node": ">=22"
|
|
57
57
|
},
|
|
58
58
|
"bin": {
|
|
59
|
-
"counterfact": "
|
|
59
|
+
"counterfact": "bin/counterfact.js"
|
|
60
60
|
},
|
|
61
61
|
"files": [
|
|
62
62
|
"bin",
|
|
@@ -67,7 +67,7 @@
|
|
|
67
67
|
"test": "yarn node --experimental-vm-modules ./node_modules/jest-cli/bin/jest --testPathIgnorePatterns=black-box",
|
|
68
68
|
"test:black-box": "rimraf dist && yarn build && python3 -m pytest test-black-box/ -v",
|
|
69
69
|
"test:tsd": "tsd --typings ./dist/server/counterfact-types/index.ts --files ./test/**/*.test-d.ts",
|
|
70
|
-
"build": "rm -rf dist && tsc && copyfiles -f \"src/
|
|
70
|
+
"build": "rm -rf dist && tsc && copyfiles -f \"src/counterfact-types/*.ts\" dist/server/counterfact-types && copyfiles -f \"src/server/*.cjs\" dist/server",
|
|
71
71
|
"prepack": "yarn build",
|
|
72
72
|
"release": "npx changeset publish",
|
|
73
73
|
"prepare": "husky install",
|
|
@@ -84,7 +84,7 @@
|
|
|
84
84
|
"@changesets/cli": "2.30.0",
|
|
85
85
|
"@eslint/js": "10.0.1",
|
|
86
86
|
"@jest/globals": "^30.3.0",
|
|
87
|
-
"@swc/core": "1.15.
|
|
87
|
+
"@swc/core": "1.15.24",
|
|
88
88
|
"@swc/jest": "0.2.39",
|
|
89
89
|
"@testing-library/dom": "10.4.1",
|
|
90
90
|
"@types/debug": "^4.1.12",
|
|
@@ -94,12 +94,11 @@
|
|
|
94
94
|
"@types/koa-bodyparser": "4.3.13",
|
|
95
95
|
"@types/koa-proxy": "1.0.8",
|
|
96
96
|
"@types/koa-static": "4.0.4",
|
|
97
|
-
"@types/lodash": "4.17.24",
|
|
98
97
|
"@types/node": "22",
|
|
99
|
-
"@typescript-eslint/eslint-plugin": "^8.
|
|
100
|
-
"@typescript-eslint/parser": "^8.
|
|
98
|
+
"@typescript-eslint/eslint-plugin": "^8.58.0",
|
|
99
|
+
"@typescript-eslint/parser": "^8.58.0",
|
|
101
100
|
"copyfiles": "2.4.1",
|
|
102
|
-
"eslint": "10.
|
|
101
|
+
"eslint": "10.2.0",
|
|
103
102
|
"eslint-formatter-github-annotations": "0.1.0",
|
|
104
103
|
"eslint-import-resolver-typescript": "4.4.4",
|
|
105
104
|
"eslint-plugin-etc": "2.0.3",
|
|
@@ -127,12 +126,11 @@
|
|
|
127
126
|
"@apidevtools/json-schema-ref-parser": "13.0.5",
|
|
128
127
|
"@hapi/accept": "6.0.3",
|
|
129
128
|
"@types/json-schema": "7.0.15",
|
|
129
|
+
"ajv": "8.18.0",
|
|
130
130
|
"chokidar": "5.0.0",
|
|
131
131
|
"commander": "14.0.3",
|
|
132
132
|
"debug": "4.4.3",
|
|
133
|
-
"fetch": "1.1.0",
|
|
134
133
|
"fs-extra": "11.3.4",
|
|
135
|
-
"handlebars": "4.7.9",
|
|
136
134
|
"http-terminator": "3.2.0",
|
|
137
135
|
"js-yaml": "4.1.1",
|
|
138
136
|
"json-schema-faker": "0.6.0",
|
|
@@ -141,12 +139,14 @@
|
|
|
141
139
|
"koa-bodyparser": "4.4.1",
|
|
142
140
|
"koa-proxies": "0.12.4",
|
|
143
141
|
"koa2-swagger-ui": "5.12.0",
|
|
144
|
-
"lodash": "4.18.1",
|
|
145
142
|
"node-fetch": "3.3.2",
|
|
146
143
|
"open": "11.0.0",
|
|
147
144
|
"patch-package": "8.0.1",
|
|
145
|
+
"posthog-node": "^5.28.11",
|
|
148
146
|
"precinct": "12.2.0",
|
|
149
147
|
"prettier": "3.8.1",
|
|
148
|
+
"recast": "0.23.11",
|
|
149
|
+
"tsx": "^4.20.3",
|
|
150
150
|
"typescript": "6.0.2"
|
|
151
151
|
},
|
|
152
152
|
"packageManager": "yarn@1.22.22+sha512.a6b2f7906b721bba3d67d4aff083df04dad64c399707841b7acf00f6b133b7ac24255f2652fa22ae3534329dc6180534e98d17432037ff6fd140556e2bb3137e",
|
package/dist/client/README.md
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
# `src/client/` — Built-in UI Templates
|
|
2
|
-
|
|
3
|
-
This directory contains [Handlebars](https://handlebarsjs.com/) (`.hbs`) templates that are rendered by `page-middleware.ts` to produce the browser-facing pages bundled with Counterfact.
|
|
4
|
-
|
|
5
|
-
## Files
|
|
6
|
-
|
|
7
|
-
| File | Description |
|
|
8
|
-
|---|---|
|
|
9
|
-
| `index.html.hbs` | Template for the Counterfact dashboard (`/counterfact/`); lists registered routes and shows server status |
|
|
10
|
-
| `rapi-doc.html.hbs` | Template for the interactive API documentation page (`/counterfact/swagger/`); embeds the [RapiDoc](https://rapidocweb.com/) viewer and adds VSCode "open file" links |
|
|
11
|
-
|
|
12
|
-
## How It Works
|
|
13
|
-
|
|
14
|
-
When a request arrives for `/counterfact/` or `/counterfact/swagger/`, `page-middleware.ts` compiles the appropriate template with runtime data (routes, port, base path, etc.) and sends the resulting HTML to the browser. No build step is required; templates are rendered on the fly.
|