@openpkg-ts/sdk 0.35.1 → 0.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -29,7 +29,7 @@ import {
29
29
  toPagefindRecords,
30
30
  toSearchIndex,
31
31
  toSearchIndexJSON
32
- } from "./shared/chunk-4fgxg5jj.js";
32
+ } from "./shared/chunk-hnajr1tb.js";
33
33
 
34
34
  // src/primitives/diff.ts
35
35
  import {
@@ -1746,7 +1746,9 @@ function parseExamplesFromTags(tags) {
1746
1746
  function stripParamSeparator(text) {
1747
1747
  if (!text)
1748
1748
  return;
1749
- const stripped = text.replace(/^-\s*/, "").trim();
1749
+ let stripped = text.replace(/^-\s*/, "").trim();
1750
+ const parts = stripped.split(/\n\s*\n/);
1751
+ stripped = parts[0].trim();
1750
1752
  return stripped || undefined;
1751
1753
  }
1752
1754
  function stripTypeParamSeparator(text) {
@@ -1951,6 +1953,21 @@ function isSymbolDeprecated(symbol) {
1951
1953
  }
1952
1954
  return { deprecated: true, reason };
1953
1955
  }
1956
+ if (ts2.isExportSpecifier(declaration)) {
1957
+ const exportDecl = declaration.parent?.parent;
1958
+ if (exportDecl && ts2.isExportDeclaration(exportDecl)) {
1959
+ const parentTag = ts2.getJSDocDeprecatedTag(exportDecl);
1960
+ if (parentTag) {
1961
+ let reason;
1962
+ if (typeof parentTag.comment === "string") {
1963
+ reason = parentTag.comment;
1964
+ } else if (Array.isArray(parentTag.comment)) {
1965
+ reason = parentTag.comment.map((c) => typeof c === "string" ? c : c.text).join("");
1966
+ }
1967
+ return { deprecated: true, reason };
1968
+ }
1969
+ }
1970
+ }
1954
1971
  }
1955
1972
  return { deprecated: false };
1956
1973
  }
