thinkwell 0.5.5 → 0.5.7
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/agent.d.ts.map +1 -1
- package/dist/agent.js +232 -278
- package/dist/agent.js.map +1 -1
- package/dist/build.js +44 -98
- package/dist/cli/build.js +92 -227
- package/dist/cli/bundle.js +570 -1136
- package/dist/cli/check.js +125 -214
- package/dist/cli/commands.js +63 -177
- package/dist/cli/compiler-host.js +81 -190
- package/dist/cli/dependency-check.js +125 -269
- package/dist/cli/dependency-errors.js +12 -84
- package/dist/cli/fmt.js +1 -13
- package/dist/cli/init-command.js +21 -68
- package/dist/cli/init.js +90 -220
- package/dist/cli/loader.js +95 -361
- package/dist/cli/new-command.js +25 -73
- package/dist/cli/package-manager.js +50 -117
- package/dist/cli/schema.d.ts.map +1 -1
- package/dist/cli/schema.js +91 -245
- package/dist/cli/schema.js.map +1 -1
- package/dist/cli/workspace.js +92 -226
- package/dist/connectors/index.js +1 -7
- package/dist/generated/features.d.ts +6 -0
- package/dist/generated/features.d.ts.map +1 -0
- package/dist/generated/features.js +5 -0
- package/dist/generated/features.js.map +1 -0
- package/dist/index.js +0 -5
- package/dist/schema.js +3 -36
- package/dist/session.js +50 -82
- package/dist/think-builder.d.ts.map +1 -1
- package/dist/think-builder.js +287 -368
- package/dist/think-builder.js.map +1 -1
- package/dist/thought-event.d.ts +1 -0
- package/dist/thought-event.d.ts.map +1 -1
- package/dist/thought-event.js +0 -1
- package/dist/thought-stream.js +60 -96
- package/dist-pkg/acp.cjs +13386 -1876
- package/dist-pkg/cli-build.cjs +264 -446
- package/dist-pkg/cli-bundle.cjs +433 -818
- package/dist-pkg/cli-check.cjs +302 -499
- package/dist-pkg/cli-dependency-check.cjs +39 -82
- package/dist-pkg/cli-dependency-errors.cjs +9 -41
- package/dist-pkg/cli-loader.cjs +91 -173
- package/dist-pkg/protocol.cjs +2 -8
- package/dist-pkg/thinkwell.cjs +927 -1846
- package/package.json +9 -7
|
@@ -1,132 +1,65 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Package manager detection for `thinkwell build` and `thinkwell check`.
|
|
3
|
-
*
|
|
4
|
-
* Detects the package manager used by a project by checking for lockfiles
|
|
5
|
-
* and the `packageManager` field in package.json.
|
|
6
|
-
*/
|
|
7
1
|
import { existsSync, readFileSync } from "node:fs";
|
|
8
2
|
import { join } from "node:path";
|
|
9
|
-
// ============================================================================
|
|
10
|
-
// Lockfile detection
|
|
11
|
-
// ============================================================================
|
|
12
|
-
/** Lockfile names in priority order. */
|
|
13
3
|
const LOCKFILES = [
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
4
|
+
{ file: "pnpm-lock.yaml", pm: "pnpm" },
|
|
5
|
+
{ file: "yarn.lock", pm: "yarn" },
|
|
6
|
+
{ file: "package-lock.json", pm: "npm" }
|
|
17
7
|
];
|
|
18
|
-
/**
|
|
19
|
-
* Detect package manager by checking for lockfiles.
|
|
20
|
-
* Returns the first lockfile found, or null if none exist.
|
|
21
|
-
*/
|
|
22
8
|
function detectByLockfile(projectDir) {
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
return null;
|
|
9
|
+
for (const { file, pm } of LOCKFILES) {
|
|
10
|
+
const lockfilePath = join(projectDir, file);
|
|
11
|
+
if (existsSync(lockfilePath))
|
|
12
|
+
return { pm, lockfile: file };
|
|
13
|
+
}
|
|
14
|
+
return null;
|
|
30
15
|
}
|
|
31
|
-
// ============================================================================
|
|
32
|
-
// packageManager field parsing
|
|
33
|
-
// ============================================================================
|
|
34
|
-
/**
|
|
35
|
-
* Parse the `packageManager` field from package.json.
|
|
36
|
-
*
|
|
37
|
-
* The field format is defined by corepack: `<name>@<version>`
|
|
38
|
-
* Examples: "pnpm@9.0.0", "yarn@4.0.0", "npm@10.0.0"
|
|
39
|
-
*
|
|
40
|
-
* Returns the package manager name, or null if the field is missing/invalid.
|
|
41
|
-
*/
|
|
42
16
|
export function parsePackageManagerField(value) {
|
|
43
|
-
|
|
44
|
-
return null;
|
|
45
|
-
}
|
|
46
|
-
// Parse the name part (before @version)
|
|
47
|
-
const atIndex = value.indexOf("@");
|
|
48
|
-
const name = atIndex > 0 ? value.slice(0, atIndex) : value;
|
|
49
|
-
// Validate against known package managers
|
|
50
|
-
if (name === "pnpm" || name === "npm" || name === "yarn") {
|
|
51
|
-
return name;
|
|
52
|
-
}
|
|
17
|
+
if (typeof value != "string")
|
|
53
18
|
return null;
|
|
19
|
+
const atIndex = value.indexOf("@"), name = atIndex > 0 ? value.slice(0, atIndex) : value;
|
|
20
|
+
return name === "pnpm" || name === "npm" || name === "yarn" ? name : null;
|
|
54
21
|
}
|
|
55
|
-
/**
|
|
56
|
-
* Detect package manager by reading the `packageManager` field from package.json.
|
|
57
|
-
*/
|
|
58
22
|
function detectByPackageJson(projectDir) {
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
catch {
|
|
69
|
-
return null;
|
|
70
|
-
}
|
|
23
|
+
const pkgPath = join(projectDir, "package.json");
|
|
24
|
+
if (!existsSync(pkgPath))
|
|
25
|
+
return null;
|
|
26
|
+
try {
|
|
27
|
+
const content = readFileSync(pkgPath, "utf-8"), pkg = JSON.parse(content);
|
|
28
|
+
return parsePackageManagerField(pkg.packageManager);
|
|
29
|
+
} catch {
|
|
30
|
+
return null;
|
|
31
|
+
}
|
|
71
32
|
}
|
|
72
|
-
// ============================================================================
|
|
73
|
-
// Command generation
|
|
74
|
-
// ============================================================================
|
|
75
|
-
/**
|
|
76
|
-
* Create a PackageManagerInfo object for the given package manager.
|
|
77
|
-
*/
|
|
78
33
|
function createPackageManagerInfo(name, lockfile) {
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
34
|
+
return {
|
|
35
|
+
name,
|
|
36
|
+
lockfile,
|
|
37
|
+
addCommand: (pkg, dev) => {
|
|
38
|
+
switch (name) {
|
|
39
|
+
case "pnpm":
|
|
40
|
+
return dev ? `pnpm add -D ${pkg}` : `pnpm add ${pkg}`;
|
|
41
|
+
case "yarn":
|
|
42
|
+
return dev ? `yarn add -D ${pkg}` : `yarn add ${pkg}`;
|
|
43
|
+
case "npm":
|
|
44
|
+
return dev ? `npm install -D ${pkg}` : `npm install ${pkg}`;
|
|
45
|
+
}
|
|
46
|
+
},
|
|
47
|
+
whyCommand: (pkg) => {
|
|
48
|
+
switch (name) {
|
|
49
|
+
case "pnpm":
|
|
50
|
+
return ["pnpm", "why", pkg, "--json"];
|
|
51
|
+
case "yarn":
|
|
52
|
+
return ["yarn", "why", pkg, "--json"];
|
|
53
|
+
case "npm":
|
|
54
|
+
return ["npm", "why", pkg, "--json"];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
};
|
|
103
58
|
}
|
|
104
|
-
// ============================================================================
|
|
105
|
-
// Main detection function
|
|
106
|
-
// ============================================================================
|
|
107
|
-
/**
|
|
108
|
-
* Detect the package manager for a project.
|
|
109
|
-
*
|
|
110
|
-
* Detection priority:
|
|
111
|
-
* 1. Lockfile presence (pnpm-lock.yaml > yarn.lock > package-lock.json)
|
|
112
|
-
* 2. `packageManager` field in package.json
|
|
113
|
-
* 3. Default to npm
|
|
114
|
-
*
|
|
115
|
-
* @param projectDir - The project directory to check
|
|
116
|
-
* @returns Package manager information
|
|
117
|
-
*/
|
|
118
59
|
export function detectPackageManager(projectDir) {
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
// 2. Fall back to packageManager field (may be aspirational)
|
|
125
|
-
const fromField = detectByPackageJson(projectDir);
|
|
126
|
-
if (fromField) {
|
|
127
|
-
return createPackageManagerInfo(fromField, null);
|
|
128
|
-
}
|
|
129
|
-
// 3. Default to npm
|
|
130
|
-
return createPackageManagerInfo("npm", null);
|
|
60
|
+
const lockfileResult = detectByLockfile(projectDir);
|
|
61
|
+
if (lockfileResult)
|
|
62
|
+
return createPackageManagerInfo(lockfileResult.pm, lockfileResult.lockfile);
|
|
63
|
+
const fromField = detectByPackageJson(projectDir);
|
|
64
|
+
return createPackageManagerInfo(fromField || "npm", null);
|
|
131
65
|
}
|
|
132
|
-
//# sourceMappingURL=package-manager.js.map
|
package/dist/cli/schema.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/cli/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.d.ts","sourceRoot":"","sources":["../../src/cli/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAY5B;;GAEG;AACH,MAAM,WAAW,QAAQ;IACvB,mEAAmE;IACnE,IAAI,EAAE,MAAM,CAAC;IACb,8BAA8B;IAC9B,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC;IACd,+DAA+D;IAC/D,aAAa,EAAE,MAAM,CAAC;IACtB,6DAA6D;IAC7D,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,oDAAoD;IACpD,MAAM,EAAE,MAAM,CAAC;IACf,4EAA4E;IAC5E,iBAAiB,EAAE,MAAM,CAAC;IAC1B,4DAA4D;IAC5D,UAAU,EAAE,OAAO,CAAC;CACrB;AAUD;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,QAAQ,EAAE,CAoDxE;AAqCD;;;;;;;;;;;;GAYG;AACH,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,KAAK,EAAE,QAAQ,EAAE,EACjB,UAAU,CAAC,EAAE,MAAM,EACnB,UAAU,CAAC,EAAE,MAAM,GAClB,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CA4BrB;AAWD;;GAEG;AACH,MAAM,WAAW,SAAS;IACxB,6CAA6C;IAC7C,QAAQ,EAAE,MAAM,CAAC;IACjB,yBAAyB;IACzB,IAAI,EAAE,MAAM,CAAC;CACd;AAyBD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,QAAQ,EAAE,EACjB,OAAO,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAC3B,SAAS,EAAE,CAiBb;AAED;;;;;GAKG;AACH,wBAAgB,oBAAoB,IAAI,MAAM,CAI7C;AAED;;;;;;GAMG;AACH,wBAAgB,eAAe,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,SAAS,EAAE,GAAG,MAAM,CAM/E;AAMD;;;;;;;;GAQG;AACH,wBAAgB,oBAAoB,CAAC,MAAM,EAAE,MAAM,GAAG,OAAO,CAE5D;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,EAAE,MAAM,GAAG,MAAM,CA0B9F"}
|
package/dist/cli/schema.js
CHANGED
|
@@ -1,272 +1,118 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Standalone schema generation for the compiled binary.
|
|
3
|
-
*
|
|
4
|
-
* This module provides schema generation functionality for the CLI. It handles:
|
|
5
|
-
*
|
|
6
|
-
* 1. **Type Discovery**: Finding types marked with @JSONSchema JSDoc tag
|
|
7
|
-
* 2. **Schema Generation**: Delegating to the thinkwell/build API
|
|
8
|
-
* 3. **Code Injection**: Generating namespace declarations with SchemaProvider
|
|
9
|
-
*
|
|
10
|
-
* Schema generation is handled by the `thinkwell/build` module, which
|
|
11
|
-
* encapsulates all interaction with `ts-json-schema-generator`. In
|
|
12
|
-
* explicit-config mode, the build API is resolved from the project's
|
|
13
|
-
* `node_modules` so the project-local version is used. In zero-config mode,
|
|
14
|
-
* the bundled version is used directly.
|
|
15
|
-
*
|
|
16
|
-
* Unlike the bun-plugin which operates at bundle time with caching across files,
|
|
17
|
-
* this module operates at runtime on individual user scripts.
|
|
18
|
-
*/
|
|
19
1
|
import ts from "typescript";
|
|
20
2
|
import { join } from "node:path";
|
|
21
3
|
import { createRequire } from "node:module";
|
|
22
4
|
import { generateSchemas as bundledGenerateSchemas } from "../build.js";
|
|
23
|
-
|
|
24
|
-
// Type Discovery
|
|
25
|
-
// =============================================================================
|
|
5
|
+
import { extractShebang } from "./loader.js";
|
|
26
6
|
const JSONSCHEMA_TAG = "JSONSchema";
|
|
27
|
-
/**
|
|
28
|
-
* Check if a node has a JSDoc comment with the specified tag.
|
|
29
|
-
*/
|
|
30
7
|
function hasJsDocTag(node, tagName) {
|
|
31
|
-
|
|
32
|
-
return jsDocNodes.some((tag) => tag.tagName.text === tagName);
|
|
8
|
+
return ts.getJSDocTags(node).some((tag) => tag.tagName.text === tagName);
|
|
33
9
|
}
|
|
34
|
-
/**
|
|
35
|
-
* Find all types marked with @JSONSchema in the given source.
|
|
36
|
-
*
|
|
37
|
-
* @param path - The file path (used for source file creation)
|
|
38
|
-
* @param source - The TypeScript source code
|
|
39
|
-
* @returns Array of TypeInfo for each marked type
|
|
40
|
-
*/
|
|
41
10
|
export function findMarkedTypes(path, source) {
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
ts.
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
declarationLength,
|
|
72
|
-
isExported,
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
}
|
|
76
|
-
}
|
|
77
|
-
ts.forEachChild(node, visit);
|
|
78
|
-
});
|
|
79
|
-
return results;
|
|
11
|
+
const sourceFile = ts.createSourceFile(
|
|
12
|
+
path,
|
|
13
|
+
source,
|
|
14
|
+
ts.ScriptTarget.Latest,
|
|
15
|
+
!0
|
|
16
|
+
// setParentNodes - needed for JSDoc traversal
|
|
17
|
+
), results = [];
|
|
18
|
+
return ts.forEachChild(sourceFile, function visit(node) {
|
|
19
|
+
if ((ts.isInterfaceDeclaration(node) || ts.isTypeAliasDeclaration(node) || ts.isEnumDeclaration(node) || ts.isClassDeclaration(node)) && hasJsDocTag(node, JSONSCHEMA_TAG)) {
|
|
20
|
+
const name = node.name?.text;
|
|
21
|
+
if (name) {
|
|
22
|
+
const { line, character } = sourceFile.getLineAndCharacterOfPosition(node.getStart());
|
|
23
|
+
let keyword = "interface";
|
|
24
|
+
ts.isTypeAliasDeclaration(node) ? keyword = "type" : ts.isEnumDeclaration(node) ? keyword = "enum" : ts.isClassDeclaration(node) && (keyword = "class");
|
|
25
|
+
const declarationLength = keyword.length + 1 + name.length, isExported = node.modifiers?.some((m) => m.kind === ts.SyntaxKind.ExportKeyword) ?? !1;
|
|
26
|
+
results.push({
|
|
27
|
+
name,
|
|
28
|
+
node,
|
|
29
|
+
startPosition: node.getStart(),
|
|
30
|
+
endPosition: node.getEnd(),
|
|
31
|
+
line: line + 1,
|
|
32
|
+
column: character + 1,
|
|
33
|
+
declarationLength,
|
|
34
|
+
isExported
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
ts.forEachChild(node, visit);
|
|
39
|
+
}), results;
|
|
80
40
|
}
|
|
81
|
-
// =============================================================================
|
|
82
|
-
// Schema Generation
|
|
83
|
-
// =============================================================================
|
|
84
|
-
/**
|
|
85
|
-
* Resolve the `generateSchemas` function from the thinkwell/build API.
|
|
86
|
-
*
|
|
87
|
-
* When `projectDir` is provided (explicit-config mode), resolves
|
|
88
|
-
* `thinkwell/build` from the project's `node_modules` and uses its
|
|
89
|
-
* exported `generateSchemas`. This ensures schema generation uses the
|
|
90
|
-
* project-local version of `ts-json-schema-generator` (encapsulated
|
|
91
|
-
* inside `thinkwell/build`), without leaking it into the user's contract.
|
|
92
|
-
*
|
|
93
|
-
* In explicit-config mode, resolution failure is an error — `thinkwell`
|
|
94
|
-
* is a checked dependency, so `thinkwell/build` is guaranteed available.
|
|
95
|
-
* Silently falling back to the bundled version would hide version
|
|
96
|
-
* mismatches.
|
|
97
|
-
*
|
|
98
|
-
* Returns the bundled version only in zero-config mode (no projectDir).
|
|
99
|
-
*/
|
|
100
41
|
function resolveGenerateSchemas(projectDir) {
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
`This may indicate a version mismatch — try updating the thinkwell dependency.`);
|
|
109
|
-
}
|
|
110
|
-
return bundledGenerateSchemas;
|
|
42
|
+
if (projectDir) {
|
|
43
|
+
const buildMod = createRequire(join(projectDir, "package.json"))("thinkwell/build");
|
|
44
|
+
if (typeof buildMod.generateSchemas == "function")
|
|
45
|
+
return buildMod.generateSchemas;
|
|
46
|
+
throw new Error(`thinkwell/build resolved from ${projectDir} but does not export generateSchemas. This may indicate a version mismatch \u2014 try updating the thinkwell dependency.`);
|
|
47
|
+
}
|
|
48
|
+
return bundledGenerateSchemas;
|
|
111
49
|
}
|
|
112
|
-
/**
|
|
113
|
-
* Generate JSON schemas for the given types.
|
|
114
|
-
*
|
|
115
|
-
* Delegates to the `thinkwell/build` API (project-local or bundled) for
|
|
116
|
-
* the actual schema generation. This module only handles type discovery,
|
|
117
|
-
* error formatting, and code injection.
|
|
118
|
-
*
|
|
119
|
-
* @param path - The path to the TypeScript file
|
|
120
|
-
* @param types - The types to generate schemas for
|
|
121
|
-
* @param sourceCode - The source code (for error messages)
|
|
122
|
-
* @param projectDir - Optional project root for resolving project-local build API
|
|
123
|
-
* @returns Map from type name to JSON schema object
|
|
124
|
-
*/
|
|
125
50
|
export function generateSchemas(path, types, sourceCode, projectDir) {
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
return schemas;
|
|
129
|
-
}
|
|
130
|
-
const buildGenerateSchemas = resolveGenerateSchemas(projectDir);
|
|
131
|
-
for (const typeInfo of types) {
|
|
132
|
-
const { name, line, column } = typeInfo;
|
|
133
|
-
try {
|
|
134
|
-
const result = buildGenerateSchemas(path, [name]);
|
|
135
|
-
const schema = result.get(name);
|
|
136
|
-
if (schema) {
|
|
137
|
-
schemas.set(name, schema);
|
|
138
|
-
}
|
|
139
|
-
}
|
|
140
|
-
catch (error) {
|
|
141
|
-
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
142
|
-
throw new Error(`Failed to generate schema for type '${name}' at ${path}:${line}:${column}\n` +
|
|
143
|
-
` ${errorMessage}\n` +
|
|
144
|
-
` Ensure the type is exported and uses only JSON-compatible features.`);
|
|
145
|
-
}
|
|
146
|
-
}
|
|
51
|
+
const schemas = /* @__PURE__ */ new Map();
|
|
52
|
+
if (types.length === 0)
|
|
147
53
|
return schemas;
|
|
54
|
+
const buildGenerateSchemas = resolveGenerateSchemas(projectDir);
|
|
55
|
+
for (const typeInfo of types) {
|
|
56
|
+
const { name, line, column } = typeInfo;
|
|
57
|
+
try {
|
|
58
|
+
const schema = buildGenerateSchemas(path, [name]).get(name);
|
|
59
|
+
schema && schemas.set(name, schema);
|
|
60
|
+
} catch (error) {
|
|
61
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
62
|
+
throw new Error(`Failed to generate schema for type '${name}' at ${path}:${line}:${column}
|
|
63
|
+
${errorMessage}
|
|
64
|
+
Ensure the type is exported and uses only JSON-compatible features.`);
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return schemas;
|
|
148
68
|
}
|
|
149
|
-
// =============================================================================
|
|
150
|
-
// Code Generation
|
|
151
|
-
// =============================================================================
|
|
152
|
-
/**
|
|
153
|
-
* Mangled namespace name for the thinkwell/acp import.
|
|
154
|
-
*/
|
|
155
69
|
const ACP_NAMESPACE = "$$__thinkwell__acp__$$";
|
|
156
|
-
/**
|
|
157
|
-
* Generate a namespace declaration for a single type.
|
|
158
|
-
*
|
|
159
|
-
* If the original type declaration is exported, the namespace is also exported
|
|
160
|
-
* so that cross-file imports (e.g. `import { Greeting } from "./types.js"`)
|
|
161
|
-
* can access `Greeting.Schema`.
|
|
162
|
-
*/
|
|
163
70
|
function generateNamespace(name, schema, isExported) {
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
].join("\n");
|
|
71
|
+
const schemaJson = JSON.stringify(schema, null, 2).split(`
|
|
72
|
+
`).map((line, i) => i === 0 ? line : " " + line).join(`
|
|
73
|
+
`);
|
|
74
|
+
return [
|
|
75
|
+
`${isExported ? "export " : ""}namespace ${name} {`,
|
|
76
|
+
` export const Schema: ${ACP_NAMESPACE}.SchemaProvider<${name}> = {`,
|
|
77
|
+
` toJsonSchema: () => (${schemaJson}) as ${ACP_NAMESPACE}.JsonSchema,`,
|
|
78
|
+
" };",
|
|
79
|
+
"}"
|
|
80
|
+
].join(`
|
|
81
|
+
`);
|
|
176
82
|
}
|
|
177
|
-
/**
|
|
178
|
-
* Generate insertions for namespace declarations.
|
|
179
|
-
*
|
|
180
|
-
* @param types - The types to generate namespaces for
|
|
181
|
-
* @param schemas - Map from type name to JSON schema object
|
|
182
|
-
* @returns Array of insertions sorted by position (descending)
|
|
183
|
-
*/
|
|
184
83
|
export function generateInsertions(types, schemas) {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
}
|
|
196
|
-
// Sort by position descending for safe end-to-start insertion
|
|
197
|
-
return insertions.sort((a, b) => b.position - a.position);
|
|
84
|
+
const insertions = [];
|
|
85
|
+
for (const { name, endPosition, isExported } of types) {
|
|
86
|
+
const schema = schemas.get(name);
|
|
87
|
+
schema && insertions.push({
|
|
88
|
+
position: endPosition,
|
|
89
|
+
code: `
|
|
90
|
+
` + generateNamespace(name, schema, isExported)
|
|
91
|
+
});
|
|
92
|
+
}
|
|
93
|
+
return insertions.sort((a, b) => b.position - a.position);
|
|
198
94
|
}
|
|
199
|
-
/**
|
|
200
|
-
* Generate the import statement for injected code.
|
|
201
|
-
*
|
|
202
|
-
* For the compiled binary, we use the bundled module registry instead of
|
|
203
|
-
* a real import, since the types are available at runtime via global.__bundled__.
|
|
204
|
-
*/
|
|
205
95
|
export function generateSchemaImport() {
|
|
206
|
-
|
|
207
|
-
// but we still need the type declaration for TypeScript
|
|
208
|
-
return `import type * as ${ACP_NAMESPACE} from "@thinkwell/acp";`;
|
|
96
|
+
return `import type * as ${ACP_NAMESPACE} from "@thinkwell/acp";`;
|
|
209
97
|
}
|
|
210
|
-
/**
|
|
211
|
-
* Apply insertions to source code.
|
|
212
|
-
*
|
|
213
|
-
* @param source - The original source code
|
|
214
|
-
* @param insertions - Insertions to apply (must be sorted by position descending)
|
|
215
|
-
* @returns The modified source code
|
|
216
|
-
*/
|
|
217
98
|
export function applyInsertions(source, insertions) {
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
return result;
|
|
99
|
+
let result = source;
|
|
100
|
+
for (const { position, code } of insertions)
|
|
101
|
+
result = result.slice(0, position) + code + result.slice(position);
|
|
102
|
+
return result;
|
|
223
103
|
}
|
|
224
|
-
// =============================================================================
|
|
225
|
-
// Main Transform Function
|
|
226
|
-
// =============================================================================
|
|
227
|
-
/**
|
|
228
|
-
* Check if source code contains @JSONSchema markers.
|
|
229
|
-
*
|
|
230
|
-
* This is a fast string check to avoid full AST parsing for files
|
|
231
|
-
* that don't use the feature.
|
|
232
|
-
*
|
|
233
|
-
* @param source - The script source code
|
|
234
|
-
* @returns true if the source may contain @JSONSchema types
|
|
235
|
-
*/
|
|
236
104
|
export function hasJsonSchemaMarkers(source) {
|
|
237
|
-
|
|
105
|
+
return source.includes("@JSONSchema");
|
|
238
106
|
}
|
|
239
|
-
/**
|
|
240
|
-
* Transform source code by processing @JSONSchema types.
|
|
241
|
-
*
|
|
242
|
-
* This function:
|
|
243
|
-
* 1. Finds types marked with @JSONSchema
|
|
244
|
-
* 2. Generates JSON schemas for each type
|
|
245
|
-
* 3. Injects namespace declarations with SchemaProvider implementations
|
|
246
|
-
* 4. Adds the necessary type import
|
|
247
|
-
*
|
|
248
|
-
* @param path - The file path
|
|
249
|
-
* @param source - The TypeScript source code
|
|
250
|
-
* @param projectDir - Optional project root for resolving project-local ts-json-schema-generator
|
|
251
|
-
* @returns The transformed source code, or the original if no transforms needed
|
|
252
|
-
*/
|
|
253
107
|
export function transformJsonSchemas(path, source, projectDir) {
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
const schemas = generateSchemas(path, markedTypes, source, projectDir);
|
|
265
|
-
// Generate and apply insertions
|
|
266
|
-
const insertions = generateInsertions(markedTypes, schemas);
|
|
267
|
-
let modifiedSource = applyInsertions(source, insertions);
|
|
268
|
-
// Add the type import at the beginning
|
|
269
|
-
modifiedSource = generateSchemaImport() + "\n" + modifiedSource;
|
|
270
|
-
return modifiedSource;
|
|
108
|
+
if (!hasJsonSchemaMarkers(source))
|
|
109
|
+
return source;
|
|
110
|
+
const markedTypes = findMarkedTypes(path, source);
|
|
111
|
+
if (markedTypes.length === 0)
|
|
112
|
+
return source;
|
|
113
|
+
const schemas = generateSchemas(path, markedTypes, source, projectDir), insertions = generateInsertions(markedTypes, schemas);
|
|
114
|
+
let modifiedSource = applyInsertions(source, insertions);
|
|
115
|
+
const [shebang, rest] = extractShebang(modifiedSource);
|
|
116
|
+
return modifiedSource = shebang + generateSchemaImport() + `
|
|
117
|
+
` + rest, modifiedSource;
|
|
271
118
|
}
|
|
272
|
-
//# sourceMappingURL=schema.js.map
|
package/dist/cli/schema.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/cli/schema.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AAEH,OAAO,EAAE,MAAM,YAAY,CAAC;AAC5B,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AACjC,OAAO,EAAE,aAAa,EAAE,MAAM,aAAa,CAAC;AAC5C,OAAO,EAAE,eAAe,IAAI,sBAAsB,EAAE,MAAM,aAAa,CAAC;
|
|
1
|
+
{"version":3,"file":"schema.js","sourceRoot":"","sources":["../../src/cli/schema.ts"],"names":[],"mappings":"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"}
|