@openpkg-ts/sdk 0.53.1 → 0.54.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 +3 -3
- package/dist/index.d.ts +4 -51
- package/dist/index.js +183 -566
- 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,82 @@ 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 packageNameFromPath(fileName) {
|
|
1791
|
+
return [...fileName.matchAll(NODE_MODULES_PKG)].at(-1)?.[1];
|
|
1792
|
+
}
|
|
1793
|
+
function packageLabel(fileName, workspacePackages) {
|
|
1794
|
+
let pkg = packageNameFromPath(fileName);
|
|
1795
|
+
if (!pkg) {
|
|
1796
|
+
for (const [name, dir] of workspacePackages) {
|
|
1797
|
+
if (fileName.startsWith(`${path3.resolve(dir)}${path3.sep}`)) {
|
|
1798
|
+
pkg = name;
|
|
1799
|
+
break;
|
|
1800
|
+
}
|
|
1801
|
+
}
|
|
1802
|
+
}
|
|
1803
|
+
return (pkg ?? "local").replace(/^@/, "").replace(/\//g, "-");
|
|
1804
|
+
}
|
|
1805
|
+
function declKey(symbol, checker) {
|
|
1806
|
+
let resolved = symbol;
|
|
1807
|
+
if (symbol.flags & ts.SymbolFlags.Alias) {
|
|
1808
|
+
try {
|
|
1809
|
+
resolved = checker.getAliasedSymbol(symbol);
|
|
1810
|
+
} catch {}
|
|
1811
|
+
}
|
|
1812
|
+
const decl = resolved.declarations?.[0];
|
|
1813
|
+
if (!decl)
|
|
1814
|
+
return;
|
|
1815
|
+
return `${decl.getSourceFile().fileName}#${decl.getStart()}`;
|
|
1816
|
+
}
|
|
1817
|
+
function resolveTypeId(symbol, ctx) {
|
|
1818
|
+
const cached = ctx.typeIds.get(symbol);
|
|
1819
|
+
if (cached)
|
|
1820
|
+
return cached;
|
|
1821
|
+
const key = declKey(symbol, ctx.typeChecker);
|
|
1822
|
+
if (key) {
|
|
1823
|
+
const existing = ctx.declIds.get(key);
|
|
1824
|
+
if (existing) {
|
|
1825
|
+
ctx.typeIds.set(symbol, existing);
|
|
1826
|
+
return existing;
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
const claim = (id) => {
|
|
1830
|
+
ctx.typeIds.set(symbol, id);
|
|
1831
|
+
if (key)
|
|
1832
|
+
ctx.declIds.set(key, id);
|
|
1833
|
+
ctx.idOwner.set(id, key ?? id);
|
|
1834
|
+
return id;
|
|
1835
|
+
};
|
|
1836
|
+
const name = symbol.getName();
|
|
1837
|
+
const owner = ctx.idOwner.get(name);
|
|
1838
|
+
if (!owner || owner === key)
|
|
1839
|
+
return claim(name);
|
|
1840
|
+
const file = symbol.declarations?.[0]?.getSourceFile().fileName ?? "";
|
|
1841
|
+
const scoped = `${packageLabel(file, ctx.workspacePackages)}.${name}`;
|
|
1842
|
+
const scopedOwner = ctx.idOwner.get(scoped);
|
|
1843
|
+
if (!scopedOwner || scopedOwner === key)
|
|
1844
|
+
return claim(scoped);
|
|
1845
|
+
let n = 2;
|
|
1846
|
+
while (ctx.idOwner.has(`${name}_${n}`))
|
|
1847
|
+
n++;
|
|
1848
|
+
return claim(`${name}_${n}`);
|
|
1849
|
+
}
|
|
1850
|
+
function typeRefId(type, ctx) {
|
|
1851
|
+
const symbol = type.aliasSymbol ?? type.getSymbol();
|
|
1852
|
+
if (!symbol)
|
|
1853
|
+
return "";
|
|
1854
|
+
if (!ctx)
|
|
1855
|
+
return symbol.getName();
|
|
1856
|
+
return resolveTypeId(symbol, ctx);
|
|
1857
|
+
}
|
|
1858
|
+
|
|
1859
|
+
// src/ast/utils.ts
|
|
1860
|
+
import * as path4 from "node:path";
|
|
1861
|
+
import ts2 from "typescript";
|
|
1972
1862
|
var INLINE_TAG_RE = /(^|[^\\])\{@([a-zA-Z][a-zA-Z0-9]*)((?:[^}\\]|\\.)*)\}/g;
|
|
1973
1863
|
function parseInlineTags(...texts) {
|
|
1974
1864
|
const inlineTags = [];
|
|
@@ -2062,12 +1952,12 @@ function extractSeeTagText(tag) {
|
|
|
2062
1952
|
if (Array.isArray(tag.comment)) {
|
|
2063
1953
|
const parts = [];
|
|
2064
1954
|
for (const part of tag.comment) {
|
|
2065
|
-
if (
|
|
1955
|
+
if (ts2.isJSDocLink(part) || ts2.isJSDocLinkCode(part) || ts2.isJSDocLinkPlain(part)) {
|
|
2066
1956
|
if (part.name) {
|
|
2067
1957
|
try {
|
|
2068
1958
|
parts.push(part.name.getText());
|
|
2069
1959
|
} catch {
|
|
2070
|
-
if (
|
|
1960
|
+
if (ts2.isIdentifier(part.name)) {
|
|
2071
1961
|
parts.push(part.name.text);
|
|
2072
1962
|
}
|
|
2073
1963
|
}
|
|
@@ -2075,7 +1965,7 @@ function extractSeeTagText(tag) {
|
|
|
2075
1965
|
if (part.text) {
|
|
2076
1966
|
parts.push(part.text);
|
|
2077
1967
|
}
|
|
2078
|
-
} else if (part.kind ===
|
|
1968
|
+
} else if (part.kind === ts2.SyntaxKind.JSDocText) {
|
|
2079
1969
|
parts.push(part.text);
|
|
2080
1970
|
}
|
|
2081
1971
|
}
|
|
@@ -2084,13 +1974,13 @@ function extractSeeTagText(tag) {
|
|
|
2084
1974
|
return result;
|
|
2085
1975
|
}
|
|
2086
1976
|
}
|
|
2087
|
-
return typeof tag.comment === "string" ? tag.comment :
|
|
1977
|
+
return typeof tag.comment === "string" ? tag.comment : ts2.getTextOfJSDocComment(tag.comment) ?? "";
|
|
2088
1978
|
}
|
|
2089
1979
|
function getJSDocComment(node, symbol, checker) {
|
|
2090
|
-
const jsDocTags =
|
|
1980
|
+
const jsDocTags = ts2.getJSDocTags(node);
|
|
2091
1981
|
const commentLevelTags = [];
|
|
2092
1982
|
const tags = jsDocTags.map((tag) => {
|
|
2093
|
-
const rawText = typeof tag.comment === "string" ? tag.comment :
|
|
1983
|
+
const rawText = typeof tag.comment === "string" ? tag.comment : ts2.getTextOfJSDocComment(tag.comment) ?? "";
|
|
2094
1984
|
const { retained, hoisted } = tag.tagName.text === "see" ? { retained: rawText, hoisted: [] } : splitCommentLevelTags(rawText);
|
|
2095
1985
|
commentLevelTags.push(...hoisted);
|
|
2096
1986
|
if (tag.tagName.text === "param") {
|
|
@@ -2127,12 +2017,12 @@ function getJSDocComment(node, symbol, checker) {
|
|
|
2127
2017
|
}
|
|
2128
2018
|
return withInlineTags({ name: tag.tagName.text, text: rawText }, retained);
|
|
2129
2019
|
});
|
|
2130
|
-
const jsDocComments =
|
|
2020
|
+
const jsDocComments = ts2.getJSDocCommentsAndTags(node).filter(ts2.isJSDoc);
|
|
2131
2021
|
let description;
|
|
2132
2022
|
if (jsDocComments.length > 0) {
|
|
2133
2023
|
const firstDoc = jsDocComments[0];
|
|
2134
2024
|
if (firstDoc.comment) {
|
|
2135
|
-
description = typeof firstDoc.comment === "string" ? firstDoc.comment :
|
|
2025
|
+
description = typeof firstDoc.comment === "string" ? firstDoc.comment : ts2.getTextOfJSDocComment(firstDoc.comment);
|
|
2136
2026
|
}
|
|
2137
2027
|
}
|
|
2138
2028
|
if (!description && symbol && checker) {
|
|
@@ -2153,7 +2043,7 @@ function getJSDocComment(node, symbol, checker) {
|
|
|
2153
2043
|
}
|
|
2154
2044
|
function getSourceLocation(node, sourceFile) {
|
|
2155
2045
|
const { line } = sourceFile.getLineAndCharacterOfPosition(node.getStart(sourceFile));
|
|
2156
|
-
const relative3 =
|
|
2046
|
+
const relative3 = path4.relative(process.cwd(), sourceFile.fileName);
|
|
2157
2047
|
const file = relative3.startsWith("..") ? sourceFile.fileName : relative3;
|
|
2158
2048
|
return {
|
|
2159
2049
|
file,
|
|
@@ -2173,7 +2063,7 @@ function getParamDescription(propertyName, jsdocTags, inferredAlias) {
|
|
|
2173
2063
|
}
|
|
2174
2064
|
const isMatch = tagParamName === propertyName || inferredAlias && tagParamName === `${inferredAlias}.${propertyName}` || tagParamName.endsWith(`.${propertyName}`);
|
|
2175
2065
|
if (isMatch) {
|
|
2176
|
-
const comment = typeof tag.comment === "string" ? tag.comment :
|
|
2066
|
+
const comment = typeof tag.comment === "string" ? tag.comment : ts2.getTextOfJSDocComment(tag.comment);
|
|
2177
2067
|
return stripParamSeparator(comment);
|
|
2178
2068
|
}
|
|
2179
2069
|
}
|
|
@@ -2186,11 +2076,11 @@ function extractVarianceModifiers(modifiers) {
|
|
|
2186
2076
|
let hasOut = false;
|
|
2187
2077
|
let isConst;
|
|
2188
2078
|
for (const mod of modifiers) {
|
|
2189
|
-
if (mod.kind ===
|
|
2079
|
+
if (mod.kind === ts2.SyntaxKind.InKeyword)
|
|
2190
2080
|
hasIn = true;
|
|
2191
|
-
if (mod.kind ===
|
|
2081
|
+
if (mod.kind === ts2.SyntaxKind.OutKeyword)
|
|
2192
2082
|
hasOut = true;
|
|
2193
|
-
if (mod.kind ===
|
|
2083
|
+
if (mod.kind === ts2.SyntaxKind.ConstKeyword)
|
|
2194
2084
|
isConst = true;
|
|
2195
2085
|
}
|
|
2196
2086
|
const variance = hasIn && hasOut ? "inout" : hasIn ? "in" : hasOut ? "out" : undefined;
|
|
@@ -2212,7 +2102,7 @@ function extractTypeParameters(node, checker) {
|
|
|
2212
2102
|
const defType = checker.getTypeAtLocation(tp.default);
|
|
2213
2103
|
defaultType = checker.typeToString(defType);
|
|
2214
2104
|
}
|
|
2215
|
-
const { variance, isConst } = extractVarianceModifiers(
|
|
2105
|
+
const { variance, isConst } = extractVarianceModifiers(ts2.getModifiers(tp));
|
|
2216
2106
|
return {
|
|
2217
2107
|
name,
|
|
2218
2108
|
...constraint ? { constraint } : {},
|
|
@@ -2233,7 +2123,7 @@ function isSymbolDeprecated(symbol) {
|
|
|
2233
2123
|
return { deprecated: true, reason };
|
|
2234
2124
|
}
|
|
2235
2125
|
for (const declaration of symbol.getDeclarations() ?? []) {
|
|
2236
|
-
const tag =
|
|
2126
|
+
const tag = ts2.getJSDocDeprecatedTag(declaration);
|
|
2237
2127
|
if (tag) {
|
|
2238
2128
|
let reason;
|
|
2239
2129
|
if (typeof tag.comment === "string") {
|
|
@@ -2243,10 +2133,10 @@ function isSymbolDeprecated(symbol) {
|
|
|
2243
2133
|
}
|
|
2244
2134
|
return { deprecated: true, reason };
|
|
2245
2135
|
}
|
|
2246
|
-
if (
|
|
2136
|
+
if (ts2.isExportSpecifier(declaration)) {
|
|
2247
2137
|
const exportDecl = declaration.parent?.parent;
|
|
2248
|
-
if (exportDecl &&
|
|
2249
|
-
const parentTag =
|
|
2138
|
+
if (exportDecl && ts2.isExportDeclaration(exportDecl)) {
|
|
2139
|
+
const parentTag = ts2.getJSDocDeprecatedTag(exportDecl);
|
|
2250
2140
|
if (parentTag) {
|
|
2251
2141
|
let reason;
|
|
2252
2142
|
if (typeof parentTag.comment === "string") {
|
|
@@ -2291,8 +2181,8 @@ function extractTypeParametersFromSignature(signature, checker) {
|
|
|
2291
2181
|
const tpSymbol = tp.getSymbol();
|
|
2292
2182
|
const declarations = tpSymbol?.getDeclarations() ?? [];
|
|
2293
2183
|
for (const decl of declarations) {
|
|
2294
|
-
if (
|
|
2295
|
-
({ variance, isConst } = extractVarianceModifiers(
|
|
2184
|
+
if (ts2.isTypeParameterDeclaration(decl)) {
|
|
2185
|
+
({ variance, isConst } = extractVarianceModifiers(ts2.getModifiers(decl)));
|
|
2296
2186
|
break;
|
|
2297
2187
|
}
|
|
2298
2188
|
}
|
|
@@ -2306,60 +2196,60 @@ function extractTypeParametersFromSignature(signature, checker) {
|
|
|
2306
2196
|
});
|
|
2307
2197
|
}
|
|
2308
2198
|
function getExportKind(declaration, type) {
|
|
2309
|
-
if (
|
|
2199
|
+
if (ts2.isFunctionDeclaration(declaration) || ts2.isFunctionExpression(declaration))
|
|
2310
2200
|
return "function";
|
|
2311
|
-
if (
|
|
2201
|
+
if (ts2.isClassDeclaration(declaration))
|
|
2312
2202
|
return "class";
|
|
2313
|
-
if (
|
|
2203
|
+
if (ts2.isInterfaceDeclaration(declaration))
|
|
2314
2204
|
return "interface";
|
|
2315
|
-
if (
|
|
2205
|
+
if (ts2.isTypeAliasDeclaration(declaration))
|
|
2316
2206
|
return "type";
|
|
2317
|
-
if (
|
|
2207
|
+
if (ts2.isEnumDeclaration(declaration))
|
|
2318
2208
|
return "enum";
|
|
2319
|
-
if (
|
|
2209
|
+
if (ts2.isModuleDeclaration(declaration) || ts2.isNamespaceExport(declaration))
|
|
2320
2210
|
return "namespace";
|
|
2321
|
-
if (
|
|
2211
|
+
if (ts2.isVariableDeclaration(declaration) && type.getConstructSignatures().length > 0)
|
|
2322
2212
|
return "class";
|
|
2323
|
-
if (
|
|
2213
|
+
if (ts2.isVariableDeclaration(declaration) && type.getCallSignatures().length > 0)
|
|
2324
2214
|
return "function";
|
|
2325
2215
|
return "variable";
|
|
2326
2216
|
}
|
|
2327
2217
|
|
|
2328
2218
|
// src/compiler/program.ts
|
|
2329
2219
|
import * as fs4 from "node:fs";
|
|
2330
|
-
import * as
|
|
2331
|
-
import
|
|
2220
|
+
import * as path5 from "node:path";
|
|
2221
|
+
import ts3 from "typescript";
|
|
2332
2222
|
function isJsFile(file) {
|
|
2333
2223
|
return /\.(js|mjs|cjs|jsx)$/.test(file);
|
|
2334
2224
|
}
|
|
2335
2225
|
function getScriptKind(file) {
|
|
2336
2226
|
if (/\.tsx$/.test(file))
|
|
2337
|
-
return
|
|
2227
|
+
return ts3.ScriptKind.TSX;
|
|
2338
2228
|
if (/\.jsx$/.test(file))
|
|
2339
|
-
return
|
|
2229
|
+
return ts3.ScriptKind.JSX;
|
|
2340
2230
|
if (/\.(js|mjs|cjs)$/.test(file))
|
|
2341
|
-
return
|
|
2342
|
-
return
|
|
2231
|
+
return ts3.ScriptKind.JS;
|
|
2232
|
+
return ts3.ScriptKind.TS;
|
|
2343
2233
|
}
|
|
2344
2234
|
var DEFAULT_COMPILER_OPTIONS = {
|
|
2345
|
-
target:
|
|
2346
|
-
module:
|
|
2235
|
+
target: ts3.ScriptTarget.Latest,
|
|
2236
|
+
module: ts3.ModuleKind.NodeNext,
|
|
2347
2237
|
lib: ["lib.es2021.d.ts"],
|
|
2348
2238
|
declaration: true,
|
|
2349
|
-
moduleResolution:
|
|
2239
|
+
moduleResolution: ts3.ModuleResolutionKind.NodeNext,
|
|
2350
2240
|
strict: true
|
|
2351
2241
|
};
|
|
2352
2242
|
function resolveWorkspaceEntry(pkgDir) {
|
|
2353
2243
|
const candidates = [
|
|
2354
|
-
|
|
2355
|
-
|
|
2356
|
-
|
|
2244
|
+
path5.join(pkgDir, "src", "index.ts"),
|
|
2245
|
+
path5.join(pkgDir, "src", "index.tsx"),
|
|
2246
|
+
path5.join(pkgDir, "index.ts")
|
|
2357
2247
|
];
|
|
2358
2248
|
try {
|
|
2359
|
-
const pkg = JSON.parse(fs4.readFileSync(
|
|
2249
|
+
const pkg = JSON.parse(fs4.readFileSync(path5.join(pkgDir, "package.json"), "utf-8"));
|
|
2360
2250
|
for (const field of [pkg.types, pkg.typings]) {
|
|
2361
2251
|
if (typeof field === "string") {
|
|
2362
|
-
candidates.push(
|
|
2252
|
+
candidates.push(path5.resolve(pkgDir, field));
|
|
2363
2253
|
}
|
|
2364
2254
|
}
|
|
2365
2255
|
} catch {}
|
|
@@ -2371,51 +2261,51 @@ function isDirentDir2(parent, entry) {
|
|
|
2371
2261
|
if (!entry.isSymbolicLink())
|
|
2372
2262
|
return false;
|
|
2373
2263
|
try {
|
|
2374
|
-
return fs4.statSync(
|
|
2264
|
+
return fs4.statSync(path5.join(parent, entry.name)).isDirectory();
|
|
2375
2265
|
} catch {
|
|
2376
2266
|
return false;
|
|
2377
2267
|
}
|
|
2378
2268
|
}
|
|
2379
2269
|
function extensionOf(file) {
|
|
2380
2270
|
if (file.endsWith(".d.mts"))
|
|
2381
|
-
return
|
|
2271
|
+
return ts3.Extension.Dmts;
|
|
2382
2272
|
if (file.endsWith(".d.cts"))
|
|
2383
|
-
return
|
|
2273
|
+
return ts3.Extension.Dcts;
|
|
2384
2274
|
if (file.endsWith(".d.ts"))
|
|
2385
|
-
return
|
|
2275
|
+
return ts3.Extension.Dts;
|
|
2386
2276
|
if (file.endsWith(".mts"))
|
|
2387
|
-
return
|
|
2277
|
+
return ts3.Extension.Mts;
|
|
2388
2278
|
if (file.endsWith(".cts"))
|
|
2389
|
-
return
|
|
2279
|
+
return ts3.Extension.Cts;
|
|
2390
2280
|
if (file.endsWith(".tsx"))
|
|
2391
|
-
return
|
|
2281
|
+
return ts3.Extension.Tsx;
|
|
2392
2282
|
if (file.endsWith(".ts"))
|
|
2393
|
-
return
|
|
2283
|
+
return ts3.Extension.Ts;
|
|
2394
2284
|
if (file.endsWith(".mjs"))
|
|
2395
|
-
return
|
|
2285
|
+
return ts3.Extension.Mjs;
|
|
2396
2286
|
if (file.endsWith(".cjs"))
|
|
2397
|
-
return
|
|
2287
|
+
return ts3.Extension.Cjs;
|
|
2398
2288
|
if (file.endsWith(".jsx"))
|
|
2399
|
-
return
|
|
2289
|
+
return ts3.Extension.Jsx;
|
|
2400
2290
|
if (file.endsWith(".js"))
|
|
2401
|
-
return
|
|
2402
|
-
return
|
|
2291
|
+
return ts3.Extension.Js;
|
|
2292
|
+
return ts3.Extension.Ts;
|
|
2403
2293
|
}
|
|
2404
2294
|
function resolveProjectReferences(configPath, parsedConfig) {
|
|
2405
2295
|
const additionalFiles = [];
|
|
2406
2296
|
if (!parsedConfig.projectReferences?.length) {
|
|
2407
2297
|
return additionalFiles;
|
|
2408
2298
|
}
|
|
2409
|
-
const configDir =
|
|
2299
|
+
const configDir = path5.dirname(configPath);
|
|
2410
2300
|
for (const ref of parsedConfig.projectReferences) {
|
|
2411
|
-
const refPath =
|
|
2412
|
-
const refConfigPath = fs4.existsSync(
|
|
2301
|
+
const refPath = path5.resolve(configDir, ref.path);
|
|
2302
|
+
const refConfigPath = fs4.existsSync(path5.join(refPath, "tsconfig.json")) ? path5.join(refPath, "tsconfig.json") : refPath;
|
|
2413
2303
|
if (!fs4.existsSync(refConfigPath))
|
|
2414
2304
|
continue;
|
|
2415
|
-
const refConfigFile =
|
|
2305
|
+
const refConfigFile = ts3.readConfigFile(refConfigPath, ts3.sys.readFile);
|
|
2416
2306
|
if (refConfigFile.error)
|
|
2417
2307
|
continue;
|
|
2418
|
-
const refParsed =
|
|
2308
|
+
const refParsed = ts3.parseJsonConfigFileContent(refConfigFile.config, ts3.sys, path5.dirname(refConfigPath));
|
|
2419
2309
|
additionalFiles.push(...refParsed.fileNames);
|
|
2420
2310
|
}
|
|
2421
2311
|
return additionalFiles;
|
|
@@ -2448,7 +2338,7 @@ function buildWorkspaceMap(baseDir) {
|
|
|
2448
2338
|
let rootDir;
|
|
2449
2339
|
let workspaceGlobs2 = [];
|
|
2450
2340
|
for (let i = 0;i < 10; i++) {
|
|
2451
|
-
const pnpmPath =
|
|
2341
|
+
const pnpmPath = path5.join(currentDir, "pnpm-workspace.yaml");
|
|
2452
2342
|
if (fs4.existsSync(pnpmPath)) {
|
|
2453
2343
|
try {
|
|
2454
2344
|
const yamlContent = fs4.readFileSync(pnpmPath, "utf-8");
|
|
@@ -2459,7 +2349,7 @@ function buildWorkspaceMap(baseDir) {
|
|
|
2459
2349
|
}
|
|
2460
2350
|
} catch {}
|
|
2461
2351
|
}
|
|
2462
|
-
const pkgPath =
|
|
2352
|
+
const pkgPath = path5.join(currentDir, "package.json");
|
|
2463
2353
|
if (fs4.existsSync(pkgPath)) {
|
|
2464
2354
|
try {
|
|
2465
2355
|
const pkg = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
|
|
@@ -2470,7 +2360,7 @@ function buildWorkspaceMap(baseDir) {
|
|
|
2470
2360
|
}
|
|
2471
2361
|
} catch {}
|
|
2472
2362
|
}
|
|
2473
|
-
const parent =
|
|
2363
|
+
const parent = path5.dirname(currentDir);
|
|
2474
2364
|
if (parent === currentDir)
|
|
2475
2365
|
break;
|
|
2476
2366
|
currentDir = parent;
|
|
@@ -2479,15 +2369,15 @@ function buildWorkspaceMap(baseDir) {
|
|
|
2479
2369
|
return;
|
|
2480
2370
|
const packages = new Map;
|
|
2481
2371
|
for (const glob of workspaceGlobs2) {
|
|
2482
|
-
const globDir =
|
|
2372
|
+
const globDir = path5.join(rootDir, glob.replace(/\/\*$/, ""));
|
|
2483
2373
|
if (!fs4.existsSync(globDir) || !fs4.statSync(globDir).isDirectory())
|
|
2484
2374
|
continue;
|
|
2485
2375
|
const entries = fs4.readdirSync(globDir, { withFileTypes: true });
|
|
2486
2376
|
for (const entry of entries) {
|
|
2487
2377
|
if (!isDirentDir2(globDir, entry))
|
|
2488
2378
|
continue;
|
|
2489
|
-
const pkgDir =
|
|
2490
|
-
const pkgJsonPath =
|
|
2379
|
+
const pkgDir = path5.join(globDir, entry.name);
|
|
2380
|
+
const pkgJsonPath = path5.join(pkgDir, "package.json");
|
|
2491
2381
|
if (!fs4.existsSync(pkgJsonPath))
|
|
2492
2382
|
continue;
|
|
2493
2383
|
try {
|
|
@@ -2505,7 +2395,7 @@ function discoverAmbientTypePackages(baseDir) {
|
|
|
2505
2395
|
const seen = new Set;
|
|
2506
2396
|
let currentDir = baseDir;
|
|
2507
2397
|
for (let i = 0;i < 10; i++) {
|
|
2508
|
-
const typesDir =
|
|
2398
|
+
const typesDir = path5.join(currentDir, "node_modules", "@types");
|
|
2509
2399
|
try {
|
|
2510
2400
|
if (fs4.existsSync(typesDir) && fs4.statSync(typesDir).isDirectory()) {
|
|
2511
2401
|
for (const entry of fs4.readdirSync(typesDir, { withFileTypes: true })) {
|
|
@@ -2518,7 +2408,7 @@ function discoverAmbientTypePackages(baseDir) {
|
|
|
2518
2408
|
}
|
|
2519
2409
|
}
|
|
2520
2410
|
} catch {}
|
|
2521
|
-
const parent =
|
|
2411
|
+
const parent = path5.dirname(currentDir);
|
|
2522
2412
|
if (parent === currentDir)
|
|
2523
2413
|
break;
|
|
2524
2414
|
currentDir = parent;
|
|
@@ -2527,24 +2417,24 @@ function discoverAmbientTypePackages(baseDir) {
|
|
|
2527
2417
|
}
|
|
2528
2418
|
function createProgram(options) {
|
|
2529
2419
|
const { content } = options;
|
|
2530
|
-
const entryFile =
|
|
2531
|
-
const baseDir =
|
|
2532
|
-
let configPath =
|
|
2420
|
+
const entryFile = path5.resolve(options.entryFile);
|
|
2421
|
+
const baseDir = path5.resolve(options.baseDir ?? path5.dirname(entryFile));
|
|
2422
|
+
let configPath = ts3.findConfigFile(baseDir, ts3.sys.fileExists, "tsconfig.json");
|
|
2533
2423
|
if (!configPath) {
|
|
2534
|
-
configPath =
|
|
2424
|
+
configPath = ts3.findConfigFile(baseDir, ts3.sys.fileExists, "jsconfig.json");
|
|
2535
2425
|
}
|
|
2536
2426
|
let compilerOptions = { ...DEFAULT_COMPILER_OPTIONS };
|
|
2537
2427
|
let additionalRootFiles = [];
|
|
2538
2428
|
if (configPath) {
|
|
2539
|
-
const configFile =
|
|
2540
|
-
const parsedConfig =
|
|
2429
|
+
const configFile = ts3.readConfigFile(configPath, ts3.sys.readFile);
|
|
2430
|
+
const parsedConfig = ts3.parseJsonConfigFileContent(configFile.config, ts3.sys, path5.dirname(configPath));
|
|
2541
2431
|
compilerOptions = { ...compilerOptions, ...parsedConfig.options };
|
|
2542
2432
|
additionalRootFiles = resolveProjectReferences(configPath, parsedConfig);
|
|
2543
2433
|
let sourceFiles = parsedConfig.fileNames.filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("/dist/") && !f.includes("/node_modules/"));
|
|
2544
2434
|
if (/\.d\.[cm]?ts$/.test(entryFile)) {
|
|
2545
2435
|
sourceFiles = sourceFiles.filter((f) => {
|
|
2546
2436
|
try {
|
|
2547
|
-
return !
|
|
2437
|
+
return !ts3.getOutputFileNames(parsedConfig, f, !ts3.sys.useCaseSensitiveFileNames).some((out) => path5.resolve(out) === entryFile);
|
|
2548
2438
|
} catch {
|
|
2549
2439
|
return true;
|
|
2550
2440
|
}
|
|
@@ -2572,7 +2462,7 @@ function createProgram(options) {
|
|
|
2572
2462
|
}
|
|
2573
2463
|
}
|
|
2574
2464
|
const workspaceMap = buildWorkspaceMap(baseDir);
|
|
2575
|
-
const compilerHost =
|
|
2465
|
+
const compilerHost = ts3.createCompilerHost(compilerOptions, true);
|
|
2576
2466
|
let inMemorySource;
|
|
2577
2467
|
if (workspaceMap) {
|
|
2578
2468
|
compilerHost.resolveModuleNameLiterals = (moduleLiterals, containingFile, redirectedReference, options2, containingSourceFile) => moduleLiterals.map((literal) => {
|
|
@@ -2589,12 +2479,12 @@ function createProgram(options) {
|
|
|
2589
2479
|
};
|
|
2590
2480
|
}
|
|
2591
2481
|
}
|
|
2592
|
-
const mode =
|
|
2593
|
-
return
|
|
2482
|
+
const mode = ts3.getModeForUsageLocation(containingSourceFile, literal, options2);
|
|
2483
|
+
return ts3.resolveModuleName(literal.text, containingFile, options2, compilerHost, undefined, redirectedReference, mode);
|
|
2594
2484
|
});
|
|
2595
2485
|
}
|
|
2596
2486
|
if (content !== undefined) {
|
|
2597
|
-
inMemorySource =
|
|
2487
|
+
inMemorySource = ts3.createSourceFile(entryFile, content, ts3.ScriptTarget.Latest, true, getScriptKind(entryFile));
|
|
2598
2488
|
const originalGetSourceFile = compilerHost.getSourceFile.bind(compilerHost);
|
|
2599
2489
|
compilerHost.getSourceFile = (fileName, languageVersion, onError, shouldCreateNewSourceFile) => {
|
|
2600
2490
|
if (fileName === entryFile) {
|
|
@@ -2604,7 +2494,7 @@ function createProgram(options) {
|
|
|
2604
2494
|
};
|
|
2605
2495
|
}
|
|
2606
2496
|
const rootFiles = [entryFile, ...additionalRootFiles];
|
|
2607
|
-
const program =
|
|
2497
|
+
const program = ts3.createProgram(rootFiles, compilerOptions, compilerHost);
|
|
2608
2498
|
const sourceFile = inMemorySource ?? program.getSourceFile(entryFile);
|
|
2609
2499
|
return {
|
|
2610
2500
|
program,
|
|
@@ -2625,77 +2515,6 @@ import ts5 from "typescript";
|
|
|
2625
2515
|
// src/types/schema-builder.ts
|
|
2626
2516
|
import ts4 from "typescript";
|
|
2627
2517
|
|
|
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
2518
|
// src/schema/builtins.ts
|
|
2700
2519
|
var BUILTIN_TYPE_SCHEMAS = {
|
|
2701
2520
|
Array: { type: "array" },
|
|
@@ -3025,12 +2844,10 @@ function getTypeOrigin(type, _checker) {
|
|
|
3025
2844
|
if (!declarations || declarations.length === 0)
|
|
3026
2845
|
return;
|
|
3027
2846
|
const fileName = declarations[0].getSourceFile().fileName;
|
|
3028
|
-
const
|
|
3029
|
-
if (
|
|
3030
|
-
return;
|
|
3031
|
-
if (match[1] === "typescript")
|
|
2847
|
+
const pkg = packageNameFromPath(fileName);
|
|
2848
|
+
if (pkg === "typescript")
|
|
3032
2849
|
return;
|
|
3033
|
-
return
|
|
2850
|
+
return pkg;
|
|
3034
2851
|
}
|
|
3035
2852
|
function isBuiltinGeneric(name) {
|
|
3036
2853
|
return BUILTIN_GENERICS.has(name);
|
|
@@ -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,7 +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
6964
|
function isLibFile(fileName) {
|
|
7225
6965
|
return fileName.includes("/typescript/lib/lib.") || fileName.includes("\\typescript\\lib\\lib.");
|
|
7226
6966
|
}
|
|
@@ -7248,91 +6988,12 @@ function createExternalExpansionPredicate(opts) {
|
|
|
7248
6988
|
const fileName = decl.getSourceFile().fileName;
|
|
7249
6989
|
if (isLibFile(fileName))
|
|
7250
6990
|
return false;
|
|
7251
|
-
const
|
|
7252
|
-
if (
|
|
7253
|
-
return packageAllowed(
|
|
6991
|
+
const pkg = packageNameFromPath(fileName);
|
|
6992
|
+
if (pkg)
|
|
6993
|
+
return packageAllowed(pkg);
|
|
7254
6994
|
return true;
|
|
7255
6995
|
};
|
|
7256
6996
|
}
|
|
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
6997
|
function expandReachableTypes(exportedSymbols, ctx, opts) {
|
|
7337
6998
|
if (opts.followExternal === false)
|
|
7338
6999
|
return;
|
|
@@ -7801,44 +7462,7 @@ async function extract(options) {
|
|
|
7801
7462
|
...included ? {} : { skipReason: "filtered" }
|
|
7802
7463
|
});
|
|
7803
7464
|
}
|
|
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
|
-
}
|
|
7465
|
+
const followExternal = options.followExternal;
|
|
7842
7466
|
const ctx = createContext(program, sourceFile, {
|
|
7843
7467
|
maxTypeDepth,
|
|
7844
7468
|
includePrivate,
|
|
@@ -7870,12 +7494,10 @@ async function extract(options) {
|
|
|
7870
7494
|
const allDecls = [...targetSymbol.declarations ?? [], ...symbol.declarations ?? []];
|
|
7871
7495
|
for (const decl of allDecls) {
|
|
7872
7496
|
const sf = decl.getSourceFile();
|
|
7873
|
-
|
|
7874
|
-
|
|
7875
|
-
|
|
7876
|
-
|
|
7877
|
-
break;
|
|
7878
|
-
}
|
|
7497
|
+
const pkg = sf && packageNameFromPath(sf.fileName);
|
|
7498
|
+
if (pkg) {
|
|
7499
|
+
externalPackage = pkg;
|
|
7500
|
+
break;
|
|
7879
7501
|
}
|
|
7880
7502
|
if (ts19.isExportSpecifier(decl)) {
|
|
7881
7503
|
const exportDecl = decl.parent?.parent;
|
|
@@ -8081,9 +7703,6 @@ async function extract(options) {
|
|
|
8081
7703
|
suggestion: "Check serialization errors for these exports"
|
|
8082
7704
|
});
|
|
8083
7705
|
}
|
|
8084
|
-
if (evaluate) {
|
|
8085
|
-
await calibrateDiagnostics(diagnostics, evaluate);
|
|
8086
|
-
}
|
|
8087
7706
|
return {
|
|
8088
7707
|
spec,
|
|
8089
7708
|
diagnostics,
|
|
@@ -9004,8 +8623,6 @@ export {
|
|
|
9004
8623
|
PRIMITIVES,
|
|
9005
8624
|
NUMBER_PROTOTYPE_METHODS,
|
|
9006
8625
|
LATEST_VERSION,
|
|
9007
|
-
JEV_MODEL,
|
|
9008
|
-
JEV_CONFIDENCE,
|
|
9009
8626
|
CacheManager,
|
|
9010
8627
|
CONFIG_FILENAME,
|
|
9011
8628
|
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.0",
|
|
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
|
}
|