@@ -2011,6 +2028,8 @@ function getExportKind(declaration, type) {
2011
2028
  return "enum";
2012
2029
  if (ts2.isModuleDeclaration(declaration) || ts2.isNamespaceExport(declaration))
2013
2030
  return "namespace";
2031
+ if (ts2.isVariableDeclaration(declaration) && type.getConstructSignatures().length > 0)
2032
+ return "class";
2014
2033
  if (ts2.isVariableDeclaration(declaration) && type.getCallSignatures().length > 0)
2015
2034
  return "function";
2016
2035
  return "variable";
@@ -2155,6 +2174,63 @@ var ARRAY_PROTOTYPE_METHODS = new Set([
2155
2174
  "toString",
2156
2175
  "toLocaleString"
2157
2176
  ]);
2177
+ var STRING_PROTOTYPE_METHODS = new Set([
2178
+ "charAt",
2179
+ "charCodeAt",
2180
+ "codePointAt",
2181
+ "concat",
2182
+ "endsWith",
2183
+ "includes",
2184
+ "indexOf",
2185
+ "lastIndexOf",
2186
+ "localeCompare",
2187
+ "match",
2188
+ "matchAll",
2189
+ "normalize",
2190
+ "padEnd",
2191
+ "padStart",
2192
+ "repeat",
2193
+ "replace",
2194
+ "replaceAll",
2195
+ "search",
2196
+ "slice",
2197
+ "split",
2198
+ "startsWith",
2199
+ "substring",
2200
+ "toLocaleLowerCase",
2201
+ "toLocaleUpperCase",
2202
+ "toLowerCase",
2203
+ "toUpperCase",
2204
+ "trim",
2205
+ "trimEnd",
2206
+ "trimStart",
2207
+ "at",
2208
+ "bold",
2209
+ "fixed",
2210
+ "italics",
2211
+ "link",
2212
+ "small",
2213
+ "strike",
2214
+ "sub",
2215
+ "sup",
2216
+ "anchor",
2217
+ "big",
2218
+ "blink",
2219
+ "fontcolor",
2220
+ "fontsize",
2221
+ "substr",
2222
+ "toString",
2223
+ "valueOf",
2224
+ "length"
2225
+ ]);
2226
+ var NUMBER_PROTOTYPE_METHODS = new Set([
2227
+ "toFixed",
2228
+ "toExponential",
2229
+ "toPrecision",
2230
+ "toString",
2231
+ "valueOf",
2232
+ "toLocaleString"
2233
+ ]);
2158
2234
  function isPrimitiveName(name) {
2159
2235
  return PRIMITIVES.has(name);
2160
2236
  }
@@ -2227,40 +2303,13 @@ function buildSchema(type, checker, ctx) {
2227
2303
  const schema = buildSchemaInternal(type, checker, ctx);
2228
2304
  return ensureNonEmptySchema(schema, type, checker);
2229
2305
  }
2230
- function buildSchemaInternal(type, checker, ctx) {
2231
- if (isAtMaxDepth(ctx)) {
2232
- return { type: checker.typeToString(type) };
2233
- }
2234
- if (ctx?.visitedTypes.has(type)) {
2235
- const callSignatures = type.getCallSignatures();
2236
- if (callSignatures.length > 0) {
2237
- return buildFunctionSchema(callSignatures, checker, ctx);
2238
- }
2239
- const symbol2 = type.getSymbol() || type.aliasSymbol;
2240
- if (symbol2 && !isAnonymous(type)) {
2241
- const name = symbol2.getName();
2242
- const schema = { $ref: `#/types/${name}` };
2243
- const typeRef2 = type;
2244
- if (typeRef2.target) {
2245
- const typeArgs2 = checker.getTypeArguments(typeRef2);
2246
- if (typeArgs2 && typeArgs2.length > 0) {
2247
- ctx.visitedTypes.delete(type);
2248
- schema.typeArguments = typeArgs2.map((t) => buildSchema(t, checker, ctx));
2249
- ctx.visitedTypes.add(type);
2250
- }
2251
- }
2252
- return schema;
2253
- }
2254
- if (type.flags & ts3.TypeFlags.Object) {
2255
- const properties = type.getProperties();
2256
- if (properties.length > 0) {
2257
- return buildObjectSchema(properties, checker, ctx, type);
2258
- }
2306
+ function buildMaxDepthSchema(type, checker) {
2307
+ const symbol = type.getSymbol() || type.aliasSymbol;
2308
+ if (symbol && !isAnonymous(type)) {
2309
+ const name = symbol.getName();
2310
+ if (!name.startsWith("__") && !isPrimitiveName(name)) {
2311
+ return { $ref: `#/types/${name}` };
2259
2312
  }
2260
- return { type: checker.typeToString(type) };
2261
- }
2262
- if (ctx && type.flags & ts3.TypeFlags.Object) {
2263
- ctx.visitedTypes.add(type);
2264
2313
  }
2265
2314
  if (type.flags & ts3.TypeFlags.String)
2266
2315
  return { type: "string" };
@@ -2274,223 +2323,281 @@ function buildSchemaInternal(type, checker, ctx) {
2274
2323
  return { type: "null" };
2275
2324
  if (type.flags & ts3.TypeFlags.Void)
2276
2325
  return { type: "void" };
2277
- if (type.flags & ts3.TypeFlags.Any)
2278
- return { type: "any" };
2279
- if (type.flags & ts3.TypeFlags.Unknown)
2280
- return { type: "unknown" };
2281
- if (type.flags & ts3.TypeFlags.Never)
2282
- return { type: "never" };
2283
- if (type.flags & ts3.TypeFlags.BigInt)
2284
- return { type: "bigint" };
2285
- if (type.flags & ts3.TypeFlags.ESSymbol)
2286
- return { type: "symbol" };
2287
- if (type.isThisType?.()) {
2288
- const constraint = type.getConstraint?.();
2289
- const symbol2 = constraint?.getSymbol() ?? type.getSymbol();
2290
- if (symbol2 && !isAnonymous(type)) {
2291
- return {
2292
- $ref: `#/types/${symbol2.getName()}`,
2293
- "x-ts-type": "this"
2294
- };
2295
- }
2296
- }
2297
- if (type.flags & ts3.TypeFlags.StringLiteral) {
2298
- const literal = type.value;
2299
- return { type: "string", enum: [literal] };
2326
+ if (type.isUnion()) {
2327
+ const schemas = type.types.map((t) => buildMaxDepthSchema(t, checker));
2328
+ return { anyOf: schemas };
2300
2329
  }
2301
- if (type.flags & ts3.TypeFlags.NumberLiteral) {
2302
- const literal = type.value;
2303
- return { type: "number", enum: [literal] };
2330
+ if (type.isIntersection()) {
2331
+ const schemas = type.types.map((t) => buildMaxDepthSchema(t, checker));
2332
+ return { allOf: schemas };
2304
2333
  }
2305
- if (type.flags & ts3.TypeFlags.BooleanLiteral) {
2306
- const typeString2 = checker.typeToString(type);
2307
- return { type: "boolean", enum: [typeString2 === "true"] };
2334
+ return { type: checker.typeToString(type) };
2335
+ }
2336
+ function buildSchemaInternal(type, checker, ctx) {
2337
+ if (isAtMaxDepth(ctx)) {
2338
+ return buildMaxDepthSchema(type, checker);
2308
2339
  }
2309
- if (type.isUnion()) {
2310
- const types = type.types;
2311
- const allStringLiterals = types.every((t) => t.flags & ts3.TypeFlags.StringLiteral);
2312
- if (allStringLiterals) {
2313
- const enumValues = types.map((t) => t.value);
2314
- return { type: "string", enum: enumValues };
2315
- }
2316
- const allNumberLiterals = types.every((t) => t.flags & ts3.TypeFlags.NumberLiteral);
2317
- if (allNumberLiterals) {
2318
- const enumValues = types.map((t) => t.value);
2319
- return { type: "number", enum: enumValues };
2320
- }
2321
- if (ctx) {
2322
- return withDepth(ctx, () => ({
2323
- anyOf: types.map((t) => buildSchema(t, checker, ctx))
2324
- }));
2340
+ if (ctx?.visitedTypes.has(type)) {
2341
+ const callSignatures = type.getCallSignatures();
2342
+ if (callSignatures.length > 0) {
2343
+ return buildFunctionSchema(callSignatures, checker, ctx);
2325
2344
  }
2326
- return { anyOf: types.map((t) => buildSchema(t, checker, ctx)) };
2345
+ const symbol = type.getSymbol() || type.aliasSymbol;
2346
+ if (symbol && !isAnonymous(type)) {
2347
+ return { $ref: `#/types/${symbol.getName()}` };
2348
+ }
2349
+ return { type: checker.typeToString(type) };
2327
2350
  }
2328
- const isIntersectionType = type.isIntersection() || !!(type.flags & ts3.TypeFlags.Intersection);
2329
- if (isIntersectionType && "types" in type) {
2330
- const intersectionType = type;
2331
- const filteredTypes = intersectionType.types.filter((t) => !(t.flags & ts3.TypeFlags.Never));
2332
- if (filteredTypes.length === 0) {
2351
+ const addedToVisited = !!(ctx && type.flags & ts3.TypeFlags.Object);
2352
+ if (addedToVisited) {
2353
+ ctx.visitedTypes.add(type);
2354
+ }
2355
+ try {
2356
+ if (type.flags & ts3.TypeFlags.String)
2357
+ return { type: "string" };
2358
+ if (type.flags & ts3.TypeFlags.Number)
2359
+ return { type: "number" };
2360
+ if (type.flags & ts3.TypeFlags.Boolean)
2361
+ return { type: "boolean" };
2362
+ if (type.flags & ts3.TypeFlags.Undefined)
2363
+ return { type: "undefined" };
2364
+ if (type.flags & ts3.TypeFlags.Null)
2365
+ return { type: "null" };
2366
+ if (type.flags & ts3.TypeFlags.Void)
2367
+ return { type: "void" };
2368
+ if (type.flags & ts3.TypeFlags.Any)
2369
+ return { type: "any" };
2370
+ if (type.flags & ts3.TypeFlags.Unknown)
2371
+ return { type: "unknown" };
2372
+ if (type.flags & ts3.TypeFlags.Never)
2333
2373
  return { type: "never" };
2374
+ if (type.flags & ts3.TypeFlags.BigInt)
2375
+ return { type: "bigint" };
2376
+ if (type.flags & ts3.TypeFlags.ESSymbol)
2377
+ return { type: "symbol" };
2378
+ if (type.isThisType === true) {
2379
+ const constraint = type.getConstraint?.();
2380
+ const symbol2 = constraint?.getSymbol() ?? type.getSymbol();
2381
+ if (symbol2 && !isAnonymous(type)) {
2382
+ return {
2383
+ $ref: `#/types/${symbol2.getName()}`,
2384
+ "x-ts-type": "this"
2385
+ };
2386
+ }
2334
2387
  }
2335
- if (filteredTypes.length === 1) {
2336
- return buildSchema(filteredTypes[0], checker, ctx);
2337
- }
2338
- if (ctx) {
2339
- return withDepth(ctx, () => ({
2340
- allOf: filteredTypes.map((t) => buildSchema(t, checker, ctx))
2341
- }));
2388
+ if (type.flags & ts3.TypeFlags.StringLiteral) {
2389
+ const literal = type.value;
2390
+ return { type: "string", enum: [literal] };
2391
+ }
2392
+ if (type.flags & ts3.TypeFlags.NumberLiteral) {
2393
+ const literal = type.value;
2394
+ return { type: "number", enum: [literal] };
2395
+ }
2396
+ if (type.flags & ts3.TypeFlags.BooleanLiteral) {
2397
+ const typeString2 = checker.typeToString(type);
2398
+ return { type: "boolean", enum: [typeString2 === "true"] };
2399
+ }
2400
+ if (type.aliasSymbol && !type.aliasTypeArguments?.length) {
2401
+ const aliasName = type.aliasSymbol.getName();
2402
+ if (!aliasName.startsWith("__") && !isPrimitiveName(aliasName)) {
2403
+ const packageOrigin = getTypeOrigin(type, checker);
2404
+ const schema = { $ref: `#/types/${aliasName}` };
2405
+ if (packageOrigin) {
2406
+ setSchemaExtension(schema, "x-ts-package", packageOrigin);
2407
+ }
2408
+ return schema;
2409
+ }
2342
2410
  }
2343
- return { allOf: filteredTypes.map((t) => buildSchema(t, checker, ctx)) };
2344
- }
2345
- const typeString = checker.typeToString(type);
2346
- if (typeString === "never[]" || typeString === "[]") {
2347
- return { type: "array", prefixedItems: [], minItems: 0, maxItems: 0 };
2348
- }
2349
- const symbol = type.getSymbol() || type.aliasSymbol;
2350
- if (symbol?.getName() === "Array" && isBuiltinSymbol(symbol)) {
2351
- const typeRef2 = type;
2352
- const typeArgs2 = typeRef2.target ? checker.getTypeArguments(typeRef2) : undefined;
2353
- const elementType = typeArgs2?.[0];
2354
- if (elementType) {
2355
- return { type: "array", items: buildSchema(elementType, checker, ctx) };
2356
- }
2357
- return { type: "array", items: { "x-ts-type": "unknown" } };
2358
- }
2359
- if (checker.isArrayType(type)) {
2360
- const arrayTypeRef = type;
2361
- const arrayTypeArgs = checker.getTypeArguments(arrayTypeRef);
2362
- const elementType = arrayTypeArgs?.[0];
2363
- if (elementType) {
2411
+ if (type.isUnion()) {
2412
+ const types = type.types;
2413
+ const allStringLiterals = types.every((t) => t.flags & ts3.TypeFlags.StringLiteral);
2414
+ if (allStringLiterals) {
2415
+ const enumValues = types.map((t) => t.value);
2416
+ return { type: "string", enum: enumValues };
2417
+ }
2418
+ const allNumberLiterals = types.every((t) => t.flags & ts3.TypeFlags.NumberLiteral);
2419
+ if (allNumberLiterals) {
2420
+ const enumValues = types.map((t) => t.value);
2421
+ return { type: "number", enum: enumValues };
2422
+ }
2364
2423
  if (ctx) {
2365
2424
  return withDepth(ctx, () => ({
2366
- type: "array",
2367
- items: buildSchema(elementType, checker, ctx)
2425
+ anyOf: types.map((t) => buildSchema(t, checker, ctx))
2368
2426
  }));
2369
2427
  }
2370
- return { type: "array", items: buildSchema(elementType, checker, ctx) };
2428
+ return { anyOf: types.map((t) => buildSchema(t, checker, ctx)) };
2429
+ }
2430
+ const isIntersectionType = type.isIntersection() || !!(type.flags & ts3.TypeFlags.Intersection);
2431
+ if (isIntersectionType && "types" in type) {
2432
+ const intersectionType = type;
2433
+ const filteredTypes = intersectionType.types.filter((t) => !(t.flags & ts3.TypeFlags.Never));
2434
+ if (filteredTypes.length === 0) {
2435
+ return { type: "never" };
2436
+ }
2437
+ if (filteredTypes.length === 1) {
2438
+ return buildSchema(filteredTypes[0], checker, ctx);
2439
+ }
2440
+ if (ctx) {
2441
+ return withDepth(ctx, () => ({
2442
+ allOf: filteredTypes.map((t) => buildSchema(t, checker, ctx))
2443
+ }));
2444
+ }
2445
+ return { allOf: filteredTypes.map((t) => buildSchema(t, checker, ctx)) };
2371
2446
  }
2372
- return { type: "array" };
2373
- }
2374
- if (checker.isTupleType(type)) {
2375
- const tupleTypeRef = type;
2376
- const elementTypes = checker.getTypeArguments(tupleTypeRef) ?? [];
2377
- if (ctx) {
2378
- return withDepth(ctx, () => {
2379
- const prevInTupleElement = ctx.inTupleElement;
2380
- ctx.inTupleElement = true;
2381
- try {
2382
- return {
2447
+ const typeString = checker.typeToString(type);
2448
+ if (typeString === "never[]" || typeString === "[]") {
2449
+ return { type: "array", prefixedItems: [], minItems: 0, maxItems: 0 };
2450
+ }
2451
+ const symbol = type.getSymbol() || type.aliasSymbol;
2452
+ if (symbol?.getName() === "Array" && isBuiltinSymbol(symbol)) {
2453
+ const typeRef2 = type;
2454
+ const typeArgs2 = typeRef2.target ? checker.getTypeArguments(typeRef2) : undefined;
2455
+ const elementType = typeArgs2?.[0];
2456
+ if (elementType) {
2457
+ return { type: "array", items: buildSchema(elementType, checker, ctx) };
2458
+ }
2459
+ return { type: "array", items: { "x-ts-type": "unknown" } };
2460
+ }
2461
+ if (checker.isArrayType(type)) {
2462
+ const arrayTypeRef = type;
2463
+ const arrayTypeArgs = checker.getTypeArguments(arrayTypeRef);
2464
+ const elementType = arrayTypeArgs?.[0];
2465
+ if (elementType) {
2466
+ if (ctx) {
2467
+ return withDepth(ctx, () => ({
2383
2468
  type: "array",
2384
- prefixedItems: elementTypes.map((t) => buildSchema(t, checker, ctx)),
2385
- minItems: elementTypes.length,
2386
- maxItems: elementTypes.length
2387
- };
2388
- } finally {
2389
- ctx.inTupleElement = prevInTupleElement;
2469
+ items: buildSchema(elementType, checker, ctx)
2470
+ }));
2390
2471
  }
2391
- });
2392
- }
2393
- return {
2394
- type: "array",
2395
- prefixedItems: elementTypes.map((t) => buildSchema(t, checker, ctx)),
2396
- minItems: elementTypes.length,
2397
- maxItems: elementTypes.length
2398
- };
2399
- }
2400
- const typeRef = type;
2401
- const typeArgs = typeRef.target ? checker.getTypeArguments(typeRef) : undefined;
2402
- if (typeRef.target && typeArgs && typeArgs.length > 0) {
2403
- const symbol2 = typeRef.target.getSymbol();
2404
- const name = symbol2?.getName();
2405
- if (name && BUILTIN_TYPES.has(name)) {
2406
- return { $ref: `#/types/${name}` };
2472
+ return { type: "array", items: buildSchema(elementType, checker, ctx) };
2473
+ }
2474
+ return { type: "array" };
2407
2475
  }
2408
- if (name && (isBuiltinGeneric(name) || !isAnonymous(typeRef.target))) {
2409
- const packageOrigin = getTypeOrigin(typeRef.target, checker);
2476
+ if (checker.isTupleType(type)) {
2477
+ const tupleTypeRef = type;
2478
+ const elementTypes = checker.getTypeArguments(tupleTypeRef) ?? [];
2410
2479
  if (ctx) {
2411
2480
  return withDepth(ctx, () => {
2412
- const schema2 = {
2413
- $ref: `#/types/${name}`,
2414
- typeArguments: typeArgs.map((t) => buildSchema(t, checker, ctx))
2415
- };
2416
- if (packageOrigin) {
2417
- setSchemaExtension(schema2, "x-ts-package", packageOrigin);
2481
+ const prevInTupleElement = ctx.inTupleElement;
2482
+ ctx.inTupleElement = true;
2483
+ try {
2484
+ return {
2485
+ type: "array",
2486
+ prefixedItems: elementTypes.map((t) => buildSchema(t, checker, ctx)),
2487
+ minItems: elementTypes.length,
2488
+ maxItems: elementTypes.length
2489
+ };
2490
+ } finally {
2491
+ ctx.inTupleElement = prevInTupleElement;
2418
2492
  }
2419
- return schema2;
2420
2493
  });
2421
2494
  }
2422
- const schema = {
2423
- $ref: `#/types/${name}`,
2424
- typeArguments: typeArgs.map((t) => buildSchema(t, checker, ctx))
2495
+ return {
2496
+ type: "array",
2497
+ prefixedItems: elementTypes.map((t) => buildSchema(t, checker, ctx)),
2498
+ minItems: elementTypes.length,
2499
+ maxItems: elementTypes.length
2425
2500
  };
2426
- if (packageOrigin) {
2427
- setSchemaExtension(schema, "x-ts-package", packageOrigin);
2428
- }
2429
- return schema;
2430
- }
2431
- }
2432
- const aliasTypeArgs = type.aliasTypeArguments;
2433
- const aliasSymbol = type.aliasSymbol;
2434
- if (aliasSymbol && aliasTypeArgs && aliasTypeArgs.length > 0) {
2435
- const name = aliasSymbol.getName();
2436
- if (BUILTIN_TYPES.has(name)) {
2437
- return { $ref: `#/types/${name}` };
2438
2501
  }
2439
- if (isBuiltinGeneric(name) || !name.startsWith("__")) {
2440
- const packageOrigin = getTypeOrigin(type, checker);
2441
- if (ctx) {
2442
- return withDepth(ctx, () => {
2443
- const schema2 = {
2444
- $ref: `#/types/${name}`,
2445
- typeArguments: aliasTypeArgs.map((t) => buildSchema(t, checker, ctx))
2446
- };
2447
- if (packageOrigin) {
2448
- setSchemaExtension(schema2, "x-ts-package", packageOrigin);
2449
- }
2450
- return schema2;
2451
- });
2502
+ const typeRef = type;
2503
+ const typeArgs = typeRef.target ? checker.getTypeArguments(typeRef) : undefined;
2504
+ if (typeRef.target && typeArgs && typeArgs.length > 0) {
2505
+ const symbol2 = typeRef.target.getSymbol();
2506
+ const name = symbol2?.getName();
2507
+ if (name && BUILTIN_TYPES.has(name)) {
2508
+ return { $ref: `#/types/${name}` };
2452
2509
  }
2453
- const schema = {
2454
- $ref: `#/types/${name}`,
2455
- typeArguments: aliasTypeArgs.map((t) => buildSchema(t, checker, ctx))
2456
- };
2457
- if (packageOrigin) {
2458
- setSchemaExtension(schema, "x-ts-package", packageOrigin);
2510
+ if (name && (isBuiltinGeneric(name) || !isAnonymous(typeRef.target))) {
2511
+ const packageOrigin = getTypeOrigin(typeRef.target, checker);
2512
+ if (ctx) {
2513
+ return withDepth(ctx, () => {
2514
+ const schema2 = {
2515
+ $ref: `#/types/${name}`,
2516
+ typeArguments: typeArgs.map((t) => buildSchema(t, checker, ctx))
2517
+ };
2518
+ if (packageOrigin) {
2519
+ setSchemaExtension(schema2, "x-ts-package", packageOrigin);
2520
+ }
2521
+ return schema2;
2522
+ });
2523
+ }
2524
+ const schema = {
2525
+ $ref: `#/types/${name}`,
2526
+ typeArguments: typeArgs.map((t) => buildSchema(t, checker, ctx))
2527
+ };
2528
+ if (packageOrigin) {
2529
+ setSchemaExtension(schema, "x-ts-package", packageOrigin);
2530
+ }
2531
+ return schema;
2459
2532
  }
2460
- return schema;
2461
2533
  }
2462
- }
2463
- if (type.flags & ts3.TypeFlags.Object) {
2464
- const callSignatures = type.getCallSignatures();
2465
- if (callSignatures.length > 0) {
2466
- return buildFunctionSchema(callSignatures, checker, ctx);
2534
+ const aliasTypeArgs = type.aliasTypeArguments;
2535
+ const aliasSymbol = type.aliasSymbol;
2536
+ if (aliasSymbol && aliasTypeArgs && aliasTypeArgs.length > 0) {
2537
+ const name = aliasSymbol.getName();
2538
+ if (BUILTIN_TYPES.has(name)) {
2539
+ return { $ref: `#/types/${name}` };
2540
+ }
2541
+ if (isBuiltinGeneric(name) || !name.startsWith("__")) {
2542
+ const packageOrigin = getTypeOrigin(type, checker);
2543
+ if (ctx) {
2544
+ return withDepth(ctx, () => {
2545
+ const schema2 = {
2546
+ $ref: `#/types/${name}`,
2547
+ typeArguments: aliasTypeArgs.map((t) => buildSchema(t, checker, ctx))
2548
+ };
2549
+ if (packageOrigin) {
2550
+ setSchemaExtension(schema2, "x-ts-package", packageOrigin);
2551
+ }
2552
+ return schema2;
2553
+ });
2554
+ }
2555
+ const schema = {
2556
+ $ref: `#/types/${name}`,
2557
+ typeArguments: aliasTypeArgs.map((t) => buildSchema(t, checker, ctx))
2558
+ };
2559
+ if (packageOrigin) {
2560
+ setSchemaExtension(schema, "x-ts-package", packageOrigin);
2561
+ }
2562
+ return schema;
2563
+ }
2467
2564
  }
2468
- }
2469
- if (symbol && !isAnonymous(type)) {
2470
- const name = symbol.getName();
2471
- if (isPrimitiveName(name)) {
2472
- return { type: name };
2565
+ if (type.flags & ts3.TypeFlags.Object) {
2566
+ const callSignatures = type.getCallSignatures();
2567
+ if (callSignatures.length > 0) {
2568
+ return buildFunctionSchema(callSignatures, checker, ctx);
2569
+ }
2473
2570
  }
2474
- if (BUILTIN_TYPES.has(name)) {
2475
- return { $ref: `#/types/${name}` };
2571
+ if (symbol && !isAnonymous(type)) {
2572
+ const name = symbol.getName();
2573
+ if (isPrimitiveName(name)) {
2574
+ return { type: name };
2575
+ }
2576
+ if (BUILTIN_TYPES.has(name)) {
2577
+ return { $ref: `#/types/${name}` };
2578
+ }
2579
+ if (!name.startsWith("__")) {
2580
+ const packageOrigin = getTypeOrigin(type, checker);
2581
+ const schema = { $ref: `#/types/${name}` };
2582
+ if (packageOrigin) {
2583
+ setSchemaExtension(schema, "x-ts-package", packageOrigin);
2584
+ }
2585
+ return schema;
2586
+ }
2476
2587
  }
2477
- if (!name.startsWith("__")) {
2478
- const packageOrigin = getTypeOrigin(type, checker);
2479
- const schema = { $ref: `#/types/${name}` };
2480
- if (packageOrigin) {
2481
- setSchemaExtension(schema, "x-ts-package", packageOrigin);
2588
+ if (type.flags & ts3.TypeFlags.Object) {
2589
+ const objectType = type;
2590
+ const properties = type.getProperties();
2591
+ if (properties.length > 0 || objectType.objectFlags & ts3.ObjectFlags.Anonymous) {
2592
+ return buildObjectSchema(properties, checker, ctx, type);
2482
2593
  }
2483
- return schema;
2484
2594
  }
2485
- }
2486
- if (type.flags & ts3.TypeFlags.Object) {
2487
- const objectType = type;
2488
- const properties = type.getProperties();
2489
- if (properties.length > 0 || objectType.objectFlags & ts3.ObjectFlags.Anonymous) {
2490
- return buildObjectSchema(properties, checker, ctx, type);
2595
+ return { type: checker.typeToString(type) };
2596
+ } finally {
2597
+ if (addedToVisited) {
2598
+ ctx.visitedTypes.delete(type);
2491
2599
  }
2492
2600
  }
2493
- return { type: checker.typeToString(type) };
2494
2601
  }
2495
2602
  function buildFunctionSchema(callSignatures, checker, ctx) {
2496
2603
  const buildSignatures = () => {
@@ -2523,6 +2630,7 @@ function buildFunctionSchema(callSignatures, checker, ctx) {
2523
2630
  return { type: "function", signatures: buildSignatures() };
2524
2631
  }
2525
2632
  function buildObjectSchema(properties, checker, ctx, originalType) {
2633
+ const isArrayLikeType = originalType ? checker.isArrayType(originalType) || checker.isTupleType(originalType) || originalType.symbol?.getName() === "Array" && isBuiltinSymbol(originalType.symbol) : false;
2526
2634
  const buildProps = () => {
2527
2635
  const props = {};
2528
2636
  const required = [];
@@ -2530,7 +2638,7 @@ function buildObjectSchema(properties, checker, ctx, originalType) {
2530
2638
  const propName = prop.getName();
2531
2639
  if (propName.startsWith("_"))
2532
2640
  continue;
2533
- if (ARRAY_PROTOTYPE_METHODS.has(propName)) {
2641
+ if (isArrayLikeType && ARRAY_PROTOTYPE_METHODS.has(propName)) {
2534
2642
  continue;
2535
2643
  }
2536
2644
  const propType = checker.getTypeOfSymbol(prop);
@@ -2801,11 +2909,11 @@ function extractDefaultValue(initializer) {
2801
2909
  function registerReferencedTypes(type, ctx, depth = 0) {
2802
2910
  if (depth > ctx.maxTypeDepth)
2803
2911
  return;
2804
- if (ctx.visitedTypes.has(type))
2912
+ if (ctx.registeredTypes.has(type))
2805
2913
  return;
2806
2914
  const isPrimitive = type.flags & (ts4.TypeFlags.String | ts4.TypeFlags.Number | ts4.TypeFlags.Boolean | ts4.TypeFlags.Void | ts4.TypeFlags.Undefined | ts4.TypeFlags.Null | ts4.TypeFlags.Any | ts4.TypeFlags.Unknown | ts4.TypeFlags.Never | ts4.TypeFlags.StringLiteral | ts4.TypeFlags.NumberLiteral | ts4.TypeFlags.BooleanLiteral);
2807
2915
  if (!isPrimitive) {
2808
- ctx.visitedTypes.add(type);
2916
+ ctx.registeredTypes.add(type);
2809
2917
  }
2810
2918
  const { typeChecker: checker, typeRegistry } = ctx;
2811
2919
  typeRegistry.registerType(type, ctx);
@@ -2912,8 +3020,6 @@ function isGenericTypeParameter(name) {
2912
3020
  return true;
2913
3021
  if (/^T[A-Z]/.test(name))
2914
3022
  return true;
2915
- if (["Key", "Value", "Item", "Element"].includes(name))
2916
- return true;
2917
3023
  return false;
2918
3024
  }
2919
3025
  function isExternalType(decl) {
@@ -2939,7 +3045,7 @@ class TypeRegistry {
2939
3045
  return Array.from(this.types.values());
2940
3046
  }
2941
3047
  registerType(type, ctx) {
2942
- const symbol = type.getSymbol() || type.aliasSymbol;
3048
+ const symbol = type.aliasSymbol || type.getSymbol();
2943
3049
  if (!symbol)
2944
3050
  return;
2945
3051
  const name = symbol.getName();
@@ -2994,7 +3100,7 @@ class TypeRegistry {
2994
3100
  }
2995
3101
  let schema = buildSchema(type, checker, ctx);
2996
3102
  if (this.isSelfRef(schema, name)) {
2997
- schema = this.buildObjectSchemaFromType(type, checker, ctx);
3103
+ schema = this.resolveSelRefSchema(type, checker, ctx);
2998
3104
  }
2999
3105
  return {
3000
3106
  id: name,
@@ -3010,7 +3116,56 @@ class TypeRegistry {
3010
3116
  const obj = schema;
3011
3117
  return obj.$ref === `#/types/${typeName}`;
3012
3118
  }
3013
- buildObjectSchemaFromType(type, checker, ctx) {
3119
+ resolveSelRefSchema(type, checker, ctx) {
3120
+ if (type.isUnion()) {
3121
+ const types = type.types;
3122
+ const allStringLiterals = types.every((t) => t.flags & ts5.TypeFlags.StringLiteral);
3123
+ if (allStringLiterals) {
3124
+ return {
3125
+ type: "string",
3126
+ enum: types.map((t) => t.value)
3127
+ };
3128
+ }
3129
+ const allNumberLiterals = types.every((t) => t.flags & ts5.TypeFlags.NumberLiteral);
3130
+ if (allNumberLiterals) {
3131
+ return {
3132
+ type: "number",
3133
+ enum: types.map((t) => t.value)
3134
+ };
3135
+ }
3136
+ return {
3137
+ anyOf: types.map((t) => buildSchema(t, checker, ctx))
3138
+ };
3139
+ }
3140
+ const symbol = type.getSymbol() ?? type.aliasSymbol;
3141
+ if (symbol) {
3142
+ const decl = symbol.declarations?.find(ts5.isEnumDeclaration);
3143
+ if (decl) {
3144
+ const members = [];
3145
+ for (const member of decl.members) {
3146
+ const memberSymbol = checker.getSymbolAtLocation(member.name);
3147
+ if (memberSymbol) {
3148
+ const constantValue = checker.getConstantValue(member);
3149
+ if (constantValue !== undefined) {
3150
+ members.push({
3151
+ name: memberSymbol.getName(),
3152
+ value: constantValue
3153
+ });
3154
+ }
3155
+ }
3156
+ }
3157
+ if (members.length > 0) {
3158
+ return {
3159
+ type: typeof members[0].value === "string" ? "string" : "number",
3160
+ enum: members.map((m) => m.value),
3161
+ "x-enum-members": members
3162
+ };
3163
+ }
3164
+ }
3165
+ }
3166
+ return this.buildObjectSchemaFromProperties(type, checker, ctx);
3167
+ }
3168
+ buildObjectSchemaFromProperties(type, checker, ctx) {
3014
3169
  const properties = type.getProperties();
3015
3170
  if (properties.length === 0) {
3016
3171
  return { type: checker.typeToString(type) };
@@ -3022,11 +3177,18 @@ class TypeRegistry {
3022
3177
  const typeName = type.getSymbol()?.getName() ?? "anonymous";
3023
3178
  ctx.onTruncation(typeName, properties.length, limit);
3024
3179
  }
3180
+ const isArrayLike = checker.isArrayType(type) || checker.isTupleType(type) || type.symbol?.getName() === "Array" && type.symbol?.getDeclarations()?.[0]?.getSourceFile()?.fileName?.includes("/typescript/lib/lib.");
3181
+ const isStringLike = type.flags & ts5.TypeFlags.StringLike;
3182
+ const isNumberLike = type.flags & ts5.TypeFlags.NumberLike;
3025
3183
  for (const prop of properties.slice(0, limit)) {
3026
3184
  const propName = prop.getName();
3027
3185
  if (propName.startsWith("_"))
3028
3186
  continue;
3029
- if (ARRAY_PROTOTYPE_METHODS.has(propName))
3187
+ if (isArrayLike && ARRAY_PROTOTYPE_METHODS.has(propName))
3188
+ continue;
3189
+ if (isStringLike && STRING_PROTOTYPE_METHODS.has(propName))
3190
+ continue;
3191
+ if (isNumberLike && NUMBER_PROTOTYPE_METHODS.has(propName))
3030
3192
  continue;
3031
3193
  const propType = checker.getTypeOfSymbol(prop);
3032
3194
  this.registerType(propType, ctx);
@@ -3049,15 +3211,16 @@ function createContext(program, sourceFile, options = {}) {
3049
3211
  typeChecker: program.getTypeChecker(),
3050
3212
  program,
3051
3213
  sourceFile,
3052
- maxTypeDepth: options.maxTypeDepth ?? 4,
3214
+ maxTypeDepth: options.maxTypeDepth ?? 5,
3053
3215
  maxExternalTypeDepth: options.maxExternalTypeDepth ?? 2,
3054
3216
  currentDepth: 0,
3055
3217
  resolveExternalTypes: options.resolveExternalTypes ?? true,
3056
3218
  typeRegistry: new TypeRegistry,
3057
3219
  exportedIds: new Set,
3058
3220
  visitedTypes: new Set,
3221
+ registeredTypes: new Set,
3059
3222
  includePrivate: options.includePrivate ?? false,
3060
- maxProperties: options.maxProperties ?? 20,
3223
+ maxProperties: options.maxProperties ?? 100,
3061
3224
  onTruncation: options.onTruncation
3062
3225
  };
3063
3226
  }
@@ -3354,6 +3517,8 @@ function serializeProperty(node, ctx) {
3354
3517
  flags.readonly = true;
3355
3518
  if (node.questionToken)
3356
3519
  flags.optional = true;
3520
+ const symbol = checker.getSymbolAtLocation(node.name ?? node);
3521
+ const { deprecated, reason: deprecationReason } = isSymbolDeprecated(symbol);
3357
3522
  return {
3358
3523
  name,
3359
3524
  kind: "property",
@@ -3361,7 +3526,8 @@ function serializeProperty(node, ctx) {
3361
3526
  tags: tags.length > 0 ? tags : undefined,
3362
3527
  visibility,
3363
3528
  schema,
3364
- flags: Object.keys(flags).length > 0 ? flags : undefined
3529
+ flags: Object.keys(flags).length > 0 ? flags : undefined,
3530
+ ...deprecated ? { deprecated: true, deprecationReason } : {}
3365
3531
  };
3366
3532
  }
3367
3533
  function serializeMethod(node, ctx) {
@@ -3389,6 +3555,8 @@ function serializeMethod(node, ctx) {
3389
3555
  if (modifiers?.some((m) => m.kind === ts7.SyntaxKind.AbstractKeyword)) {
3390
3556
  flags.abstract = true;
3391
3557
  }
3558
+ const symbol = checker.getSymbolAtLocation(node.name ?? node);
3559
+ const { deprecated, reason: deprecationReason } = isSymbolDeprecated(symbol);
3392
3560
  return {
3393
3561
  name,
3394
3562
  kind: "method",
@@ -3396,7 +3564,8 @@ function serializeMethod(node, ctx) {
3396
3564
  tags: tags.length > 0 ? tags : undefined,
3397
3565
  visibility,
3398
3566
  signatures: signatures.length > 0 ? signatures : undefined,
3399
- flags: Object.keys(flags).length > 0 ? flags : undefined
3567
+ flags: Object.keys(flags).length > 0 ? flags : undefined,
3568
+ ...deprecated ? { deprecated: true, deprecationReason } : {}
3400
3569
  };
3401
3570
  }
3402
3571
  function serializeConstructor(node, ctx) {
@@ -3582,6 +3751,14 @@ function serializeFunctionExport(node, ctx, nameOverride) {
3582
3751
  ...callSignatures.length > 1 ? { overloadIndex: index } : {}
3583
3752
  };
3584
3753
  });
3754
+ const flags = {};
3755
+ const modifiers = ts8.getModifiers(node);
3756
+ if (modifiers?.some((m) => m.kind === ts8.SyntaxKind.AsyncKeyword)) {
3757
+ flags.async = true;
3758
+ }
3759
+ if (node.asteriskToken) {
3760
+ flags.generator = true;
3761
+ }
3585
3762
  return {
3586
3763
  id: name,
3587
3764
  name,
@@ -3591,6 +3768,7 @@ function serializeFunctionExport(node, ctx, nameOverride) {
3591
3768
  source,
3592
3769
  typeParameters,
3593
3770
  signatures,
3771
+ ...Object.keys(flags).length > 0 ? { flags } : {},
3594
3772
  ...deprecated ? { deprecated: true, deprecationReason } : {},
3595
3773
  ...examples.length > 0 ? { examples } : {}
3596
3774
  };
@@ -3698,13 +3876,16 @@ function serializePropertySignature(node, ctx) {
3698
3876
  if (node.modifiers?.some((m) => m.kind === ts9.SyntaxKind.ReadonlyKeyword)) {
3699
3877
  flags.readonly = true;
3700
3878
  }
3879
+ const symbol = checker.getSymbolAtLocation(node.name);
3880
+ const { deprecated, reason: deprecationReason } = isSymbolDeprecated(symbol);
3701
3881
  return {
3702
3882
  name,
3703
3883
  kind: "property",
3704
3884
  description,
3705
3885
  tags: tags.length > 0 ? tags : undefined,
3706
3886
  schema,
3707
- flags: Object.keys(flags).length > 0 ? flags : undefined
3887
+ flags: Object.keys(flags).length > 0 ? flags : undefined,
3888
+ ...deprecated ? { deprecated: true, deprecationReason } : {}
3708
3889
  };
3709
3890
  }
3710
3891
  function serializeMethodSignature(node, ctx) {
@@ -3717,13 +3898,16 @@ function serializeMethodSignature(node, ctx) {
3717
3898
  const flags = {};
3718
3899
  if (node.questionToken)
3719
3900
  flags.optional = true;
3901
+ const symbol = checker.getSymbolAtLocation(node.name);
3902
+ const { deprecated, reason: deprecationReason } = isSymbolDeprecated(symbol);
3720
3903
  return {
3721
3904
  name,
3722
3905
  kind: "method",
3723
3906
  description,
3724
3907
  tags: tags.length > 0 ? tags : undefined,
3725
3908
  signatures: signatures.length > 0 ? signatures : undefined,
3726
- flags: Object.keys(flags).length > 0 ? flags : undefined
3909
+ flags: Object.keys(flags).length > 0 ? flags : undefined,
3910
+ ...deprecated ? { deprecated: true, deprecationReason } : {}
3727
3911
  };
3728
3912
  }
3729
3913
  function serializeCallSignature(node, ctx) {
@@ -4463,12 +4647,12 @@ async function getExport(options) {
4463
4647
  const result = createProgram({ entryFile, baseDir, content });
4464
4648
  const { program, sourceFile } = result;
4465
4649
  if (!sourceFile) {
4466
- return { export: null, types: [], errors: [`Could not load source file: ${entryFile}`] };
4650
+ return { export: null, types: [], errors: [`Entry file not found: ${entryFile}. Specify with: drift get src/index.ts <name>`] };
4467
4651
  }
4468
4652
  const checker = program.getTypeChecker();
4469
4653
  const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
4470
4654
  if (!moduleSymbol) {
4471
- return { export: null, types: [], errors: ["Could not get module symbol"] };
4655
+ return { export: null, types: [], errors: [`No exports found in ${entryFile}. Is this the right entry point?`] };
4472
4656
  }
4473
4657
  const exportedSymbols = checker.getExportsOfModule(moduleSymbol);
4474
4658
  const targetSymbol = exportedSymbols.find((s) => s.getName() === exportName);
@@ -4482,12 +4666,39 @@ async function getExport(options) {
4482
4666
  const ctx = createContext(program, sourceFile, { maxTypeDepth });
4483
4667
  ctx.exportedIds = exportedIds;
4484
4668
  try {
4669
+ const originalDecls = targetSymbol.declarations ?? [];
4670
+ const isNamespaceExportDecl = originalDecls.some((d) => ts11.isNamespaceExport(d) || ts11.isNamespaceImport(d));
4671
+ if (isNamespaceExportDecl) {
4672
+ const spec2 = serializeNamespaceForGet(targetSymbol, exportName, ctx);
4673
+ const types2 = ctx.typeRegistry.getAll().map((t) => normalizeType(t, { dialect: "draft-2020-12" }));
4674
+ return { export: normalizeExport(spec2, { dialect: "draft-2020-12" }), types: types2, errors };
4675
+ }
4485
4676
  const { declaration, resolvedSymbol, isTypeOnly } = resolveExportTarget(targetSymbol, checker);
4486
4677
  if (!declaration) {
4678
+ const externalPackage = detectExternalPackage(targetSymbol, checker);
4679
+ if (externalPackage) {
4680
+ const stub = {
4681
+ id: exportName,
4682
+ name: exportName,
4683
+ kind: "external",
4684
+ source: { package: externalPackage }
4685
+ };
4686
+ return { export: stub, types: [], errors };
4687
+ }
4487
4688
  return { export: null, types: [], errors: [`No declaration found for '${exportName}'`] };
4488
4689
  }
4489
4690
  let spec = serializeDeclaration(declaration, targetSymbol, resolvedSymbol, exportName, ctx, isTypeOnly);
4490
4691
  if (!spec) {
4692
+ const externalPackage = detectExternalPackage(targetSymbol, checker);
4693
+ if (externalPackage) {
4694
+ const stub = {
4695
+ id: exportName,
4696
+ name: exportName,
4697
+ kind: "external",
4698
+ source: { package: externalPackage }
4699
+ };
4700
+ return { export: stub, types: [], errors };
4701
+ }
4491
4702
  return { export: null, types: [], errors: [`Could not serialize '${exportName}'`] };
4492
4703
  }
4493
4704
  spec = normalizeExport(spec, { dialect: "draft-2020-12" });
@@ -4537,17 +4748,27 @@ function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportN
4537
4748
  } else if (ts11.isVariableDeclaration(declaration)) {
4538
4749
  const varStatement = declaration.parent?.parent;
4539
4750
  if (varStatement && ts11.isVariableStatement(varStatement)) {
4540
- if (declaration.initializer && ts11.isArrowFunction(declaration.initializer)) {
4751
+ if (declaration.initializer && (ts11.isArrowFunction(declaration.initializer) || ts11.isFunctionExpression(declaration.initializer))) {
4541
4752
  const varName = ts11.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
4542
4753
  result = serializeFunctionExport(declaration.initializer, ctx, varName);
4543
4754
  } else {
4544
- result = serializeVariable(declaration, varStatement, ctx);
4755
+ const checker = ctx.program.getTypeChecker();
4756
+ const varType = checker.getTypeAtLocation(declaration);
4757
+ if (varType.getCallSignatures().length > 0) {
4758
+ result = serializeVariable(declaration, varStatement, ctx);
4759
+ if (result)
4760
+ result = { ...result, kind: "function" };
4761
+ } else {
4762
+ result = serializeVariable(declaration, varStatement, ctx);
4763
+ }
4545
4764
  }
4546
4765
  }
4766
+ } else if (ts11.isNamespaceExport(declaration) || ts11.isModuleDeclaration(declaration) || ts11.isNamespaceImport(declaration) || ts11.isSourceFile(declaration)) {
4767
+ result = serializeNamespaceForGet(_exportSymbol, exportName, ctx);
4547
4768
  }
4548
4769
  if (result) {
4549
4770
  if (result.name !== exportName) {
4550
- result = { ...result, id: exportName, name: result.name };
4771
+ result = { ...result, id: exportName, name: exportName };
4551
4772
  }
4552
4773
  if (isTypeOnly) {
4553
4774
  result = { ...result, flags: { ...result.flags ?? {}, typeOnly: true } };
@@ -4555,6 +4776,65 @@ function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportN
4555
4776
  }
4556
4777
  return result;
4557
4778
  }
4779
+ function serializeNamespaceForGet(symbol, exportName, ctx) {
4780
+ const checker = ctx.program.getTypeChecker();
4781
+ let targetSymbol = symbol;
4782
+ if (symbol.flags & ts11.SymbolFlags.Alias) {
4783
+ const aliased = checker.getAliasedSymbol(symbol);
4784
+ if (aliased && aliased !== symbol) {
4785
+ targetSymbol = aliased;
4786
+ }
4787
+ }
4788
+ const members = [];
4789
+ try {
4790
+ const nsExports = checker.getExportsOfModule(targetSymbol);
4791
+ for (const memberSymbol of nsExports) {
4792
+ const memberName = memberSymbol.getName();
4793
+ const memberDecls = memberSymbol.declarations ?? [];
4794
+ const memberDecl = memberSymbol.valueDeclaration || memberDecls[0];
4795
+ if (memberDecl) {
4796
+ const type = checker.getTypeAtLocation(memberDecl);
4797
+ const kind = getExportKind(memberDecl, type);
4798
+ members.push({ name: memberName, kind });
4799
+ }
4800
+ }
4801
+ } catch {}
4802
+ return {
4803
+ id: exportName,
4804
+ name: exportName,
4805
+ kind: "namespace",
4806
+ tags: [],
4807
+ ...members.length > 0 ? { members } : {}
4808
+ };
4809
+ }
4810
+ function detectExternalPackage(symbol, checker) {
4811
+ let targetSymbol = symbol;
4812
+ if (symbol.flags & ts11.SymbolFlags.Alias) {
4813
+ const aliased = checker.getAliasedSymbol(symbol);
4814
+ if (aliased && aliased !== symbol) {
4815
+ targetSymbol = aliased;
4816
+ }
4817
+ }
4818
+ const allDecls = [...targetSymbol.declarations ?? [], ...symbol.declarations ?? []];
4819
+ for (const decl of allDecls) {
4820
+ const sf = decl.getSourceFile();
4821
+ if (sf?.fileName.includes("node_modules")) {
4822
+ const match = sf.fileName.match(/node_modules\/(@[^/]+\/[^/]+|[^/]+)/);
4823
+ if (match)
4824
+ return match[1];
4825
+ }
4826
+ if (ts11.isExportSpecifier(decl)) {
4827
+ const exportDecl = decl.parent?.parent;
4828
+ if (exportDecl && ts11.isExportDeclaration(exportDecl) && exportDecl.moduleSpecifier) {
4829
+ const moduleText = exportDecl.moduleSpecifier.text;
4830
+ if (!moduleText.startsWith(".") && !moduleText.startsWith("/")) {
4831
+ return moduleText;
4832
+ }
4833
+ }
4834
+ }
4835
+ }
4836
+ return;
4837
+ }
4558
4838
  // src/primitives/list.ts
4559
4839
  import * as path4 from "node:path";
4560
4840
  import ts12 from "typescript";
@@ -4565,12 +4845,12 @@ async function listExports(options) {
4565
4845
  const result = createProgram({ entryFile, baseDir, content });
4566
4846
  const { program, sourceFile } = result;
4567
4847
  if (!sourceFile) {
4568
- return { exports: [], errors: [`Could not load source file: ${entryFile}`] };
4848
+ return { exports: [], errors: [`Entry file not found: ${entryFile}. Specify with: drift list src/index.ts`] };
4569
4849
  }
4570
4850
  const checker = program.getTypeChecker();
4571
4851
  const moduleSymbol = checker.getSymbolAtLocation(sourceFile);
4572
4852
  if (!moduleSymbol) {
4573
- return { exports: [], errors: ["Could not get module symbol"] };
4853
+ return { exports: [], errors: [`No exports found in ${entryFile}. Is this the right entry point?`] };
4574
4854
  }
4575
4855
  const exportedSymbols = checker.getExportsOfModule(moduleSymbol);
4576
4856
  for (const symbol of exportedSymbols) {
@@ -4598,8 +4878,15 @@ function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
4598
4878
  }
4599
4879
  const declarations = targetSymbol.declarations ?? [];
4600
4880
  const declaration = targetSymbol.valueDeclaration || declarations.find((d) => d.kind !== ts12.SyntaxKind.ExportSpecifier) || declarations[0];
4601
- if (!declaration)
4602
- return null;
4881
+ if (!declaration) {
4882
+ return {
4883
+ name,
4884
+ kind: "external",
4885
+ file: "<external>",
4886
+ line: 0,
4887
+ reexport: true
4888
+ };
4889
+ }
4603
4890
  if (ts12.isSourceFile(declaration)) {
4604
4891
  return {
4605
4892
  name,
@@ -5769,7 +6056,7 @@ async function extract(options) {
5769
6056
  if (!sourceFile) {
5770
6057
  return {
5771
6058
  spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
5772
- diagnostics: [{ message: `Could not load source file: ${entryFile}`, severity: "error" }]
6059
+ diagnostics: [{ message: `Entry file not found: ${entryFile}. Specify with: drift list src/index.ts`, severity: "error" }]
5773
6060
  };
5774
6061
  }
5775
6062
  const typeChecker = program.getTypeChecker();
@@ -5777,7 +6064,7 @@ async function extract(options) {
5777
6064
  if (!moduleSymbol) {
5778
6065
  return {
5779
6066
  spec: createEmptySpec(entryFile, includeSchema, isDtsSource),
5780
- diagnostics: [{ message: "Could not get module symbol", severity: "warning" }]
6067
+ diagnostics: [{ message: `No exports found in ${entryFile}. Is this the right entry point?`, severity: "warning" }]
5781
6068
  };
5782
6069
  }
5783
6070
  const exportedSymbols = typeChecker.getExportsOfModule(moduleSymbol);
@@ -5896,6 +6183,41 @@ async function extract(options) {
5896
6183
  }
5897
6184
  const verification = buildVerificationSummary(exportedSymbols.length, exports.length, exportTracker);
5898
6185
  const meta = await getPackageMeta(entryFile, baseDir);
6186
+ {
6187
+ const symFlags = ts16.SymbolFlags.Type | ts16.SymbolFlags.Interface | ts16.SymbolFlags.Class;
6188
+ const maxPasses = 5;
6189
+ for (let pass = 0;pass < maxPasses; pass++) {
6190
+ const allRefs = new Map;
6191
+ for (const exp of exports) {
6192
+ collectAllRefsWithContext(exp, allRefs, {
6193
+ exportName: exp.id || exp.name,
6194
+ location: "property",
6195
+ path: []
6196
+ });
6197
+ }
6198
+ for (const t of ctx.typeRegistry.getAll()) {
6199
+ collectAllRefsWithContext(t, allRefs, {
6200
+ exportName: t.id,
6201
+ location: "property",
6202
+ path: []
6203
+ });
6204
+ }
6205
+ let added = 0;
6206
+ for (const [typeName] of allRefs) {
6207
+ if (ctx.typeRegistry.has(typeName))
6208
+ continue;
6209
+ if (BUILTIN_TYPES2.has(typeName))
6210
+ continue;
6211
+ const tsType = findTypeInProgram(typeName, typeChecker, program, sourceFile, symFlags);
6212
+ if (tsType) {
6213
+ ctx.typeRegistry.registerType(tsType, ctx);
6214
+ added++;
6215
+ }
6216
+ }
6217
+ if (added === 0)
6218
+ break;
6219
+ }
6220
+ }
5899
6221
  const types = ctx.typeRegistry.getAll();
5900
6222
  const projectBaseDir = baseDir ?? path8.dirname(entryFile);
5901
6223
  const definedTypes = new Set(types.map((t) => t.id));
@@ -6022,11 +6344,17 @@ function serializeDeclaration2(declaration, exportSymbol, exportName, ctx, isTyp
6022
6344
  } else if (ts16.isVariableDeclaration(declaration)) {
6023
6345
  const varStatement = declaration.parent?.parent;
6024
6346
  if (varStatement && ts16.isVariableStatement(varStatement)) {
6025
- if (declaration.initializer && ts16.isArrowFunction(declaration.initializer)) {
6347
+ if (declaration.initializer && (ts16.isArrowFunction(declaration.initializer) || ts16.isFunctionExpression(declaration.initializer))) {
6026
6348
  const varName = ts16.isIdentifier(declaration.name) ? declaration.name.text : declaration.name.getText();
6027
6349
  result = serializeFunctionExport(declaration.initializer, ctx, varName);
6028
6350
  } else {
6029
6351
  result = serializeVariable(declaration, varStatement, ctx);
6352
+ if (result?.kind === "variable") {
6353
+ const type = ctx.typeChecker.getTypeAtLocation(declaration);
6354
+ if (type.getConstructSignatures().length > 0) {
6355
+ result = { ...result, kind: "class" };
6356
+ }
6357
+ }
6030
6358
  }
6031
6359
  }
6032
6360
  } else if (ts16.isNamespaceExport(declaration) || ts16.isModuleDeclaration(declaration) || ts16.isNamespaceImport(declaration) || ts16.isSourceFile(declaration)) {
@@ -6051,6 +6379,12 @@ function serializeDeclaration2(declaration, exportSymbol, exportName, ctx, isTyp
6051
6379
  flags: { ...result.flags ?? {}, typeOnly: true }
6052
6380
  };
6053
6381
  }
6382
+ if (!result.deprecated) {
6383
+ const { deprecated, reason: deprecationReason } = isSymbolDeprecated(exportSymbol);
6384
+ if (deprecated) {
6385
+ result = { ...result, deprecated: true, deprecationReason };
6386
+ }
6387
+ }
6054
6388
  }
6055
6389
  return result;
6056
6390
  }
@@ -6098,7 +6432,7 @@ function serializeNamespaceMember(symbol, memberName, ctx) {
6098
6432
  return null;
6099
6433
  const type = checker.getTypeAtLocation(declaration);
6100
6434
  const callSignatures = type.getCallSignatures();
6101
- const deprecated = isSymbolDeprecated(targetSymbol);
6435
+ const { deprecated } = isSymbolDeprecated(targetSymbol);
6102
6436
  let kind = "variable";
6103
6437
  if (ts16.isFunctionDeclaration(declaration) || ts16.isFunctionExpression(declaration)) {
6104
6438
  kind = "function";
@@ -6219,20 +6553,42 @@ function createEmptySpec(entryFile, includeSchema, isDtsSource) {
6219
6553
  }
6220
6554
  };
6221
6555
  }
6556
+ function findTypeInProgram(name, checker, program, sourceFile, symFlags) {
6557
+ const localSym = checker.resolveName(name, sourceFile, symFlags, false);
6558
+ if (localSym)
6559
+ return checker.getDeclaredTypeOfSymbol(localSym);
6560
+ const entryDir = path8.dirname(sourceFile.fileName);
6561
+ for (const sf of program.getSourceFiles()) {
6562
+ const fn = sf.fileName;
6563
+ if (fn.includes("/typescript/lib/lib.") || fn.includes("\\typescript\\lib\\lib."))
6564
+ continue;
6565
+ if (fn.includes("/@types/node/") || fn.includes("\\@types\\node\\"))
6566
+ continue;
6567
+ if (fn.startsWith(entryDir))
6568
+ continue;
6569
+ const sym = checker.resolveName(name, sf, symFlags, false);
6570
+ if (sym)
6571
+ return checker.getDeclaredTypeOfSymbol(sym);
6572
+ }
6573
+ return;
6574
+ }
6222
6575
  async function getPackageMeta(entryFile, baseDir) {
6223
- const searchDir = baseDir ?? path8.dirname(entryFile);
6224
- const pkgPath = path8.join(searchDir, "package.json");
6225
- try {
6226
- if (fs7.existsSync(pkgPath)) {
6227
- const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
6228
- return {
6229
- name: pkg.name ?? path8.basename(searchDir),
6230
- version: pkg.version,
6231
- description: pkg.description
6232
- };
6233
- }
6234
- } catch {}
6235
- return { name: path8.basename(searchDir) };
6576
+ let dir = baseDir ?? path8.dirname(entryFile);
6577
+ while (dir !== path8.dirname(dir)) {
6578
+ const pkgPath = path8.join(dir, "package.json");
6579
+ try {
6580
+ if (fs7.existsSync(pkgPath)) {
6581
+ const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
6582
+ return {
6583
+ name: pkg.name ?? path8.basename(dir),
6584
+ version: pkg.version,
6585
+ description: pkg.description
6586
+ };
6587
+ }
6588
+ } catch {}
6589
+ dir = path8.dirname(dir);
6590
+ }
6591
+ return { name: path8.basename(baseDir ?? path8.dirname(entryFile)) };
6236
6592
  }
6237
6593
 
6238
6594
  // src/primitives/spec.ts
@@ -6355,8 +6711,10 @@ export {
6355
6711
  arktypeAdapter,
6356
6712
  analyzeSpec,
6357
6713
  TypeRegistry,
6714
+ STRING_PROTOTYPE_METHODS,
6358
6715
  QueryBuilder,
6359
6716
  PRIMITIVES,
6717
+ NUMBER_PROTOTYPE_METHODS,
6360
6718
  CacheManager,
6361
6719
  CONFIG_FILENAME,
6362
6720
  BUILTIN_TYPE_SCHEMAS,