@openpkg-ts/sdk 0.53.1 → 0.54.1
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 +3 -3
- package/dist/index.d.ts +4 -51
- package/dist/index.js +188 -576
- package/package.json +1 -5
package/README.md
CHANGED
|
@@ -89,11 +89,11 @@ const { spec, diagnostics, verification } = await extractSpec({
|
|
|
89
89
|
maxTypeDepth: 4,
|
|
90
90
|
only: ['use*'], // filter by pattern
|
|
91
91
|
ignore: ['*Internal'], // exclude by pattern
|
|
92
|
-
followExternal: ['@ai-sdk/*'], // or true
|
|
92
|
+
followExternal: ['@ai-sdk/*'], // or true
|
|
93
93
|
});
|
|
94
94
|
```
|
|
95
95
|
|
|
96
|
-
|
|
96
|
+
Specs record `generation.entryPoint` and `generation.entryPointSource` (`types` / `exports` / `fallback` / `explicit` / `llm`).
|
|
97
97
|
|
|
98
98
|
### resolveTarget
|
|
99
99
|
|
|
@@ -111,7 +111,7 @@ if (resolved.kind === 'ok') {
|
|
|
111
111
|
}
|
|
112
112
|
```
|
|
113
113
|
|
|
114
|
-
|
|
114
|
+
GitHub URLs clone via `gh` if present, else `git clone --depth 1`.
|
|
115
115
|
|
|
116
116
|
### diffSpecs
|
|
117
117
|
|
package/dist/index.d.ts
CHANGED
|
@@ -1,42 +1,5 @@
|
|
|
1
1
|
import { BreakingSeverity, CategorizedBreaking, calculateNextVersion, categorizeBreakingChanges, diffSpec, diffSpec as diffSpec2, MemberChangeInfo, recommendSemverBump, SemverBump, SemverRecommendation, SpecDiff } from "@openpkg-ts/spec";
|
|
2
2
|
import { EntryPointDetectionMethod, OpenPkg } from "@openpkg-ts/spec";
|
|
3
|
-
declare const JEV_MODEL = "typesafe-ai/jev";
|
|
4
|
-
declare const JEV_CONFIDENCE = .5;
|
|
5
|
-
type ChoiceQuestion = {
|
|
6
|
-
type: "choice";
|
|
7
|
-
instructions: string;
|
|
8
|
-
criteria: Record<string, string>;
|
|
9
|
-
};
|
|
10
|
-
type ScoreQuestion = {
|
|
11
|
-
type: "score";
|
|
12
|
-
instructions: string;
|
|
13
|
-
criteria: string[];
|
|
14
|
-
};
|
|
15
|
-
type EvaluateQuestion = ChoiceQuestion | ScoreQuestion;
|
|
16
|
-
type EvaluateRequest = {
|
|
17
|
-
model: string;
|
|
18
|
-
state: unknown;
|
|
19
|
-
questions: Record<string, EvaluateQuestion>;
|
|
20
|
-
providerOptions?: {
|
|
21
|
-
gateway?: {
|
|
22
|
-
zeroDataRetention?: boolean;
|
|
23
|
-
};
|
|
24
|
-
};
|
|
25
|
-
};
|
|
26
|
-
type EvaluateAnswer = {
|
|
27
|
-
choice?: string;
|
|
28
|
-
score?: number;
|
|
29
|
-
probabilities?: Record<string, number>;
|
|
30
|
-
};
|
|
31
|
-
type EvaluateResult = {
|
|
32
|
-
answers: Record<string, EvaluateAnswer>;
|
|
33
|
-
providerMetadata?: {
|
|
34
|
-
typesafe?: {
|
|
35
|
-
confidence?: Record<string, number>;
|
|
36
|
-
};
|
|
37
|
-
};
|
|
38
|
-
};
|
|
39
|
-
type EvaluateFn = (request: EvaluateRequest) => Promise<EvaluateResult>;
|
|
40
3
|
/** Configuration for resolving external package re-exports */
|
|
41
4
|
interface ExternalsConfig {
|
|
42
5
|
/** Package patterns to resolve (globs supported, e.g., "@myorg/*") */
|
|
@@ -84,9 +47,7 @@ interface ExtractOptions {
|
|
|
84
47
|
* - `false` → disable the reachability-expansion pass entirely
|
|
85
48
|
* - default → workspace siblings only; everything else stubbed
|
|
86
49
|
*/
|
|
87
|
-
followExternal?: boolean | string[]
|
|
88
|
-
evaluate?: EvaluateFn;
|
|
89
|
-
decisions?: "heuristic" | "jev";
|
|
50
|
+
followExternal?: boolean | string[];
|
|
90
51
|
/** Callback when properties are truncated */
|
|
91
52
|
onTruncation?: (typeName: string, actual: number, limit: number) => void;
|
|
92
53
|
}
|
|
@@ -189,13 +150,11 @@ interface OpenpkgConfig {
|
|
|
189
150
|
* them as opaque stubs. `true` follows every dependency; a string[] follows
|
|
190
151
|
* only the named packages (by declaring package name). Default: stub.
|
|
191
152
|
*/
|
|
192
|
-
followExternal?: boolean | string[]
|
|
153
|
+
followExternal?: boolean | string[];
|
|
193
154
|
/** Only extract these exports (supports * wildcards). */
|
|
194
155
|
only?: string[];
|
|
195
156
|
/** Ignore these exports (supports * wildcards). */
|
|
196
157
|
ignore?: string[];
|
|
197
|
-
/** Use Jev for package/entry routing. Requires AI_GATEWAY_API_KEY. */
|
|
198
|
-
decisions?: "heuristic" | "jev";
|
|
199
158
|
}
|
|
200
159
|
/** Default config filename */
|
|
201
160
|
declare const CONFIG_FILENAME = "openpkg.config.json";
|
|
@@ -1077,8 +1036,6 @@ type ResolveTargetOptions = {
|
|
|
1077
1036
|
input?: string;
|
|
1078
1037
|
intent?: string;
|
|
1079
1038
|
cwd?: string;
|
|
1080
|
-
decisions?: "heuristic" | "jev";
|
|
1081
|
-
evaluate?: EvaluateFn;
|
|
1082
1039
|
clone?: CloneFn;
|
|
1083
1040
|
};
|
|
1084
1041
|
type ResolveOk = {
|
|
@@ -1106,11 +1063,7 @@ type ResolveExplicit = {
|
|
|
1106
1063
|
entryFile: string;
|
|
1107
1064
|
entryPointSource: "explicit";
|
|
1108
1065
|
};
|
|
1109
|
-
type
|
|
1110
|
-
kind: "unavailable";
|
|
1111
|
-
reason: string;
|
|
1112
|
-
};
|
|
1113
|
-
type ResolveTargetResult = (ResolveOk | ResolveAmbiguous | ResolveNeedsBuild | ResolveEmpty | ResolveExplicit | ResolveUnavailable) & {
|
|
1066
|
+
type ResolveTargetResult = (ResolveOk | ResolveAmbiguous | ResolveNeedsBuild | ResolveEmpty | ResolveExplicit) & {
|
|
1114
1067
|
/** Present when this resolution owns a temp clone. Call after extraction. */
|
|
1115
1068
|
cleanup?: () => void;
|
|
1116
1069
|
};
|
|
@@ -2030,4 +1983,4 @@ declare function findDiscriminatorProperty(unionTypes: ts16.Type[], checker: ts1
|
|
|
2030
1983
|
import ts17 from "typescript";
|
|
2031
1984
|
declare function isExported(node: ts17.Node): boolean;
|
|
2032
1985
|
declare function getNodeName(node: ts17.Node): string | undefined;
|
|
2033
|
-
export { zodAdapter, writtenTypeText, withDescription2 as withDescription, withDeprecated, validateSpec, valibotAdapter, typeboxAdapter, toToolSchema, toSearchIndexJSON, toSearchIndex2 as toSearchIndex, toPagefindRecords2 as toPagefindRecords, toNavigation2 as toNavigation, toMarkdown2 as toMarkdown, toJsonSchema, toJSONString, toJSON2 as toJSON, toHTML2 as toHTML, toFumadocsMetaJSON, toDocusaurusSidebarJS, toAlgoliaRecords2 as toAlgoliaRecords, stripUndefinedFromType, stripTsExtensions, sortByName, shouldEmitAliasTypeText, serializeVariable, serializeTypeAlias, serializeInterface, serializeFunctionExport, serializeEnum, serializeClass, scrubImportQualifiers, schemasAreEqual, schemaIsAny, resolveTypeRef, resolveTarget, resolveExportTarget, resolveCompiledPath, renderTypeText, registerReferencedTypes, registerAdapter, recommendSemverBump, query, pickEntry, parseGithubRepo, normalizeType, normalizeSchema, normalizeMembers, normalizeExport, mergeConfig, loadSpec, loadConfig, listExports, isTypeReference, isTypeOnlyExport, isSymbolDeprecated, isStandardJSONSchema, isSchemaType, isRemoteInput, isReadonlyPropertySymbol, isPureRefSchema, isProperty, isPrimitiveName, isPathLikeInput, isMethod, isExported, isEntryFilePath, isBuiltinSymbol, isBuiltinGeneric, isAnonymous, groupByVisibility, getValidationErrors, getTypeOrigin, getSourceLocation, getProperties, getParamDescription, getNonNullableType, getNodeName, getMethods, getMemberBadges, getJSDocComment, getExportKind, getExport2 as getExport, getAvailableVersions, toMarkdown2 as generateDocs, formatTypeParameters, formatSchema, formatReturnType, formatParameters, formatMappedType, formatConditionalType, formatBadges, findWorkspaceRoot, findDiscriminatorProperty, findAdapter, filterSpec, extractTypeParameters, extractStandardSchemasFromTs, extractStandardSchemasFromProject, extractStandardSchemas, extractSpec, extractSchemaType, extractParameters, extract, exportToMarkdown, exportToJsonSchema, ensureNonEmptySchema, diffSpec2 as diffSpecs, diffSpec, detectTsRuntime, deduplicateSchemas, decoratePropertySchema, declaredTypeNode, createProgram, createDocs, cloneRemote, categorizeBreakingChanges, catalogPackages, calculateNextVersion, bundleRefs, buildSignatureString, buildSchema, buildObjectSchema, buildFunctionSchema, assertSpec, asStandardSchema, arktypeAdapter, TypeRegistry, TypeReference2 as TypeReference, TsRuntime, ToolSchemaResult, ToolSchemaProvider, ToToolSchemaOptions, ToJsonSchemaOptions, StandardSchemaExtractionResult, StandardSchemaExtractionOutput, StandardJSONSchemaV1, StandardJSONSchemaTarget, StandardJSONSchemaOptions, SpecMappedType, SpecError, SpecDiff, SpecConditionalType, SkippedExportDetail, SimplifiedSpec, SimplifiedSignature, SimplifiedReturn, SimplifiedParameter, SimplifiedMember, SimplifiedExport, SimplifiedExample, SerializerContext, SemverRecommendation, SemverBump, SearchRecord, SearchOptions, SearchIndex, SchemaVersion, SchemaExtractionResult, SchemaAdapter, STRING_PROTOTYPE_METHODS,
|
|
1986
|
+
export { zodAdapter, writtenTypeText, withDescription2 as withDescription, withDeprecated, validateSpec, valibotAdapter, typeboxAdapter, toToolSchema, toSearchIndexJSON, toSearchIndex2 as toSearchIndex, toPagefindRecords2 as toPagefindRecords, toNavigation2 as toNavigation, toMarkdown2 as toMarkdown, toJsonSchema, toJSONString, toJSON2 as toJSON, toHTML2 as toHTML, toFumadocsMetaJSON, toDocusaurusSidebarJS, toAlgoliaRecords2 as toAlgoliaRecords, stripUndefinedFromType, stripTsExtensions, sortByName, shouldEmitAliasTypeText, serializeVariable, serializeTypeAlias, serializeInterface, serializeFunctionExport, serializeEnum, serializeClass, scrubImportQualifiers, schemasAreEqual, schemaIsAny, resolveTypeRef, resolveTarget, resolveExportTarget, resolveCompiledPath, renderTypeText, registerReferencedTypes, registerAdapter, recommendSemverBump, query, pickEntry, parseGithubRepo, normalizeType, normalizeSchema, normalizeMembers, normalizeExport, mergeConfig, loadSpec, loadConfig, listExports, isTypeReference, isTypeOnlyExport, isSymbolDeprecated, isStandardJSONSchema, isSchemaType, isRemoteInput, isReadonlyPropertySymbol, isPureRefSchema, isProperty, isPrimitiveName, isPathLikeInput, isMethod, isExported, isEntryFilePath, isBuiltinSymbol, isBuiltinGeneric, isAnonymous, groupByVisibility, getValidationErrors, getTypeOrigin, getSourceLocation, getProperties, getParamDescription, getNonNullableType, getNodeName, getMethods, getMemberBadges, getJSDocComment, getExportKind, getExport2 as getExport, getAvailableVersions, toMarkdown2 as generateDocs, formatTypeParameters, formatSchema, formatReturnType, formatParameters, formatMappedType, formatConditionalType, formatBadges, findWorkspaceRoot, findDiscriminatorProperty, findAdapter, filterSpec, extractTypeParameters, extractStandardSchemasFromTs, extractStandardSchemasFromProject, extractStandardSchemas, extractSpec, extractSchemaType, extractParameters, extract, exportToMarkdown, exportToJsonSchema, ensureNonEmptySchema, diffSpec2 as diffSpecs, diffSpec, detectTsRuntime, deduplicateSchemas, decoratePropertySchema, declaredTypeNode, createProgram, createDocs, cloneRemote, categorizeBreakingChanges, catalogPackages, calculateNextVersion, bundleRefs, buildSignatureString, buildSchema, buildObjectSchema, buildFunctionSchema, assertSpec, asStandardSchema, arktypeAdapter, TypeRegistry, TypeReference2 as TypeReference, TsRuntime, ToolSchemaResult, ToolSchemaProvider, ToToolSchemaOptions, ToJsonSchemaOptions, StandardSchemaExtractionResult, StandardSchemaExtractionOutput, StandardJSONSchemaV1, StandardJSONSchemaTarget, StandardJSONSchemaOptions, SpecMappedType, SpecError, SpecDiff, SpecConditionalType, SkippedExportDetail, SimplifiedSpec, SimplifiedSignature, SimplifiedReturn, SimplifiedParameter, SimplifiedMember, SimplifiedExport, SimplifiedExample, SerializerContext, SemverRecommendation, SemverBump, SearchRecord, SearchOptions, SearchIndex, SchemaVersion, SchemaExtractionResult, SchemaAdapter, STRING_PROTOTYPE_METHODS, ResolveTargetResult, ResolveTargetOptions, ResolveOk, ResolveNeedsBuild, ResolveExplicit, ResolveEmpty, ResolveAmbiguous, QueryBuilder, ProjectExtractionOutput, ProjectExtractionInfo, ProgramResult, ProgramOptions, PagefindRecord, PackageRecord, PRIMITIVES, OpenpkgConfig, NormalizeOptions, NavOptions, NavItem, NavGroup, NavFormat, NUMBER_PROTOTYPE_METHODS, MemberChangeInfo, MarkdownOptions, LoadOptions, ListExportsResult, ListExportsOptions, LATEST_VERSION, JsonSchemaDocument, JSONSchema, JSONOptions, HTMLOptions, GroupBy, GetExportResult, GetExportOptions, GenericNav, FumadocsMetaItem, FumadocsMeta, FormatSchemaOptions, ForgottenExport, FilterResult, FilterCriteria, ExtractionWarningCode, ExtractionWarning, ExtractStandardSchemasOptions, ExtractResult, ExtractOptions, ExtractFromProjectOptions, ExternalsConfig, ExportVerification, ExportTracker, ExportMarkdownOptions, ExportItem, DocusaurusSidebarItem, DocusaurusSidebar, DocsInstance, Diagnostic, CloneFn, CategorizedBreaking, CacheManagerOptions, CacheManager, CONFIG_FILENAME, BundleResult, BundleOptions, BuiltinSchema, BreakingSeverity, BUILTIN_TYPE_SCHEMAS, AsStandardSchemaOptions, AlgoliaRecord, ARRAY_PROTOTYPE_METHODS };
|
package/dist/index.js
CHANGED
|
@@ -78,70 +78,9 @@ function mergeConfig(fileConfig, cliOptions) {
|
|
|
78
78
|
...hasExternals ? { externals } : {},
|
|
79
79
|
followExternal: cliOptions.followExternal ?? fileConfig.followExternal,
|
|
80
80
|
only: cliOptions.only ?? fileConfig.only,
|
|
81
|
-
ignore: cliOptions.ignore ?? fileConfig.ignore
|
|
82
|
-
decisions: cliOptions.decisions ?? fileConfig.decisions
|
|
81
|
+
ignore: cliOptions.ignore ?? fileConfig.ignore
|
|
83
82
|
};
|
|
84
83
|
}
|
|
85
|
-
// src/core/decisions.ts
|
|
86
|
-
var JEV_MODEL = "typesafe-ai/jev";
|
|
87
|
-
var JEV_CONFIDENCE = 0.5;
|
|
88
|
-
var MAX_JEV_QUESTIONS = 50;
|
|
89
|
-
async function loadEvaluate() {
|
|
90
|
-
try {
|
|
91
|
-
const specifier = "ai";
|
|
92
|
-
const mod = await import(specifier);
|
|
93
|
-
if (typeof mod.experimental_evaluate !== "function") {
|
|
94
|
-
throw new Error("ai.experimental_evaluate is not a function");
|
|
95
|
-
}
|
|
96
|
-
return (request) => mod.experimental_evaluate({
|
|
97
|
-
...request,
|
|
98
|
-
providerOptions: {
|
|
99
|
-
gateway: { zeroDataRetention: true },
|
|
100
|
-
...request.providerOptions
|
|
101
|
-
}
|
|
102
|
-
});
|
|
103
|
-
} catch (err) {
|
|
104
|
-
const msg = err instanceof Error ? err.message : String(err);
|
|
105
|
-
throw new Error(`--jev requires the ai package (AI SDK ≥7.0.105): bun add ai
|
|
106
|
-
${msg}`);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
function namedConfidence(result, id) {
|
|
110
|
-
const named = result.providerMetadata?.typesafe?.confidence?.[id];
|
|
111
|
-
return typeof named === "number" ? named : undefined;
|
|
112
|
-
}
|
|
113
|
-
function choiceConfidence(result, id, choice) {
|
|
114
|
-
const named = namedConfidence(result, id);
|
|
115
|
-
if (named !== undefined)
|
|
116
|
-
return named;
|
|
117
|
-
const p = result.answers[id]?.probabilities?.[choice];
|
|
118
|
-
return typeof p === "number" ? p : 0;
|
|
119
|
-
}
|
|
120
|
-
async function jevEvaluate(evaluate, state, questions) {
|
|
121
|
-
return evaluate({
|
|
122
|
-
model: JEV_MODEL,
|
|
123
|
-
state: JSON.parse(JSON.stringify(state)),
|
|
124
|
-
questions,
|
|
125
|
-
providerOptions: { gateway: { zeroDataRetention: true } }
|
|
126
|
-
});
|
|
127
|
-
}
|
|
128
|
-
async function jevChoice(args) {
|
|
129
|
-
const keys = Object.keys(args.criteria);
|
|
130
|
-
if (keys.length < 2)
|
|
131
|
-
return null;
|
|
132
|
-
const id = args.id ?? "choice";
|
|
133
|
-
const result = await jevEvaluate(args.evaluate, args.state, {
|
|
134
|
-
[id]: {
|
|
135
|
-
type: "choice",
|
|
136
|
-
instructions: args.instructions,
|
|
137
|
-
criteria: args.criteria
|
|
138
|
-
}
|
|
139
|
-
});
|
|
140
|
-
const choice = result.answers[id]?.choice;
|
|
141
|
-
if (!choice || !(choice in args.criteria))
|
|
142
|
-
return null;
|
|
143
|
-
return { choice, confidence: choiceConfidence(result, id, choice) };
|
|
144
|
-
}
|
|
145
84
|
// src/core/loader.ts
|
|
146
85
|
import * as fs2 from "node:fs";
|
|
147
86
|
import { validateSpec } from "@openpkg-ts/spec";
|
|
@@ -1612,10 +1551,6 @@ function pickEntry(pkgDir) {
|
|
|
1612
1551
|
const best = [...cands].sort((a, b) => scoreCandidate(b) - scoreCandidate(a))[0];
|
|
1613
1552
|
return { entryFile: best.abs, entryPointSource: methodFor(best) };
|
|
1614
1553
|
}
|
|
1615
|
-
function listEntryCandidates(pkgDir) {
|
|
1616
|
-
const pkg = readJson(path2.join(pkgDir, "package.json")) ?? {};
|
|
1617
|
-
return collectCandidates(pkgDir, pkg);
|
|
1618
|
-
}
|
|
1619
1554
|
function isIgnoredPath(dir) {
|
|
1620
1555
|
const norm = dir.split(path2.sep).join("/");
|
|
1621
1556
|
return /\/(examples|fixtures|__tests__|test-fixtures)(\/|$)/.test(norm);
|
|
@@ -1666,80 +1601,9 @@ function buildCommand(pkg) {
|
|
|
1666
1601
|
return "bun run build";
|
|
1667
1602
|
return;
|
|
1668
1603
|
}
|
|
1669
|
-
function
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
} catch {
|
|
1673
|
-
return "";
|
|
1674
|
-
}
|
|
1675
|
-
}
|
|
1676
|
-
var PACKAGE_NONE = "none";
|
|
1677
|
-
async function jevPickPackage(candidates, ctx) {
|
|
1678
|
-
if (!ctx.evaluate || candidates.length < 2)
|
|
1679
|
-
return null;
|
|
1680
|
-
const criteria = {};
|
|
1681
|
-
const byId = new Map;
|
|
1682
|
-
for (const [i, pkg] of candidates.entries()) {
|
|
1683
|
-
const id = `p${i}`;
|
|
1684
|
-
byId.set(id, pkg);
|
|
1685
|
-
criteria[id] = `${pkg.name} — ${pkg.description ?? pkg.dir}${pkg.hasSrc ? " (src)" : ""}`;
|
|
1686
|
-
}
|
|
1687
|
-
criteria[PACKAGE_NONE] = "No single package is the product — these are peer libraries";
|
|
1688
|
-
const picked = await jevChoice({
|
|
1689
|
-
evaluate: ctx.evaluate,
|
|
1690
|
-
instructions: "Which package is the public TypeScript SDK to extract? Prefer the named product, not examples, wasm glue, or private packages.",
|
|
1691
|
-
criteria,
|
|
1692
|
-
state: {
|
|
1693
|
-
intent: ctx.intent ?? null,
|
|
1694
|
-
catalog: candidates.map((p, i) => ({
|
|
1695
|
-
id: `p${i}`,
|
|
1696
|
-
name: p.name,
|
|
1697
|
-
description: p.description ?? null,
|
|
1698
|
-
hasSrc: p.hasSrc,
|
|
1699
|
-
hasDist: p.hasDist,
|
|
1700
|
-
types: p.types ?? p.typings ?? null,
|
|
1701
|
-
private: p.private
|
|
1702
|
-
}))
|
|
1703
|
-
},
|
|
1704
|
-
id: "package"
|
|
1705
|
-
});
|
|
1706
|
-
if (!picked || picked.choice === PACKAGE_NONE)
|
|
1707
|
-
return null;
|
|
1708
|
-
if (picked.confidence < JEV_CONFIDENCE)
|
|
1709
|
-
return null;
|
|
1710
|
-
return byId.get(picked.choice) ?? null;
|
|
1711
|
-
}
|
|
1712
|
-
async function jevPickEntry(cands, ctx) {
|
|
1713
|
-
if (!ctx.evaluate || cands.length < 2)
|
|
1714
|
-
return null;
|
|
1715
|
-
const criteria = {};
|
|
1716
|
-
const byId = new Map;
|
|
1717
|
-
for (const [i, c] of cands.entries()) {
|
|
1718
|
-
const id = `c${i}`;
|
|
1719
|
-
byId.set(id, c);
|
|
1720
|
-
criteria[id] = `${c.rel} (${c.source})`;
|
|
1721
|
-
}
|
|
1722
|
-
const picked = await jevChoice({
|
|
1723
|
-
evaluate: ctx.evaluate,
|
|
1724
|
-
instructions: "Which file is the best OpenPkg entry point? Prefer TypeScript source over .d.ts/.js. Prefer the package root public API.",
|
|
1725
|
-
criteria,
|
|
1726
|
-
state: {
|
|
1727
|
-
candidates: cands.map((c, i) => ({
|
|
1728
|
-
id: `c${i}`,
|
|
1729
|
-
path: c.rel,
|
|
1730
|
-
source: c.source,
|
|
1731
|
-
head: head(c.abs)
|
|
1732
|
-
}))
|
|
1733
|
-
},
|
|
1734
|
-
id: "entry"
|
|
1735
|
-
});
|
|
1736
|
-
if (!picked || picked.confidence < JEV_CONFIDENCE)
|
|
1737
|
-
return null;
|
|
1738
|
-
return byId.get(picked.choice) ?? null;
|
|
1739
|
-
}
|
|
1740
|
-
async function finishPackage(pkg, ctx) {
|
|
1741
|
-
const cands = listEntryCandidates(pkg.dir);
|
|
1742
|
-
if (!cands.length) {
|
|
1604
|
+
function finishPackage(pkg) {
|
|
1605
|
+
const picked = pickEntry(pkg.dir);
|
|
1606
|
+
if (!picked) {
|
|
1743
1607
|
return {
|
|
1744
1608
|
kind: "needs-build",
|
|
1745
1609
|
package: pkg,
|
|
@@ -1747,24 +1611,9 @@ async function finishPackage(pkg, ctx) {
|
|
|
1747
1611
|
...buildCommand(pkg) ? { command: buildCommand(pkg) } : {}
|
|
1748
1612
|
};
|
|
1749
1613
|
}
|
|
1750
|
-
|
|
1751
|
-
let chosen = heuristic;
|
|
1752
|
-
let source = methodFor(heuristic);
|
|
1753
|
-
if (ctx.decisions === "jev" && cands.length >= 2) {
|
|
1754
|
-
const jev = await jevPickEntry(cands, ctx);
|
|
1755
|
-
if (jev) {
|
|
1756
|
-
chosen = jev;
|
|
1757
|
-
source = "llm";
|
|
1758
|
-
}
|
|
1759
|
-
}
|
|
1760
|
-
return {
|
|
1761
|
-
kind: "ok",
|
|
1762
|
-
package: pkg,
|
|
1763
|
-
entryFile: chosen.abs,
|
|
1764
|
-
entryPointSource: source
|
|
1765
|
-
};
|
|
1614
|
+
return { kind: "ok", package: pkg, ...picked };
|
|
1766
1615
|
}
|
|
1767
|
-
|
|
1616
|
+
function resolveLocal(abs, startDir, intent) {
|
|
1768
1617
|
const catalog = catalogPackages(startDir);
|
|
1769
1618
|
if (!catalog.length) {
|
|
1770
1619
|
return { kind: "empty", reason: "no JS/TS packages found" };
|
|
@@ -1772,9 +1621,8 @@ async function resolveLocal(abs, startDir, ctx) {
|
|
|
1772
1621
|
const root = findWorkspaceRoot(startDir);
|
|
1773
1622
|
const pointed = catalog.find((p) => p.dir === abs);
|
|
1774
1623
|
if (pointed && (isExtractable(pointed) || pointed.dir !== root)) {
|
|
1775
|
-
return finishPackage(pointed
|
|
1624
|
+
return finishPackage(pointed);
|
|
1776
1625
|
}
|
|
1777
|
-
const intent = ctx.intent;
|
|
1778
1626
|
if (intent) {
|
|
1779
1627
|
const scored = catalog.map((p) => ({ p, n: intentScore(p, intent) })).filter((x) => x.n > 0).sort((a, b) => b.n - a.n);
|
|
1780
1628
|
if (!scored.length) {
|
|
@@ -1782,61 +1630,30 @@ async function resolveLocal(abs, startDir, ctx) {
|
|
|
1782
1630
|
}
|
|
1783
1631
|
const top = scored.filter((x) => x.n === scored[0].n).map((x) => x.p);
|
|
1784
1632
|
if (top.length === 1)
|
|
1785
|
-
return finishPackage(top[0]
|
|
1786
|
-
if (ctx.decisions === "jev") {
|
|
1787
|
-
const jev = await jevPickPackage(top, ctx);
|
|
1788
|
-
if (jev)
|
|
1789
|
-
return finishPackage(jev, ctx);
|
|
1790
|
-
}
|
|
1633
|
+
return finishPackage(top[0]);
|
|
1791
1634
|
return { kind: "ambiguous", candidates: top };
|
|
1792
1635
|
}
|
|
1793
1636
|
const enclosed = enclosingPackage(startDir, catalog);
|
|
1794
1637
|
if (enclosed && enclosed.dir !== root)
|
|
1795
|
-
return finishPackage(enclosed
|
|
1638
|
+
return finishPackage(enclosed);
|
|
1796
1639
|
const extractable = catalog.filter(isExtractable);
|
|
1797
1640
|
if (extractable.length === 1)
|
|
1798
|
-
return finishPackage(extractable[0]
|
|
1799
|
-
if (extractable.length > 1)
|
|
1800
|
-
if (ctx.decisions === "jev") {
|
|
1801
|
-
const jev = await jevPickPackage(extractable, ctx);
|
|
1802
|
-
if (jev)
|
|
1803
|
-
return finishPackage(jev, ctx);
|
|
1804
|
-
}
|
|
1641
|
+
return finishPackage(extractable[0]);
|
|
1642
|
+
if (extractable.length > 1)
|
|
1805
1643
|
return { kind: "ambiguous", candidates: extractable };
|
|
1806
|
-
}
|
|
1807
1644
|
if (catalog.length === 1)
|
|
1808
|
-
return finishPackage(catalog[0]
|
|
1645
|
+
return finishPackage(catalog[0]);
|
|
1809
1646
|
return { kind: "empty", reason: "no extractable JS/TS packages found" };
|
|
1810
1647
|
}
|
|
1811
1648
|
async function resolveTarget(options = {}) {
|
|
1812
1649
|
const cwd = path2.resolve(options.cwd ?? process.cwd());
|
|
1813
1650
|
const raw = options.input?.trim() || cwd;
|
|
1814
|
-
const
|
|
1815
|
-
const ctx = {
|
|
1816
|
-
decisions,
|
|
1817
|
-
evaluate: options.evaluate,
|
|
1818
|
-
intent: options.intent?.trim() || undefined
|
|
1819
|
-
};
|
|
1820
|
-
if (decisions === "jev" && !ctx.evaluate) {
|
|
1821
|
-
if (!process.env.AI_GATEWAY_API_KEY) {
|
|
1822
|
-
return {
|
|
1823
|
-
kind: "unavailable",
|
|
1824
|
-
reason: `--jev requires AI_GATEWAY_API_KEY
|
|
1825
|
-
https://vercel.com/docs/ai-gateway
|
|
1826
|
-
omit --jev to stay local`
|
|
1827
|
-
};
|
|
1828
|
-
}
|
|
1829
|
-
try {
|
|
1830
|
-
ctx.evaluate = await loadEvaluate();
|
|
1831
|
-
} catch (err) {
|
|
1832
|
-
return { kind: "unavailable", reason: err instanceof Error ? err.message : String(err) };
|
|
1833
|
-
}
|
|
1834
|
-
}
|
|
1651
|
+
const intent = options.intent?.trim() || undefined;
|
|
1835
1652
|
if (isRemoteInput(raw)) {
|
|
1836
1653
|
const owned = !options.clone;
|
|
1837
1654
|
try {
|
|
1838
1655
|
const cloned = await (options.clone ?? cloneRemote)(raw);
|
|
1839
|
-
const result =
|
|
1656
|
+
const result = resolveLocal(cloned, cloned, intent);
|
|
1840
1657
|
if (!owned)
|
|
1841
1658
|
return result;
|
|
1842
1659
|
return {
|
|
@@ -1858,7 +1675,7 @@ async function resolveTarget(options = {}) {
|
|
|
1858
1675
|
return { kind: "empty", reason: `input does not exist: ${options.input?.trim() || raw}` };
|
|
1859
1676
|
}
|
|
1860
1677
|
const startDir = existsDir(abs) ? abs : cwd;
|
|
1861
|
-
return resolveLocal(abs, startDir,
|
|
1678
|
+
return resolveLocal(abs, startDir, intent);
|
|
1862
1679
|
}
|
|
1863
1680
|
// src/primitives/filter.ts
|
|
1864
1681
|
function matchesExport(exp, criteria) {
|
|
@@ -1966,9 +1783,85 @@ function filterSpec(spec, criteria) {
|
|
|
1966
1783
|
// src/primitives/get.ts
|
|
1967
1784
|
import ts13 from "typescript";
|
|
1968
1785
|
|
|
1969
|
-
// src/ast/
|
|
1786
|
+
// src/ast/type-identity.ts
|
|
1970
1787
|
import * as path3 from "node:path";
|
|
1971
1788
|
import ts from "typescript";
|
|
1789
|
+
var NODE_MODULES_PKG = /node_modules\/(@[^/]+\/[^/]+|[^/]+)/g;
|
|
1790
|
+
function isLibFile(fileName) {
|
|
1791
|
+
return fileName.includes("/typescript/lib/lib.") || fileName.includes("\\typescript\\lib\\lib.");
|
|
1792
|
+
}
|
|
1793
|
+
function packageNameFromPath(fileName) {
|
|
1794
|
+
return [...fileName.matchAll(NODE_MODULES_PKG)].at(-1)?.[1];
|
|
1795
|
+
}
|
|
1796
|
+
function packageLabel(fileName, workspacePackages) {
|
|
1797
|
+
let pkg = packageNameFromPath(fileName);
|
|
1798
|
+
if (!pkg) {
|
|
1799
|
+
for (const [name, dir] of workspacePackages) {
|
|
1800
|
+
if (fileName.startsWith(`${path3.resolve(dir)}${path3.sep}`)) {
|
|
1801
|
+
pkg = name;
|
|
1802
|
+
break;
|
|
1803
|
+
}
|
|
1804
|
+
}
|
|
1805
|
+
}
|
|
1806
|
+
return (pkg ?? "local").replace(/^@/, "").replace(/\//g, "-");
|
|
1807
|
+
}
|
|
1808
|
+
function declKey(symbol, checker) {
|
|
1809
|
+
let resolved = symbol;
|
|
1810
|
+
if (symbol.flags & ts.SymbolFlags.Alias) {
|
|
1811
|
+
try {
|
|
1812
|
+
resolved = checker.getAliasedSymbol(symbol);
|
|
1813
|
+
} catch {}
|
|
1814
|
+
}
|
|
1815
|
+
const decl = resolved.declarations?.[0];
|
|
1816
|
+
if (!decl)
|
|
1817
|
+
return;
|
|
1818
|
+
return `${decl.getSourceFile().fileName}#${decl.getStart()}`;
|
|
1819
|
+
}
|
|
1820
|
+
function resolveTypeId(symbol, ctx) {
|
|
1821
|
+
const cached = ctx.typeIds.get(symbol);
|
|
1822
|
+
if (cached)
|
|
1823
|
+
return cached;
|
|
1824
|
+
const key = declKey(symbol, ctx.typeChecker);
|
|
1825
|
+
if (key) {
|
|
1826
|
+
const existing = ctx.declIds.get(key);
|
|
1827
|
+
if (existing) {
|
|
1828
|
+
ctx.typeIds.set(symbol, existing);
|
|
1829
|
+
return existing;
|
|
1830
|
+
}
|
|
1831
|
+
}
|
|
1832
|
+
const claim = (id) => {
|
|
1833
|
+
ctx.typeIds.set(symbol, id);
|
|
1834
|
+
if (key)
|
|
1835
|
+
ctx.declIds.set(key, id);
|
|
1836
|
+
ctx.idOwner.set(id, key ?? id);
|
|
1837
|
+
return id;
|
|
1838
|
+
};
|
|
1839
|
+
const name = symbol.getName();
|
|
1840
|
+
const owner = ctx.idOwner.get(name);
|
|
1841
|
+
if (!owner || owner === key)
|
|
1842
|
+
return claim(name);
|
|
1843
|
+
const file = symbol.declarations?.[0]?.getSourceFile().fileName ?? "";
|
|
1844
|
+
const scoped = `${packageLabel(file, ctx.workspacePackages)}.${name}`;
|
|
1845
|
+
const scopedOwner = ctx.idOwner.get(scoped);
|
|
1846
|
+
if (!scopedOwner || scopedOwner === key)
|
|
1847
|
+
return claim(scoped);
|
|
1848
|
+
let n = 2;
|
|
1849
|
+
while (ctx.idOwner.has(`${name}_${n}`))
|
|
1850
|
+
n++;
|
|
1851
|
+
return claim(`${name}_${n}`);
|
|
1852
|
+
}
|
|
1853
|
+
function typeRefId(type, ctx) {
|
|
1854
|
+
const symbol = type.aliasSymbol ?? type.getSymbol();
|
|
1855
|
+
if (!symbol)
|
|
1856
|
+
return "";
|
|
1857
|
+
if (!ctx)
|
|
1858
|
+
return symbol.getName();
|
|
1859
|
+
return resolveTypeId(symbol, ctx);
|
|
1860
|
+
}
|
|
1861
|
+
|
|
1862
|
+
// src/ast/utils.ts
|
|
1863
|
+
import * as path4 from "node:path";
|
|
1864
|
+
import ts2 from "typescript";
|
|
1972
1865
|
var INLINE_TAG_RE = /(^|[^\\])\{@([a-zA-Z][a-zA-Z0-9]*)((?:[^}\\]|\\.)*)\}/g;
|
|
1973
1866
|
function parseInlineTags(...texts) {
|
|
1974
1867
|
const inlineTags = [];
|
|
@@ -2062,12 +1955,12 @@ function extractSeeTagText(tag) {
|
|
|
2062
1955
|
if (Array.isArray(tag.comment)) {
|
|
2063
1956
|
const parts = [];
|
|
2064
1957
|
for (const part of tag.comment) {
|
|
2065
|
-
if (
|
|
1958
|
+
if (ts2.isJSDocLink(part) || ts2.isJSDocLinkCode(part) || ts2.isJSDocLinkPlain(part)) {
|
|
2066
1959
|
if (part.name) {
|
|
2067
1960
|
try {
|
|
2068
1961
|
parts.push(part.name.getText());
|
|
2069
1962
|
} catch {
|
|
2070
|
-
if (
|
|
1963
|
+
if (ts2.isIdentifier(part.name)) {
|
|
2071
1964
|
parts.push(part.name.text);
|
|
2072
1965
|
}
|
|
2073
1966
|
}
|
|
@@ -2075,7 +1968,7 @@ function extractSeeTagText(tag) {
|
|
|
2075
1968
|
if (part.text) {
|
|
2076
1969
|
parts.push(part.text);
|
|
2077
1970
|
}
|
|
2078
|
-
} else if (part.kind ===
|
|
1971
|
+
} else if (part.kind === ts2.SyntaxKind.JSDocText) {
|
|
2079
1972
|
parts.push(part.text);
|
|
2080
1973
|
}
|
|
2081
1974
|
}
|
|
@@ -2084,13 +1977,13 @@ function extractSeeTagText(tag) {
|
|
|
2084
1977
|
return result;
|
|
2085
1978
|
}
|
|
2086
1979
|
}
|
|
2087
|
-
return typeof tag.comment === "string" ? tag.comment :
|
|
1980
|
+
return typeof tag.comment === "string" ? tag.comment : ts2.getTextOfJSDocComment(tag.comment) ?? "";
|
|
2088
1981
|
}
|
|
2089
1982
|
function getJSDocComment(node, symbol, checker) {
|
|
2090
|
-
const jsDocTags =
|
|
1983
|
+
const jsDocTags = ts2.getJSDocTags(node);
|
|
2091
1984
|
const commentLevelTags = [];
|
|
2092
1985
|
const tags = jsDocTags.map((tag) => {
|
|
2093
|
-
const rawText = typeof tag.comment === "string" ? tag.comment :
|
|
1986
|
+
const rawText = typeof tag.comment === "string" ? tag.comment : ts2.getTextOfJSDocComment(tag.comment) ?? "";
|
|
2094
1987
|
const { retained, hoisted } = tag.tagName.text === "see" ? { retained: rawText, hoisted: [] } : splitCommentLevelTags(rawText);
|
|
2095
1988
|
commentLevelTags.push(...hoisted);
|
|
2096
1989
|
if (tag.tagName.text === "param") {
|
|
@@ -2127,12 +2020,12 @@ function getJSDocComment(node, symbol, checker) {
|
|
|
2127
2020
|
}
|
|
2128
2021
|
return withInlineTags({ name: tag.tagName.text, text: rawText }, retained);
|
|
2129
2022
|
});
|
|
2130
|
-
const jsDocComments =
|
|
2023
|
+
const jsDocComments = ts2.getJSDocCommentsAndTags(node).filter(ts2.isJSDoc);
|
|
2131
2024
|
let description;
|
|
2132
2025
|
if (jsDocComments.length > 0) {
|
|
2133
2026
|
const firstDoc = jsDocComments[0];
|
|
2134
2027
|
if (firstDoc.comment) {
|
|
2135
|
-
description = typeof firstDoc.comment === "string" ? firstDoc.comment :
|
|
2028
|
+
description = typeof firstDoc.comment === "string" ? firstDoc.comment : ts2.getTextOfJSDocComment(firstDoc.comment);
|
|
2136
2029
|
}
|
|
2137
2030
|
}
|
|
2138
2031
|
if (!description && symbol && checker) {
|
|
@@ -2153,7 +2046,7 @@ function getJSDocComment(node, symbol, checker) {
|
|
|
2153
2046
|
}
|
|
2154
2047
|
function getSourceLocation(node, sourceFile) {
|
|
2155
2048
|
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
2156
|
-
const relative3 =
|
|
2049
|
+
const relative3 = path4.relative(process.cwd(), sourceFile.fileName);
|
|
2157
2050
|
const file = relative3.startsWith("..") ? sourceFile.fileName : relative3;
|
|
2158
2051
|
return {
|
|
2159
2052
|
file,
|
|
@@ -2173,7 +2066,7 @@ function getParamDescription(propertyName, jsdocTags, inferredAlias) {
|
|
|
2173
2066
|
}
|
|
2174
2067
|
const isMatch = tagParamName === propertyName || inferredAlias && tagParamName === `${inferredAlias}.${propertyName}` || tagParamName.endsWith(`.${propertyName}`);
|
|
2175
2068
|
if (isMatch) {
|
|
2176
|
-
const comment = typeof tag.comment === "string" ? tag.comment :
|
|
2069
|
+
const comment = typeof tag.comment === "string" ? tag.comment : ts2.getTextOfJSDocComment(tag.comment);
|
|
2177
2070
|
return stripParamSeparator(comment);
|
|
2178
2071
|
}
|
|
2179
2072
|
}
|
|
@@ -2186,11 +2079,11 @@ function extractVarianceModifiers(modifiers) {
|
|
|
2186
2079
|
let hasOut = false;
|
|
2187
2080
|
let isConst;
|
|
2188
2081
|
for (const mod of modifiers) {
|
|
2189
|
-
if (mod.kind ===
|
|
2082
|
+
if (mod.kind === ts2.SyntaxKind.InKeyword)
|
|
2190
2083
|
hasIn = true;
|
|
2191
|
-
if (mod.kind ===
|
|
2084
|
+
if (mod.kind === ts2.SyntaxKind.OutKeyword)
|
|
2192
2085
|
hasOut = true;
|
|
2193
|
-
if (mod.kind ===
|
|
2086
|
+
if (mod.kind === ts2.SyntaxKind.ConstKeyword)
|
|
2194
2087
|
isConst = true;
|
|
2195
2088
|
}
|
|
2196
2089
|
const variance = hasIn && hasOut ? "inout" : hasIn ? "in" : hasOut ? "out" : undefined;
|
|
@@ -2212,7 +2105,7 @@ function extractTypeParameters(node, checker) {
|
|
|
2212
2105
|
const defType = checker.getTypeAtLocation(tp.default);
|
|
2213
2106
|
defaultType = checker.typeToString(defType);
|
|
2214
2107
|
}
|
|
2215
|
-
const { variance, isConst } = extractVarianceModifiers(
|
|
2108
|
+
const { variance, isConst } = extractVarianceModifiers(ts2.getModifiers(tp));
|
|
2216
2109
|
return {
|
|
2217
2110
|
name,
|
|
2218
2111
|
...constraint ? { constraint } : {},
|
|
@@ -2233,7 +2126,7 @@ function isSymbolDeprecated(symbol) {
|
|
|
2233
2126
|
return { deprecated: true, reason };
|
|
2234
2127
|
}
|
|
2235
2128
|
for (const declaration of symbol.getDeclarations() ?? []) {
|
|
2236
|
-
const tag =
|
|
2129
|
+
const tag = ts2.getJSDocDeprecatedTag(declaration);
|
|
2237
2130
|
if (tag) {
|
|
2238
2131
|
let reason;
|
|
2239
2132
|
if (typeof tag.comment === "string") {
|
|
@@ -2243,10 +2136,10 @@ function isSymbolDeprecated(symbol) {
|
|
|
2243
2136
|
}
|
|
2244
2137
|
return { deprecated: true, reason };
|
|
2245
2138
|
}
|
|
2246
|
-
if (
|
|
2139
|
+
if (ts2.isExportSpecifier(declaration)) {
|
|
2247
2140
|
const exportDecl = declaration.parent?.parent;
|
|
2248
|
-
if (exportDecl &&
|
|
2249
|
-
const parentTag =
|
|
2141
|
+
if (exportDecl && ts2.isExportDeclaration(exportDecl)) {
|
|
2142
|
+
const parentTag = ts2.getJSDocDeprecatedTag(exportDecl);
|
|
2250
2143
|
if (parentTag) {
|
|
2251
2144
|
let reason;
|
|
2252
2145
|
if (typeof parentTag.comment === "string") {
|
|
@@ -2291,8 +2184,8 @@ function extractTypeParametersFromSignature(signature, checker) {
|
|
|
2291
2184
|
const tpSymbol = tp.getSymbol();
|
|
2292
2185
|
const declarations = tpSymbol?.getDeclarations() ?? [];
|
|
2293
2186
|
for (const decl of declarations) {
|
|
2294
|
-
if (
|
|
2295
|
-
({ variance, isConst } = extractVarianceModifiers(
|
|
2187
|
+
if (ts2.isTypeParameterDeclaration(decl)) {
|
|
2188
|
+
({ variance, isConst } = extractVarianceModifiers(ts2.getModifiers(decl)));
|
|
2296
2189
|
break;
|
|
2297
2190
|
}
|
|
2298
2191
|
}
|
|
@@ -2306,60 +2199,60 @@ function extractTypeParametersFromSignature(signature, checker) {
|
|
|
2306
2199
|
});
|
|
2307
2200
|
}
|
|
2308
2201
|
function getExportKind(declaration, type) {
|
|
2309
|
-
if (
|
|
2202
|
+
if (ts2.isFunctionDeclaration(declaration) || ts2.isFunctionExpression(declaration))
|
|
2310
2203
|
return "function";
|
|
2311
|
-
if (
|
|
2204
|
+
if (ts2.isClassDeclaration(declaration))
|
|
2312
2205
|
return "class";
|
|
2313
|
-
if (
|
|
2206
|
+
if (ts2.isInterfaceDeclaration(declaration))
|
|
2314
2207
|
return "interface";
|
|
2315
|
-
if (
|
|
2208
|
+
if (ts2.isTypeAliasDeclaration(declaration))
|
|
2316
2209
|
return "type";
|
|
2317
|
-
if (
|
|
2210
|
+
if (ts2.isEnumDeclaration(declaration))
|
|
2318
2211
|
return "enum";
|
|
2319
|
-
if (
|
|
2212
|
+
if (ts2.isModuleDeclaration(declaration) || ts2.isNamespaceExport(declaration))
|
|
2320
2213
|
return "namespace";
|
|
2321
|
-
if (
|
|
2214
|
+
if (ts2.isVariableDeclaration(declaration) && type.getConstructSignatures().length > 0)
|
|
2322
2215
|
return "class";
|
|
2323
|
-
if (
|
|
2216
|
+
if (ts2.isVariableDeclaration(declaration) && type.getCallSignatures().length > 0)
|
|
2324
2217
|
return "function";
|
|
2325
2218
|
return "variable";
|
|
2326
2219
|
}
|
|
2327
2220
|
|
|
2328
2221
|
// src/compiler/program.ts
|
|
2329
2222
|
import * as fs4 from "node:fs";
|
|
2330
|
-
import * as
|
|
2331
|
-
import
|
|
2223
|
+
import * as path5 from "node:path";
|
|
2224
|
+
import ts3 from "typescript";
|
|
2332
2225
|
function isJsFile(file) {
|
|
2333
2226
|
return /\.(js|mjs|cjs|jsx)$/.test(file);
|
|
2334
2227
|
}
|
|
2335
2228
|
function getScriptKind(file) {
|
|
2336
2229
|
if (/\.tsx$/.test(file))
|
|
2337
|
-
return
|
|
2230
|
+
return ts3.ScriptKind.TSX;
|
|
2338
2231
|
if (/\.jsx$/.test(file))
|
|
2339
|
-
return
|
|
2232
|
+
return ts3.ScriptKind.JSX;
|
|
2340
2233
|
if (/\.(js|mjs|cjs)$/.test(file))
|
|
2341
|
-
return
|
|
2342
|
-
return
|
|
2234
|
+
return ts3.ScriptKind.JS;
|
|
2235
|
+
return ts3.ScriptKind.TS;
|
|
2343
2236
|
}
|
|
2344
2237
|
var DEFAULT_COMPILER_OPTIONS = {
|
|
2345
|
-
target:
|
|
2346
|
-
module:
|
|
2238
|
+
target: ts3.ScriptTarget.Latest,
|
|
2239
|
+
module: ts3.ModuleKind.NodeNext,
|
|
2347
2240
|
lib: ["lib.es2021.d.ts"],
|
|
2348
2241
|
declaration: true,
|
|
2349
|
-
moduleResolution:
|
|
2242
|
+
moduleResolution: ts3.ModuleResolutionKind.NodeNext,
|
|
2350
2243
|
strict: true
|
|
2351
2244
|
};
|
|
2352
2245
|
function resolveWorkspaceEntry(pkgDir) {
|
|
2353
2246
|
const candidates = [
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2247
|
+
path5.join(pkgDir, "src", "index.ts"),
|
|
2248
|
+
path5.join(pkgDir, "src", "index.tsx"),
|
|
2249
|
+
path5.join(pkgDir, "index.ts")
|
|
2357
2250
|
];
|
|
2358
2251
|
try {
|
|
2359
|
-
const pkg = JSON.parse(fs4.readFileSync(
|
|
2252
|
+
const pkg = JSON.parse(fs4.readFileSync(path5.join(pkgDir, "package.json"), "utf-8"));
|
|
2360
2253
|
for (const field of [pkg.types, pkg.typings]) {
|
|
2361
2254
|
if (typeof field === "string") {
|
|
2362
|
-
candidates.push(
|
|
2255
|
+
candidates.push(path5.resolve(pkgDir, field));
|
|
2363
2256
|
}
|
|
2364
2257
|
}
|
|
2365
2258
|
} catch {}
|
|
@@ -2371,51 +2264,51 @@ function isDirentDir2(parent, entry) {
|
|
|
2371
2264
|
if (!entry.isSymbolicLink())
|
|
2372
2265
|
return false;
|
|
2373
2266
|
try {
|
|
2374
|
-
return fs4.statSync(
|
|
2267
|
+
return fs4.statSync(path5.join(parent, entry.name)).isDirectory();
|
|
2375
2268
|
} catch {
|
|
2376
2269
|
return false;
|
|
2377
2270
|
}
|
|
2378
2271
|
}
|
|
2379
2272
|
function extensionOf(file) {
|
|
2380
2273
|
if (file.endsWith(".d.mts"))
|
|
2381
|
-
return
|
|
2274
|
+
return ts3.Extension.Dmts;
|
|
2382
2275
|
if (file.endsWith(".d.cts"))
|
|
2383
|
-
return
|
|
2276
|
+
return ts3.Extension.Dcts;
|
|
2384
2277
|
if (file.endsWith(".d.ts"))
|
|
2385
|
-
return
|
|
2278
|
+
return ts3.Extension.Dts;
|
|
2386
2279
|
if (file.endsWith(".mts"))
|
|
2387
|
-
return
|
|
2280
|
+
return ts3.Extension.Mts;
|
|
2388
2281
|
if (file.endsWith(".cts"))
|
|
2389
|
-
return
|
|
2282
|
+
return ts3.Extension.Cts;
|
|
2390
2283
|
if (file.endsWith(".tsx"))
|
|
2391
|
-
return
|
|
2284
|
+
return ts3.Extension.Tsx;
|
|
2392
2285
|
if (file.endsWith(".ts"))
|
|
2393
|
-
return
|
|
2286
|
+
return ts3.Extension.Ts;
|
|
2394
2287
|
if (file.endsWith(".mjs"))
|
|
2395
|
-
return
|
|
2288
|
+
return ts3.Extension.Mjs;
|
|
2396
2289
|
if (file.endsWith(".cjs"))
|
|
2397
|
-
return
|
|
2290
|
+
return ts3.Extension.Cjs;
|
|
2398
2291
|
if (file.endsWith(".jsx"))
|
|
2399
|
-
return
|
|
2292
|
+
return ts3.Extension.Jsx;
|
|
2400
2293
|
if (file.endsWith(".js"))
|
|
2401
|
-
return
|
|
2402
|
-
return
|
|
2294
|
+
return ts3.Extension.Js;
|
|
2295
|
+
return ts3.Extension.Ts;
|
|
2403
2296
|
}
|
|
2404
2297
|
function resolveProjectReferences(configPath, parsedConfig) {
|
|
2405
2298
|
const additionalFiles = [];
|
|
2406
2299
|
if (!parsedConfig.projectReferences?.length) {
|
|
2407
2300
|
return additionalFiles;
|
|
2408
2301
|
}
|
|
2409
|
-
const configDir =
|
|
2302
|
+
const configDir = path5.dirname(configPath);
|
|
2410
2303
|
for (const ref of parsedConfig.projectReferences) {
|
|
2411
|
-
const refPath =
|
|
2412
|
-
const refConfigPath = fs4.existsSync(
|
|
2304
|
+
const refPath = path5.resolve(configDir, ref.path);
|
|
2305
|
+
const refConfigPath = fs4.existsSync(path5.join(refPath, "tsconfig.json")) ? path5.join(refPath, "tsconfig.json") : refPath;
|
|
2413
2306
|
if (!fs4.existsSync(refConfigPath))
|
|
2414
2307
|
continue;
|
|
2415
|
-
const refConfigFile =
|
|
2308
|
+
const refConfigFile = ts3.readConfigFile(refConfigPath, ts3.sys.readFile);
|
|
2416
2309
|
if (refConfigFile.error)
|
|
2417
2310
|
continue;
|
|
2418
|
-
const refParsed =
|
|
2311
|
+
const refParsed = ts3.parseJsonConfigFileContent(refConfigFile.config, ts3.sys, path5.dirname(refConfigPath));
|
|
2419
2312
|
additionalFiles.push(...refParsed.fileNames);
|
|
2420
2313
|
}
|
|
2421
2314
|
return additionalFiles;
|
|
@@ -2448,7 +2341,7 @@ function buildWorkspaceMap(baseDir) {
|
|
|
2448
2341
|
let rootDir;
|
|
2449
2342
|
let workspaceGlobs2 = [];
|
|
2450
2343
|
for (let i = 0;i < 10; i++) {
|
|
2451
|
-
const pnpmPath =
|
|
2344
|
+
const pnpmPath = path5.join(currentDir, "pnpm-workspace.yaml");
|
|
2452
2345
|
if (fs4.existsSync(pnpmPath)) {
|
|
2453
2346
|
try {
|
|
2454
2347
|
const yamlContent = fs4.readFileSync(pnpmPath, "utf-8");
|
|
@@ -2459,7 +2352,7 @@ function buildWorkspaceMap(baseDir) {
|
|
|
2459
2352
|
}
|
|
2460
2353
|
} catch {}
|
|
2461
2354
|
}
|
|
2462
|
-
const pkgPath =
|
|
2355
|
+
const pkgPath = path5.join(currentDir, "package.json");
|
|
2463
2356
|
if (fs4.existsSync(pkgPath)) {
|
|
2464
2357
|
try {
|
|
2465
2358
|
const pkg = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
|
|
@@ -2470,7 +2363,7 @@ function buildWorkspaceMap(baseDir) {
|
|
|
2470
2363
|
}
|
|
2471
2364
|
} catch {}
|
|
2472
2365
|
}
|
|
2473
|
-
const parent =
|
|
2366
|
+
const parent = path5.dirname(currentDir);
|
|
2474
2367
|
if (parent === currentDir)
|
|
2475
2368
|
break;
|
|
2476
2369
|
currentDir = parent;
|
|
@@ -2479,15 +2372,15 @@ function buildWorkspaceMap(baseDir) {
|
|
|
2479
2372
|
return;
|
|
2480
2373
|
const packages = new Map;
|
|
2481
2374
|
for (const glob of workspaceGlobs2) {
|
|
2482
|
-
const globDir =
|
|
2375
|
+
const globDir = path5.join(rootDir, glob.replace(/\/\*$/, ""));
|
|
2483
2376
|
if (!fs4.existsSync(globDir) || !fs4.statSync(globDir).isDirectory())
|
|
2484
2377
|
continue;
|
|
2485
2378
|
const entries = fs4.readdirSync(globDir, { withFileTypes: true });
|
|
2486
2379
|
for (const entry of entries) {
|
|
2487
2380
|
if (!isDirentDir2(globDir, entry))
|
|
2488
2381
|
continue;
|
|
2489
|
-
const pkgDir =
|
|
2490
|
-
const pkgJsonPath =
|
|
2382
|
+
const pkgDir = path5.join(globDir, entry.name);
|
|
2383
|
+
const pkgJsonPath = path5.join(pkgDir, "package.json");
|
|
2491
2384
|
if (!fs4.existsSync(pkgJsonPath))
|
|
2492
2385
|
continue;
|
|
2493
2386
|
try {
|
|
@@ -2505,7 +2398,7 @@ function discoverAmbientTypePackages(baseDir) {
|
|
|
2505
2398
|
const seen = new Set;
|
|
2506
2399
|
let currentDir = baseDir;
|
|
2507
2400
|
for (let i = 0;i < 10; i++) {
|
|
2508
|
-
const typesDir =
|
|
2401
|
+
const typesDir = path5.join(currentDir, "node_modules", "@types");
|
|
2509
2402
|
try {
|
|
2510
2403
|
if (fs4.existsSync(typesDir) && fs4.statSync(typesDir).isDirectory()) {
|
|
2511
2404
|
for (const entry of fs4.readdirSync(typesDir, { withFileTypes: true })) {
|
|
@@ -2518,7 +2411,7 @@ function discoverAmbientTypePackages(baseDir) {
|
|
|
2518
2411
|
}
|
|
2519
2412
|
}
|
|
2520
2413
|
} catch {}
|
|
2521
|
-
const parent =
|
|
2414
|
+
const parent = path5.dirname(currentDir);
|
|
2522
2415
|
if (parent === currentDir)
|
|
2523
2416
|
break;
|
|
2524
2417
|
currentDir = parent;
|
|
@@ -2527,24 +2420,24 @@ function discoverAmbientTypePackages(baseDir) {
|
|
|
2527
2420
|
}
|
|
2528
2421
|
function createProgram(options) {
|
|
2529
2422
|
const { content } = options;
|
|
2530
|
-
const entryFile =
|
|
2531
|
-
const baseDir =
|
|
2532
|
-
let configPath =
|
|
2423
|
+
const entryFile = path5.resolve(options.entryFile);
|
|
2424
|
+
const baseDir = path5.resolve(options.baseDir ?? path5.dirname(entryFile));
|
|
2425
|
+
let configPath = ts3.findConfigFile(baseDir, ts3.sys.fileExists, "tsconfig.json");
|
|
2533
2426
|
if (!configPath) {
|
|
2534
|
-
configPath =
|
|
2427
|
+
configPath = ts3.findConfigFile(baseDir, ts3.sys.fileExists, "jsconfig.json");
|
|
2535
2428
|
}
|
|
2536
2429
|
let compilerOptions = { ...DEFAULT_COMPILER_OPTIONS };
|
|
2537
2430
|
let additionalRootFiles = [];
|
|
2538
2431
|
if (configPath) {
|
|
2539
|
-
const configFile =
|
|
2540
|
-
const parsedConfig =
|
|
2432
|
+
const configFile = ts3.readConfigFile(configPath, ts3.sys.readFile);
|
|
2433
|
+
const parsedConfig = ts3.parseJsonConfigFileContent(configFile.config, ts3.sys, path5.dirname(configPath));
|
|
2541
2434
|
compilerOptions = { ...compilerOptions, ...parsedConfig.options };
|
|
2542
2435
|
additionalRootFiles = resolveProjectReferences(configPath, parsedConfig);
|
|
2543
2436
|
let sourceFiles = parsedConfig.fileNames.filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("/dist/") && !f.includes("/node_modules/"));
|
|
2544
2437
|
if (/\.d\.[cm]?ts$/.test(entryFile)) {
|
|
2545
2438
|
sourceFiles = sourceFiles.filter((f) => {
|
|
2546
2439
|
try {
|
|
2547
|
-
return !
|
|
2440
|
+
return !ts3.getOutputFileNames(parsedConfig, f, !ts3.sys.useCaseSensitiveFileNames).some((out) => path5.resolve(out) === entryFile);
|
|
2548
2441
|
} catch {
|
|
2549
2442
|
return true;
|
|
2550
2443
|
}
|
|
@@ -2572,7 +2465,7 @@ function createProgram(options) {
|
|
|
2572
2465
|
}
|
|
2573
2466
|
}
|
|
2574
2467
|
const workspaceMap = buildWorkspaceMap(baseDir);
|
|
2575
|
-
const compilerHost =
|
|
2468
|
+
const compilerHost = ts3.createCompilerHost(compilerOptions, true);
|
|
2576
2469
|
let inMemorySource;
|
|
2577
2470
|
if (workspaceMap) {
|
|
2578
2471
|
compilerHost.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, options2, containingSourceFile) => moduleLiterals.map((literal) => {
|
|
@@ -2589,12 +2482,12 @@ function createProgram(options) {
|
|
|
2589
2482
|
};
|
|
2590
2483
|
}
|
|
2591
2484
|
}
|
|
2592
|
-
const mode =
|
|
2593
|
-
return
|
|
2485
|
+
const mode = ts3.getModeForUsageLocation(containingSourceFile, literal, options2);
|
|
2486
|
+
return ts3.resolveModuleName(literal.text, containingFile, options2, compilerHost, undefined, redirectedReference, mode);
|
|
2594
2487
|
});
|
|
2595
2488
|
}
|
|
2596
2489
|
if (content !== undefined) {
|
|
2597
|
-
inMemorySource =
|
|
2490
|
+
inMemorySource = ts3.createSourceFile(entryFile, content, ts3.ScriptTarget.Latest, true, getScriptKind(entryFile));
|
|
2598
2491
|
const originalGetSourceFile = compilerHost.getSourceFile.bind(compilerHost);
|
|
2599
2492
|
compilerHost.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
|
|
2600
2493
|
if (fileName === entryFile) {
|
|
@@ -2604,7 +2497,7 @@ function createProgram(options) {
|
|
|
2604
2497
|
};
|
|
2605
2498
|
}
|
|
2606
2499
|
const rootFiles = [entryFile, ...additionalRootFiles];
|
|
2607
|
-
const program =
|
|
2500
|
+
const program = ts3.createProgram(rootFiles, compilerOptions, compilerHost);
|
|
2608
2501
|
const sourceFile = inMemorySource ?? program.getSourceFile(entryFile);
|
|
2609
2502
|
return {
|
|
2610
2503
|
program,
|
|
@@ -2625,77 +2518,6 @@ import ts5 from "typescript";
|
|
|
2625
2518
|
// src/types/schema-builder.ts
|
|
2626
2519
|
import ts4 from "typescript";
|
|
2627
2520
|
|
|
2628
|
-
// src/ast/type-identity.ts
|
|
2629
|
-
import * as path5 from "node:path";
|
|
2630
|
-
import ts3 from "typescript";
|
|
2631
|
-
var NODE_MODULES_PKG = /node_modules\/(@[^/]+\/[^/]+|[^/]+)/;
|
|
2632
|
-
function packageLabel(fileName, workspacePackages) {
|
|
2633
|
-
const match = fileName.match(NODE_MODULES_PKG);
|
|
2634
|
-
let pkg = match?.[1];
|
|
2635
|
-
if (!pkg) {
|
|
2636
|
-
for (const [name, dir] of workspacePackages) {
|
|
2637
|
-
if (fileName.startsWith(`${path5.resolve(dir)}${path5.sep}`)) {
|
|
2638
|
-
pkg = name;
|
|
2639
|
-
break;
|
|
2640
|
-
}
|
|
2641
|
-
}
|
|
2642
|
-
}
|
|
2643
|
-
return (pkg ?? "local").replace(/^@/, "").replace(/\//g, "-");
|
|
2644
|
-
}
|
|
2645
|
-
function declKey(symbol, checker) {
|
|
2646
|
-
let resolved = symbol;
|
|
2647
|
-
if (symbol.flags & ts3.SymbolFlags.Alias) {
|
|
2648
|
-
try {
|
|
2649
|
-
resolved = checker.getAliasedSymbol(symbol);
|
|
2650
|
-
} catch {}
|
|
2651
|
-
}
|
|
2652
|
-
const decl = resolved.declarations?.[0];
|
|
2653
|
-
if (!decl)
|
|
2654
|
-
return;
|
|
2655
|
-
return `${decl.getSourceFile().fileName}#${decl.getStart()}`;
|
|
2656
|
-
}
|
|
2657
|
-
function resolveTypeId(symbol, ctx) {
|
|
2658
|
-
const cached = ctx.typeIds.get(symbol);
|
|
2659
|
-
if (cached)
|
|
2660
|
-
return cached;
|
|
2661
|
-
const key = declKey(symbol, ctx.typeChecker);
|
|
2662
|
-
if (key) {
|
|
2663
|
-
const existing = ctx.declIds.get(key);
|
|
2664
|
-
if (existing) {
|
|
2665
|
-
ctx.typeIds.set(symbol, existing);
|
|
2666
|
-
return existing;
|
|
2667
|
-
}
|
|
2668
|
-
}
|
|
2669
|
-
const claim = (id) => {
|
|
2670
|
-
ctx.typeIds.set(symbol, id);
|
|
2671
|
-
if (key)
|
|
2672
|
-
ctx.declIds.set(key, id);
|
|
2673
|
-
ctx.idOwner.set(id, key ?? id);
|
|
2674
|
-
return id;
|
|
2675
|
-
};
|
|
2676
|
-
const name = symbol.getName();
|
|
2677
|
-
const owner = ctx.idOwner.get(name);
|
|
2678
|
-
if (!owner || owner === key)
|
|
2679
|
-
return claim(name);
|
|
2680
|
-
const file = symbol.declarations?.[0]?.getSourceFile().fileName ?? "";
|
|
2681
|
-
const scoped = `${packageLabel(file, ctx.workspacePackages)}.${name}`;
|
|
2682
|
-
const scopedOwner = ctx.idOwner.get(scoped);
|
|
2683
|
-
if (!scopedOwner || scopedOwner === key)
|
|
2684
|
-
return claim(scoped);
|
|
2685
|
-
let n = 2;
|
|
2686
|
-
while (ctx.idOwner.has(`${name}_${n}`))
|
|
2687
|
-
n++;
|
|
2688
|
-
return claim(`${name}_${n}`);
|
|
2689
|
-
}
|
|
2690
|
-
function typeRefId(type, ctx) {
|
|
2691
|
-
const symbol = type.aliasSymbol ?? type.getSymbol();
|
|
2692
|
-
if (!symbol)
|
|
2693
|
-
return "";
|
|
2694
|
-
if (!ctx)
|
|
2695
|
-
return symbol.getName();
|
|
2696
|
-
return resolveTypeId(symbol, ctx);
|
|
2697
|
-
}
|
|
2698
|
-
|
|
2699
2521
|
// src/schema/builtins.ts
|
|
2700
2522
|
var BUILTIN_TYPE_SCHEMAS = {
|
|
2701
2523
|
Array: { type: "array" },
|
|
@@ -3013,9 +2835,7 @@ function isBuiltinSymbol(symbol) {
|
|
|
3013
2835
|
const declarations = symbol.getDeclarations();
|
|
3014
2836
|
if (!declarations || declarations.length === 0)
|
|
3015
2837
|
return false;
|
|
3016
|
-
|
|
3017
|
-
const fileName = sourceFile.fileName;
|
|
3018
|
-
return fileName.includes("/typescript/lib/lib.") || fileName.includes("\\typescript\\lib\\lib.");
|
|
2838
|
+
return isLibFile(declarations[0].getSourceFile().fileName);
|
|
3019
2839
|
}
|
|
3020
2840
|
function getTypeOrigin(type, _checker) {
|
|
3021
2841
|
const symbol = type.getSymbol() ?? type.aliasSymbol;
|
|
@@ -3025,12 +2845,9 @@ function getTypeOrigin(type, _checker) {
|
|
|
3025
2845
|
if (!declarations || declarations.length === 0)
|
|
3026
2846
|
return;
|
|
3027
2847
|
const fileName = declarations[0].getSourceFile().fileName;
|
|
3028
|
-
|
|
3029
|
-
if (!match)
|
|
3030
|
-
return;
|
|
3031
|
-
if (match[1] === "typescript")
|
|
2848
|
+
if (isLibFile(fileName))
|
|
3032
2849
|
return;
|
|
3033
|
-
return
|
|
2850
|
+
return packageNameFromPath(fileName);
|
|
3034
2851
|
}
|
|
3035
2852
|
function isBuiltinGeneric(name) {
|
|
3036
2853
|
return BUILTIN_GENERICS.has(name);
|
|
@@ -4160,7 +3977,7 @@ class TypeRegistry {
|
|
|
4160
3977
|
const props = {};
|
|
4161
3978
|
const required = [];
|
|
4162
3979
|
const limit = ctx.maxProperties;
|
|
4163
|
-
const isArrayLike = checker.isArrayType(type) || checker.isTupleType(type) || type.symbol?.getName() === "Array" && type.symbol?.getDeclarations()?.[0]?.getSourceFile()?.fileName
|
|
3980
|
+
const isArrayLike = checker.isArrayType(type) || checker.isTupleType(type) || type.symbol?.getName() === "Array" && isLibFile(type.symbol?.getDeclarations()?.[0]?.getSourceFile()?.fileName ?? "");
|
|
4164
3981
|
const isStringLike = type.flags & ts6.TypeFlags.StringLike;
|
|
4165
3982
|
const isNumberLike = type.flags & ts6.TypeFlags.NumberLike;
|
|
4166
3983
|
const included = properties.filter((prop) => {
|
|
@@ -6151,11 +5968,9 @@ function detectExternalPackage(symbol, checker) {
|
|
|
6151
5968
|
const allDecls = [...targetSymbol.declarations ?? [], ...symbol.declarations ?? []];
|
|
6152
5969
|
for (const decl of allDecls) {
|
|
6153
5970
|
const sf = decl.getSourceFile();
|
|
6154
|
-
|
|
6155
|
-
|
|
6156
|
-
|
|
6157
|
-
return match[1];
|
|
6158
|
-
}
|
|
5971
|
+
const pkg = sf && packageNameFromPath(sf.fileName);
|
|
5972
|
+
if (pkg)
|
|
5973
|
+
return pkg;
|
|
6159
5974
|
if (ts13.isExportSpecifier(decl)) {
|
|
6160
5975
|
const exportDecl = decl.parent?.parent;
|
|
6161
5976
|
if (exportDecl && ts13.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
|
|
@@ -6979,80 +6794,6 @@ function extractExternalExport(exportName, resolvedModule, program, ctx, visited
|
|
|
6979
6794
|
return specExport;
|
|
6980
6795
|
}
|
|
6981
6796
|
|
|
6982
|
-
// src/builder/jev-extract.ts
|
|
6983
|
-
var FOLLOW_SCORE_LEVELS = [
|
|
6984
|
-
"opaque — a stub is enough",
|
|
6985
|
-
"useful — expanding helps",
|
|
6986
|
-
"essential — needed to understand the public API"
|
|
6987
|
-
];
|
|
6988
|
-
var AMBIGUOUS_CODES = new Set([
|
|
6989
|
-
"FORGOTTEN_EXPORT",
|
|
6990
|
-
"SERIALIZATION_FAILED",
|
|
6991
|
-
"RUNTIME_SCHEMA_ERROR"
|
|
6992
|
-
]);
|
|
6993
|
-
async function selectFollowExternal(refs, evaluate) {
|
|
6994
|
-
const sliced = refs.slice(0, MAX_JEV_QUESTIONS);
|
|
6995
|
-
if (!sliced.length)
|
|
6996
|
-
return [];
|
|
6997
|
-
const questions = {};
|
|
6998
|
-
for (const [i, ref] of sliced.entries()) {
|
|
6999
|
-
questions[`t${i}`] = {
|
|
7000
|
-
type: "score",
|
|
7001
|
-
instructions: `How load-bearing is ${ref.typeName} from ${ref.package} for understanding this public TypeScript API?`,
|
|
7002
|
-
criteria: FOLLOW_SCORE_LEVELS
|
|
7003
|
-
};
|
|
7004
|
-
}
|
|
7005
|
-
const result = await jevEvaluate(evaluate, {
|
|
7006
|
-
types: sliced,
|
|
7007
|
-
task: "OpenPkg extracts a public TS API. Stub opaque externals; expand load-bearing ones."
|
|
7008
|
-
}, questions);
|
|
7009
|
-
const follow = new Set;
|
|
7010
|
-
for (const [i, ref] of sliced.entries()) {
|
|
7011
|
-
const id = `t${i}`;
|
|
7012
|
-
const score = result.answers[id]?.score;
|
|
7013
|
-
if (typeof score !== "number")
|
|
7014
|
-
continue;
|
|
7015
|
-
const conf = namedConfidence(result, id) ?? (score >= 1.5 || score <= 0.5 ? 1 : 0);
|
|
7016
|
-
if (score >= 1.5 || score >= 1 && conf >= JEV_CONFIDENCE)
|
|
7017
|
-
follow.add(ref.package);
|
|
7018
|
-
}
|
|
7019
|
-
return [...follow];
|
|
7020
|
-
}
|
|
7021
|
-
async function calibrateDiagnostics(diagnostics, evaluate) {
|
|
7022
|
-
const targets = diagnostics.map((d, index) => ({ d, index })).filter(({ d }) => d.code && AMBIGUOUS_CODES.has(d.code)).slice(0, MAX_JEV_QUESTIONS);
|
|
7023
|
-
if (targets.length < 1)
|
|
7024
|
-
return;
|
|
7025
|
-
const questions = {};
|
|
7026
|
-
for (const [i, { d }] of targets.entries()) {
|
|
7027
|
-
questions[`d${i}`] = {
|
|
7028
|
-
type: "choice",
|
|
7029
|
-
instructions: `What severity should this extraction diagnostic have? ${d.message}`,
|
|
7030
|
-
criteria: {
|
|
7031
|
-
error: "Blocks a correct spec",
|
|
7032
|
-
warning: "Likely a real API gap",
|
|
7033
|
-
info: "Informational only"
|
|
7034
|
-
}
|
|
7035
|
-
};
|
|
7036
|
-
}
|
|
7037
|
-
const result = await jevEvaluate(evaluate, {
|
|
7038
|
-
diagnostics: targets.map(({ d }) => ({
|
|
7039
|
-
code: d.code,
|
|
7040
|
-
message: d.message,
|
|
7041
|
-
severity: d.severity
|
|
7042
|
-
}))
|
|
7043
|
-
}, questions);
|
|
7044
|
-
for (const [i, { d }] of targets.entries()) {
|
|
7045
|
-
const id = `d${i}`;
|
|
7046
|
-
const choice = result.answers[id]?.choice;
|
|
7047
|
-
if (choice !== "error" && choice !== "warning" && choice !== "info")
|
|
7048
|
-
continue;
|
|
7049
|
-
const conf = namedConfidence(result, id) ?? result.answers[id]?.probabilities?.[choice] ?? 0;
|
|
7050
|
-
if (conf < JEV_CONFIDENCE)
|
|
7051
|
-
continue;
|
|
7052
|
-
d.severity = choice;
|
|
7053
|
-
}
|
|
7054
|
-
}
|
|
7055
|
-
|
|
7056
6797
|
// src/builder/schema-merger.ts
|
|
7057
6798
|
function mergeRuntimeSchemas(staticExports, runtimeSchemas) {
|
|
7058
6799
|
let merged = 0;
|
|
@@ -7220,10 +6961,6 @@ function hasInternalTag(typeName, program, sourceFile) {
|
|
|
7220
6961
|
|
|
7221
6962
|
// src/builder/type-expansion.ts
|
|
7222
6963
|
import ts18 from "typescript";
|
|
7223
|
-
var NODE_MODULES_PKG2 = /node_modules\/(@[^/]+\/[^/]+|[^/]+)/;
|
|
7224
|
-
function isLibFile(fileName) {
|
|
7225
|
-
return fileName.includes("/typescript/lib/lib.") || fileName.includes("\\typescript\\lib\\lib.");
|
|
7226
|
-
}
|
|
7227
6964
|
function createExternalExpansionPredicate(opts) {
|
|
7228
6965
|
const matchesEntry = (entry, pkg) => {
|
|
7229
6966
|
if (!entry.includes("*"))
|
|
@@ -7232,8 +6969,6 @@ function createExternalExpansionPredicate(opts) {
|
|
|
7232
6969
|
return rx.test(pkg);
|
|
7233
6970
|
};
|
|
7234
6971
|
const packageAllowed = (pkg) => {
|
|
7235
|
-
if (pkg === "typescript")
|
|
7236
|
-
return false;
|
|
7237
6972
|
if (opts.followExternal === true)
|
|
7238
6973
|
return true;
|
|
7239
6974
|
if (Array.isArray(opts.followExternal) && opts.followExternal.some((e) => matchesEntry(e, pkg))) {
|
|
@@ -7248,91 +6983,12 @@ function createExternalExpansionPredicate(opts) {
|
|
|
7248
6983
|
const fileName = decl.getSourceFile().fileName;
|
|
7249
6984
|
if (isLibFile(fileName))
|
|
7250
6985
|
return false;
|
|
7251
|
-
const
|
|
7252
|
-
if (
|
|
7253
|
-
return packageAllowed(
|
|
6986
|
+
const pkg = packageNameFromPath(fileName);
|
|
6987
|
+
if (pkg)
|
|
6988
|
+
return packageAllowed(pkg);
|
|
7254
6989
|
return true;
|
|
7255
6990
|
};
|
|
7256
6991
|
}
|
|
7257
|
-
function collectReferencedExternals(exportedSymbols, checker, workspacePackages) {
|
|
7258
|
-
const out = [];
|
|
7259
|
-
const seen = new Set;
|
|
7260
|
-
const visited = new Set;
|
|
7261
|
-
const consider = (symbol) => {
|
|
7262
|
-
if (!symbol)
|
|
7263
|
-
return;
|
|
7264
|
-
const decl = symbol.declarations?.[0];
|
|
7265
|
-
if (!decl)
|
|
7266
|
-
return;
|
|
7267
|
-
const fileName = decl.getSourceFile().fileName;
|
|
7268
|
-
if (isLibFile(fileName))
|
|
7269
|
-
return;
|
|
7270
|
-
const match = fileName.match(NODE_MODULES_PKG2);
|
|
7271
|
-
if (!match)
|
|
7272
|
-
return;
|
|
7273
|
-
const pkg = match[1];
|
|
7274
|
-
if (pkg === "typescript" || workspacePackages.has(pkg))
|
|
7275
|
-
return;
|
|
7276
|
-
const typeName = symbol.getName();
|
|
7277
|
-
if (typeName.startsWith("__"))
|
|
7278
|
-
return;
|
|
7279
|
-
const key = `${pkg}:${typeName}`;
|
|
7280
|
-
if (seen.has(key))
|
|
7281
|
-
return;
|
|
7282
|
-
seen.add(key);
|
|
7283
|
-
out.push({ typeName, package: pkg });
|
|
7284
|
-
};
|
|
7285
|
-
const visit = (type, depth) => {
|
|
7286
|
-
if (!type || depth > 20 || visited.has(type))
|
|
7287
|
-
return;
|
|
7288
|
-
visited.add(type);
|
|
7289
|
-
const symbol = type.aliasSymbol ?? type.getSymbol();
|
|
7290
|
-
consider(symbol);
|
|
7291
|
-
for (const arg of type.aliasTypeArguments ?? [])
|
|
7292
|
-
visit(arg, depth + 1);
|
|
7293
|
-
const typeRef = type;
|
|
7294
|
-
if (typeRef.target) {
|
|
7295
|
-
for (const arg of checker.getTypeArguments(typeRef) ?? [])
|
|
7296
|
-
visit(arg, depth + 1);
|
|
7297
|
-
}
|
|
7298
|
-
if (type.isUnion() || type.isIntersection()) {
|
|
7299
|
-
for (const t of type.types)
|
|
7300
|
-
visit(t, depth + 1);
|
|
7301
|
-
}
|
|
7302
|
-
const fileName = symbol?.declarations?.[0]?.getSourceFile().fileName;
|
|
7303
|
-
if (fileName) {
|
|
7304
|
-
if (isLibFile(fileName))
|
|
7305
|
-
return;
|
|
7306
|
-
const match = fileName.match(NODE_MODULES_PKG2);
|
|
7307
|
-
if (match && !workspacePackages.has(match[1]))
|
|
7308
|
-
return;
|
|
7309
|
-
}
|
|
7310
|
-
if (!(type.flags & ts18.TypeFlags.Object || type.isClassOrInterface()))
|
|
7311
|
-
return;
|
|
7312
|
-
if (type.isClassOrInterface()) {
|
|
7313
|
-
for (const base of checker.getBaseTypes(type) ?? [])
|
|
7314
|
-
visit(base, depth + 1);
|
|
7315
|
-
}
|
|
7316
|
-
for (const prop of type.getProperties()) {
|
|
7317
|
-
if (prop.getName().startsWith("__@"))
|
|
7318
|
-
continue;
|
|
7319
|
-
visit(checker.getTypeOfSymbol(prop), depth + 1);
|
|
7320
|
-
}
|
|
7321
|
-
for (const sig of [...type.getCallSignatures(), ...type.getConstructSignatures()]) {
|
|
7322
|
-
for (const param of sig.getParameters())
|
|
7323
|
-
visit(checker.getTypeOfSymbol(param), depth + 1);
|
|
7324
|
-
visit(sig.getReturnType(), depth + 1);
|
|
7325
|
-
}
|
|
7326
|
-
for (const info of checker.getIndexInfosOfType(type)) {
|
|
7327
|
-
visit(info.type, depth + 1);
|
|
7328
|
-
}
|
|
7329
|
-
};
|
|
7330
|
-
for (const symbol of exportedSymbols) {
|
|
7331
|
-
visit(checker.getTypeOfSymbol(symbol), 0);
|
|
7332
|
-
visit(checker.getDeclaredTypeOfSymbol(symbol), 0);
|
|
7333
|
-
}
|
|
7334
|
-
return out;
|
|
7335
|
-
}
|
|
7336
6992
|
function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
7337
6993
|
if (opts.followExternal === false)
|
|
7338
6994
|
return;
|
|
@@ -7801,44 +7457,7 @@ async function extract(options) {
|
|
|
7801
7457
|
...included ? {} : { skipReason: "filtered" }
|
|
7802
7458
|
});
|
|
7803
7459
|
}
|
|
7804
|
-
|
|
7805
|
-
let evaluate = options.evaluate;
|
|
7806
|
-
if (followExternal === "auto" && !evaluate && options.decisions !== "jev") {
|
|
7807
|
-
diagnostics.push({
|
|
7808
|
-
message: "followExternal auto requires decisions: 'jev' (or an injected evaluate)",
|
|
7809
|
-
severity: "error",
|
|
7810
|
-
code: "JEV_UNAVAILABLE"
|
|
7811
|
-
});
|
|
7812
|
-
followExternal = undefined;
|
|
7813
|
-
}
|
|
7814
|
-
const wantsJev = options.decisions === "jev";
|
|
7815
|
-
if (wantsJev && !evaluate) {
|
|
7816
|
-
if (process.env.AI_GATEWAY_API_KEY) {
|
|
7817
|
-
try {
|
|
7818
|
-
evaluate = await loadEvaluate();
|
|
7819
|
-
} catch (err) {
|
|
7820
|
-
diagnostics.push({
|
|
7821
|
-
message: err instanceof Error ? err.message : String(err),
|
|
7822
|
-
severity: "error",
|
|
7823
|
-
code: "JEV_UNAVAILABLE"
|
|
7824
|
-
});
|
|
7825
|
-
}
|
|
7826
|
-
} else if (followExternal === "auto") {
|
|
7827
|
-
diagnostics.push({
|
|
7828
|
-
message: "followExternal auto requires --jev and AI_GATEWAY_API_KEY",
|
|
7829
|
-
severity: "error",
|
|
7830
|
-
code: "JEV_UNAVAILABLE"
|
|
7831
|
-
});
|
|
7832
|
-
}
|
|
7833
|
-
}
|
|
7834
|
-
if (followExternal === "auto") {
|
|
7835
|
-
if (!evaluate) {
|
|
7836
|
-
followExternal = undefined;
|
|
7837
|
-
} else {
|
|
7838
|
-
const refs = collectReferencedExternals(exportedSymbols, typeChecker, result.workspacePackages ?? new Map);
|
|
7839
|
-
followExternal = await selectFollowExternal(refs, evaluate);
|
|
7840
|
-
}
|
|
7841
|
-
}
|
|
7460
|
+
const followExternal = options.followExternal;
|
|
7842
7461
|
const ctx = createContext(program, sourceFile, {
|
|
7843
7462
|
maxTypeDepth,
|
|
7844
7463
|
includePrivate,
|
|
@@ -7870,12 +7489,10 @@ async function extract(options) {
|
|
|
7870
7489
|
const allDecls = [...targetSymbol.declarations ?? [], ...symbol.declarations ?? []];
|
|
7871
7490
|
for (const decl of allDecls) {
|
|
7872
7491
|
const sf = decl.getSourceFile();
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
break;
|
|
7878
|
-
}
|
|
7492
|
+
const pkg = sf && packageNameFromPath(sf.fileName);
|
|
7493
|
+
if (pkg) {
|
|
7494
|
+
externalPackage = pkg;
|
|
7495
|
+
break;
|
|
7879
7496
|
}
|
|
7880
7497
|
if (ts19.isExportSpecifier(decl)) {
|
|
7881
7498
|
const exportDecl = decl.parent?.parent;
|
|
@@ -8081,9 +7698,6 @@ async function extract(options) {
|
|
|
8081
7698
|
suggestion: "Check serialization errors for these exports"
|
|
8082
7699
|
});
|
|
8083
7700
|
}
|
|
8084
|
-
if (evaluate) {
|
|
8085
|
-
await calibrateDiagnostics(diagnostics, evaluate);
|
|
8086
|
-
}
|
|
8087
7701
|
return {
|
|
8088
7702
|
spec,
|
|
8089
7703
|
diagnostics,
|
|
@@ -8344,7 +7958,7 @@ function findTypeInProgram(name, checker, program, sourceFile, symFlags) {
|
|
|
8344
7958
|
const entryDir = path10.dirname(sourceFile.fileName);
|
|
8345
7959
|
for (const sf of program.getSourceFiles()) {
|
|
8346
7960
|
const fn = sf.fileName;
|
|
8347
|
-
if (
|
|
7961
|
+
if (isLibFile(fn))
|
|
8348
7962
|
continue;
|
|
8349
7963
|
if (fn.includes("/@types/node/") || fn.includes("\\@types\\node\\"))
|
|
8350
7964
|
continue;
|
|
@@ -9004,8 +8618,6 @@ export {
|
|
|
9004
8618
|
PRIMITIVES,
|
|
9005
8619
|
NUMBER_PROTOTYPE_METHODS,
|
|
9006
8620
|
LATEST_VERSION,
|
|
9007
|
-
JEV_MODEL,
|
|
9008
|
-
JEV_CONFIDENCE,
|
|
9009
8621
|
CacheManager,
|
|
9010
8622
|
CONFIG_FILENAME,
|
|
9011
8623
|
BUILTIN_TYPE_SCHEMAS,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openpkg-ts/sdk",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.54.1",
|
|
4
4
|
"description": "TypeScript API extraction SDK - programmatic primitives for OpenPkg specs",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"openpkg",
|
|
@@ -48,13 +48,9 @@
|
|
|
48
48
|
"typescript": "^5.0.0 || ^6.0.0"
|
|
49
49
|
},
|
|
50
50
|
"peerDependencies": {
|
|
51
|
-
"ai": "^7.0.105",
|
|
52
51
|
"shiki": "^1.0.0"
|
|
53
52
|
},
|
|
54
53
|
"peerDependenciesMeta": {
|
|
55
|
-
"ai": {
|
|
56
|
-
"optional": true
|
|
57
|
-
},
|
|
58
54
|
"shiki": {
|
|
59
55
|
"optional": true
|
|
60
56
|
}
|