@openpkg-ts/sdk 0.33.0 → 0.34.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
@@ -1,3 +1,32 @@
1
+ import {
2
+ QueryBuilder,
3
+ analyzeSpec,
4
+ buildSignatureString,
5
+ findMissingParamDocs,
6
+ formatBadges,
7
+ formatConditionalType,
8
+ formatMappedType,
9
+ formatParameters,
10
+ formatReturnType,
11
+ formatSchema,
12
+ formatTypeParameters,
13
+ getDeprecationMessage,
14
+ getMemberBadges,
15
+ getMethods,
16
+ getProperties,
17
+ groupByVisibility,
18
+ hasDeprecatedTag,
19
+ isMethod,
20
+ isProperty,
21
+ query,
22
+ resolveTypeRef,
23
+ sortByName,
24
+ toAlgoliaRecords,
25
+ toPagefindRecords,
26
+ toSearchIndex,
27
+ toSearchIndexJSON
28
+ } from "./shared/chunk-91b592v7.js";
29
+
1
30
  // src/primitives/diff.ts
2
31
  import {
3
32
  calculateNextVersion,
@@ -42,313 +71,9 @@ function mergeConfig(fileConfig, cliOptions) {
42
71
  }
43
72
  };
44
73
  }
45
- // src/core/diagnostics.ts
46
- function hasDeprecatedTag(exp) {
47
- if (exp.deprecated === true)
48
- return true;
49
- return exp.tags?.some((t) => t.name === "deprecated" || t.name === "@deprecated") ?? false;
50
- }
51
- function getDeprecationMessage(exp) {
52
- const tag = exp.tags?.find((t) => t.name === "deprecated" || t.name === "@deprecated");
53
- if (tag?.text.trim()) {
54
- return tag.text.trim();
55
- }
56
- return;
57
- }
58
- function findMissingParamDocs(exp) {
59
- const missing = [];
60
- for (const sig of exp.signatures ?? []) {
61
- for (const param of sig.parameters ?? []) {
62
- if (!param.description?.trim()) {
63
- missing.push(param.name);
64
- }
65
- }
66
- }
67
- return missing;
68
- }
69
- function checkMemberDescriptions(exp, members) {
70
- const items = [];
71
- for (const member of members) {
72
- if (!member.description?.trim() && member.name) {
73
- items.push({
74
- exportId: exp.id,
75
- exportName: exp.name,
76
- issue: "member missing description",
77
- member: member.name
78
- });
79
- }
80
- }
81
- return items;
82
- }
83
- function analyzeSpec(spec) {
84
- const missingDescriptions = [];
85
- const deprecatedNoReason = [];
86
- const missingParamDocs = [];
87
- for (const exp of spec.exports) {
88
- if (!exp.description?.trim()) {
89
- missingDescriptions.push({
90
- exportId: exp.id,
91
- exportName: exp.name,
92
- issue: "missing description"
93
- });
94
- }
95
- if (exp.members) {
96
- missingDescriptions.push(...checkMemberDescriptions(exp, exp.members));
97
- }
98
- if (hasDeprecatedTag(exp) && !getDeprecationMessage(exp)) {
99
- deprecatedNoReason.push({
100
- exportId: exp.id,
101
- exportName: exp.name,
102
- issue: "deprecated without reason"
103
- });
104
- }
105
- const missingParams = findMissingParamDocs(exp);
106
- for (const param of missingParams) {
107
- missingParamDocs.push({
108
- exportId: exp.id,
109
- exportName: exp.name,
110
- issue: "param missing description",
111
- param
112
- });
113
- }
114
- }
115
- return {
116
- missingDescriptions,
117
- deprecatedNoReason,
118
- missingParamDocs
119
- };
120
- }
121
- // src/core/format.ts
122
- function getMemberBadges(member) {
123
- const badges = [];
124
- const visibility = member.visibility ?? "public";
125
- if (visibility !== "public") {
126
- badges.push(visibility);
127
- }
128
- const flags = member.flags;
129
- if (flags?.static)
130
- badges.push("static");
131
- if (flags?.readonly)
132
- badges.push("readonly");
133
- if (flags?.async)
134
- badges.push("async");
135
- if (flags?.abstract)
136
- badges.push("abstract");
137
- return badges;
138
- }
139
- function formatBadges(badges) {
140
- return badges.join(" ");
141
- }
142
74
  // src/core/loader.ts
143
75
  import * as fs2 from "node:fs";
144
76
 
145
- // src/core/query.ts
146
- function formatFunctionSchema(schema) {
147
- const sigs = schema["x-ts-signatures"];
148
- if (!sigs?.length)
149
- return "(...args: unknown[]) => unknown";
150
- const sig = sigs[0];
151
- const params = formatParameters(sig);
152
- const ret = sig.returns ? formatSchema(sig.returns.schema) : "void";
153
- return `${params} => ${ret}`;
154
- }
155
- function formatSchema(schema, options) {
156
- if (!schema)
157
- return "unknown";
158
- if (typeof schema === "string")
159
- return schema;
160
- const withPackage = (typeStr) => {
161
- if (options?.includePackage && typeof schema === "object" && "x-ts-package" in schema) {
162
- const pkg = schema["x-ts-package"];
163
- return `${typeStr} (from ${pkg})`;
164
- }
165
- return typeStr;
166
- };
167
- if (typeof schema === "object" && schema !== null) {
168
- if ("x-ts-type" in schema && typeof schema["x-ts-type"] === "string") {
169
- const tsType = schema["x-ts-type"];
170
- if (tsType === "function" || schema["x-ts-function"]) {
171
- return withPackage(formatFunctionSchema(schema));
172
- }
173
- return withPackage(tsType);
174
- }
175
- if ("x-ts-function" in schema && schema["x-ts-function"]) {
176
- return withPackage(formatFunctionSchema(schema));
177
- }
178
- if ("x-ts-type-predicate" in schema) {
179
- const pred = schema["x-ts-type-predicate"];
180
- return `${pred.parameterName} is ${formatSchema(pred.type, options)}`;
181
- }
182
- if ("$ref" in schema && typeof schema.$ref === "string") {
183
- const baseName = schema.$ref.replace("#/types/", "");
184
- if ("x-ts-type-arguments" in schema && Array.isArray(schema["x-ts-type-arguments"])) {
185
- const args = schema["x-ts-type-arguments"].map((s) => formatSchema(s, options)).join(", ");
186
- return withPackage(`${baseName}<${args}>`);
187
- }
188
- return withPackage(baseName);
189
- }
190
- if ("anyOf" in schema && Array.isArray(schema.anyOf)) {
191
- const threshold = options?.collapseUnionThreshold;
192
- const members = schema.anyOf;
193
- if (threshold && members.length > threshold) {
194
- const shown = members.slice(0, 3);
195
- const remaining = members.length - 3;
196
- const shownStr = shown.map((s) => formatSchema(s, options)).join(" | ");
197
- return `${shownStr} | ... (${remaining} more)`;
198
- }
199
- return members.map((s) => formatSchema(s, options)).join(" | ");
200
- }
201
- if ("allOf" in schema && Array.isArray(schema.allOf)) {
202
- return schema.allOf.map((s) => formatSchema(s, options)).join(" & ");
203
- }
204
- if ("type" in schema && schema.type === "array") {
205
- const items = "items" in schema ? formatSchema(schema.items, options) : "unknown";
206
- return `${items}[]`;
207
- }
208
- if ("type" in schema && schema.type === "tuple" && "items" in schema) {
209
- const items = schema.items.map((s) => formatSchema(s, options)).join(", ");
210
- return `[${items}]`;
211
- }
212
- if ("type" in schema && schema.type === "object") {
213
- if ("properties" in schema && schema.properties) {
214
- const props = Object.entries(schema.properties).map(([k, v]) => `${k}: ${formatSchema(v, options)}`).join("; ");
215
- return `{ ${props} }`;
216
- }
217
- return "object";
218
- }
219
- if ("type" in schema && typeof schema.type === "string") {
220
- return withPackage(schema.type);
221
- }
222
- }
223
- return "unknown";
224
- }
225
- function formatTypeParameters(typeParams) {
226
- if (!typeParams?.length)
227
- return "";
228
- const params = typeParams.map((tp) => {
229
- let str = "";
230
- if ("const" in tp && tp.const)
231
- str += "const ";
232
- if (tp.variance === "in")
233
- str += "in ";
234
- else if (tp.variance === "out")
235
- str += "out ";
236
- else if (tp.variance === "inout")
237
- str += "in out ";
238
- str += tp.name;
239
- if (tp.constraint)
240
- str += ` extends ${tp.constraint}`;
241
- if (tp.default)
242
- str += ` = ${tp.default}`;
243
- return str;
244
- });
245
- return `<${params.join(", ")}>`;
246
- }
247
- function formatParameters(sig) {
248
- if (!sig?.parameters?.length)
249
- return "()";
250
- const params = sig.parameters.map((p) => {
251
- const optional = p.required === false ? "?" : "";
252
- const rest = p.rest ? "..." : "";
253
- const type = formatSchema(p.schema);
254
- return `${rest}${p.name}${optional}: ${type}`;
255
- });
256
- return `(${params.join(", ")})`;
257
- }
258
- function formatReturnType(sig) {
259
- if (!sig?.returns)
260
- return "void";
261
- return formatSchema(sig.returns.schema);
262
- }
263
- function buildSignatureString(exp, sigIndex = 0) {
264
- const sig = exp.signatures?.[sigIndex];
265
- const typeParams = formatTypeParameters(exp.typeParameters || sig?.typeParameters);
266
- switch (exp.kind) {
267
- case "function": {
268
- const params = formatParameters(sig);
269
- const returnType = formatReturnType(sig);
270
- return `function ${exp.name}${typeParams}${params}: ${returnType}`;
271
- }
272
- case "class": {
273
- const ext = exp.extends ? ` extends ${exp.extends}` : "";
274
- const impl = exp.implements?.length ? ` implements ${exp.implements.join(", ")}` : "";
275
- return `class ${exp.name}${typeParams}${ext}${impl}`;
276
- }
277
- case "interface": {
278
- const ext = exp.extends ? ` extends ${exp.extends}` : "";
279
- return `interface ${exp.name}${typeParams}${ext}`;
280
- }
281
- case "type": {
282
- const typeValue = typeof exp.type === "string" ? exp.type : formatSchema(exp.schema);
283
- return `type ${exp.name}${typeParams} = ${typeValue}`;
284
- }
285
- case "enum": {
286
- return `enum ${exp.name}`;
287
- }
288
- case "variable": {
289
- const typeValue = typeof exp.type === "string" ? exp.type : formatSchema(exp.schema);
290
- return `const ${exp.name}: ${typeValue}`;
291
- }
292
- default:
293
- return exp.name;
294
- }
295
- }
296
- function resolveTypeRef(ref, spec) {
297
- const id = ref.replace("#/types/", "");
298
- return spec.types?.find((t) => t.id === id);
299
- }
300
- function isMethod(member) {
301
- return !!member.signatures?.length;
302
- }
303
- function isProperty(member) {
304
- return !member.signatures?.length;
305
- }
306
- function getMethods(members) {
307
- return members?.filter(isMethod) ?? [];
308
- }
309
- function getProperties(members) {
310
- return members?.filter(isProperty) ?? [];
311
- }
312
- function groupByVisibility(members) {
313
- const groups = {
314
- public: [],
315
- protected: [],
316
- private: []
317
- };
318
- for (const member of members ?? []) {
319
- const visibility = member.visibility ?? "public";
320
- groups[visibility].push(member);
321
- }
322
- return groups;
323
- }
324
- function sortByName(items) {
325
- return [...items].sort((a, b) => a.name.localeCompare(b.name));
326
- }
327
- function formatConditionalType(condType) {
328
- const check = formatSchema(condType.checkType);
329
- const ext = formatSchema(condType.extendsType);
330
- const trueT = formatSchema(condType.trueType);
331
- const falseT = formatSchema(condType.falseType);
332
- return `${check} extends ${ext} ? ${trueT} : ${falseT}`;
333
- }
334
- function formatMappedType(mappedType) {
335
- const keyStr = formatSchema(mappedType.keyType);
336
- const valueStr = formatSchema(mappedType.valueType);
337
- let readonlyMod = "";
338
- if (mappedType.readonly === true || mappedType.readonly === "add") {
339
- readonlyMod = "readonly ";
340
- } else if (mappedType.readonly === "remove") {
341
- readonlyMod = "-readonly ";
342
- }
343
- let optionalMod = "";
344
- if (mappedType.optional === true || mappedType.optional === "add") {
345
- optionalMod = "?";
346
- } else if (mappedType.optional === "remove") {
347
- optionalMod = "-?";
348
- }
349
- return `{ ${readonlyMod}[${keyStr}]${optionalMod}: ${valueStr} }`;
350
- }
351
-
352
77
  // src/render/html.ts
353
78
  var defaultCSS = `
354
79
  :root {
@@ -1368,171 +1093,6 @@ function toDocusaurusSidebarJS(spec, options = {}) {
1368
1093
  return `module.exports = ${JSON.stringify(sidebar, null, 2)};`;
1369
1094
  }
1370
1095
 
1371
- // src/core/search.ts
1372
- var defaultSlugify2 = (name) => name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
1373
- function extractKeywords(exp, options = {}) {
1374
- const keywords = new Set;
1375
- keywords.add(exp.name);
1376
- keywords.add(exp.name.toLowerCase());
1377
- const camelParts = exp.name.split(/(?=[A-Z])/);
1378
- for (const part of camelParts) {
1379
- if (part.length > 2)
1380
- keywords.add(part.toLowerCase());
1381
- }
1382
- if (exp.tags) {
1383
- for (const tag of exp.tags) {
1384
- keywords.add(tag.name.replace("@", ""));
1385
- const tagWords = tag.text.split(/\s+/);
1386
- for (const word of tagWords) {
1387
- if (word.length > 2)
1388
- keywords.add(word.toLowerCase());
1389
- }
1390
- }
1391
- }
1392
- if (exp.description) {
1393
- const descWords = exp.description.toLowerCase().split(/\W+/).filter((w) => w.length > 2);
1394
- for (const word of descWords) {
1395
- keywords.add(word);
1396
- }
1397
- }
1398
- if (options.includeMembers && exp.members) {
1399
- for (const member of exp.members) {
1400
- if (member.name) {
1401
- keywords.add(member.name.toLowerCase());
1402
- }
1403
- }
1404
- }
1405
- if (options.includeParameters && exp.signatures) {
1406
- for (const sig of exp.signatures) {
1407
- for (const param of sig.parameters || []) {
1408
- keywords.add(param.name.toLowerCase());
1409
- }
1410
- }
1411
- }
1412
- return Array.from(keywords);
1413
- }
1414
- function buildContent(exp, options = {}) {
1415
- const parts = [];
1416
- parts.push(exp.name);
1417
- if (exp.description) {
1418
- parts.push(exp.description);
1419
- }
1420
- if (options.includeSignatures !== false) {
1421
- parts.push(buildSignatureString(exp));
1422
- }
1423
- if (exp.tags) {
1424
- parts.push(...exp.tags.map((t) => `${t.name} ${t.text}`));
1425
- }
1426
- if (options.includeMembers !== false && exp.members) {
1427
- const props = getProperties(exp.members);
1428
- const methods = getMethods(exp.members);
1429
- for (const prop of props) {
1430
- if (prop.name) {
1431
- parts.push(prop.name);
1432
- if (prop.description)
1433
- parts.push(prop.description);
1434
- }
1435
- }
1436
- for (const method of methods) {
1437
- if (method.name) {
1438
- parts.push(method.name);
1439
- if (method.description)
1440
- parts.push(method.description);
1441
- }
1442
- }
1443
- }
1444
- if (options.includeParameters !== false && exp.signatures) {
1445
- for (const sig of exp.signatures) {
1446
- for (const param of sig.parameters || []) {
1447
- parts.push(param.name);
1448
- if (param.description)
1449
- parts.push(param.description);
1450
- }
1451
- }
1452
- }
1453
- return parts.join(" ");
1454
- }
1455
- function createSearchRecord(exp, _packageName, options = {}) {
1456
- const { baseUrl = "/api", slugify = defaultSlugify2 } = options;
1457
- return {
1458
- id: exp.id,
1459
- name: exp.name,
1460
- kind: exp.kind,
1461
- signature: buildSignatureString(exp),
1462
- description: exp.description,
1463
- content: buildContent(exp, options),
1464
- keywords: extractKeywords(exp, options),
1465
- url: `${baseUrl}/${slugify(exp.name)}`,
1466
- deprecated: exp.deprecated === true
1467
- };
1468
- }
1469
- function toSearchIndex(spec, options = {}) {
1470
- const records = spec.exports.map((exp) => createSearchRecord(exp, spec.meta.name, options));
1471
- return {
1472
- records,
1473
- version: spec.meta.version || "0.0.0",
1474
- generatedAt: new Date().toISOString(),
1475
- packageName: spec.meta.name
1476
- };
1477
- }
1478
- function toPagefindRecords(spec, options = {}) {
1479
- const { baseUrl = "/api", slugify = defaultSlugify2, weights = {} } = options;
1480
- const { name: nameWeight = 10, description: descWeight = 5, signature: sigWeight = 3 } = weights;
1481
- return spec.exports.map((exp) => {
1482
- const content = buildContent(exp, options);
1483
- const signature = buildSignatureString(exp);
1484
- const filters = {
1485
- kind: [exp.kind]
1486
- };
1487
- if (exp.deprecated) {
1488
- filters.deprecated = ["true"];
1489
- }
1490
- if (exp.tags?.length) {
1491
- filters.tags = exp.tags.map((t) => t.name.replace("@", ""));
1492
- }
1493
- return {
1494
- url: `${baseUrl}/${slugify(exp.name)}`,
1495
- content,
1496
- word_count: content.split(/\s+/).length,
1497
- filters,
1498
- meta: {
1499
- title: exp.name,
1500
- kind: exp.kind,
1501
- description: exp.description?.slice(0, 160),
1502
- signature
1503
- },
1504
- weighted_sections: [
1505
- { weight: nameWeight, text: exp.name },
1506
- ...exp.description ? [{ weight: descWeight, text: exp.description }] : [],
1507
- { weight: sigWeight, text: signature }
1508
- ]
1509
- };
1510
- });
1511
- }
1512
- function toAlgoliaRecords(spec, options = {}) {
1513
- const { baseUrl = "/api", slugify = defaultSlugify2 } = options;
1514
- return spec.exports.map((exp) => ({
1515
- objectID: exp.id,
1516
- name: exp.name,
1517
- kind: exp.kind,
1518
- description: exp.description,
1519
- signature: buildSignatureString(exp),
1520
- content: buildContent(exp, options),
1521
- tags: (exp.tags || []).map((t) => t.name.replace("@", "")),
1522
- deprecated: exp.deprecated === true,
1523
- url: `${baseUrl}/${slugify(exp.name)}`,
1524
- hierarchy: {
1525
- lvl0: spec.meta.name,
1526
- lvl1: `${exp.kind.charAt(0).toUpperCase() + exp.kind.slice(1)}s`,
1527
- lvl2: exp.name
1528
- }
1529
- }));
1530
- }
1531
- function toSearchIndexJSON(spec, options = {}) {
1532
- const index = toSearchIndex(spec, options);
1533
- return options.pretty ? JSON.stringify(index, null, 2) : JSON.stringify(index);
1534
- }
1535
-
1536
1096
  // src/core/loader.ts
1537
1097
  function loadSpec(spec) {
1538
1098
  return createDocsInstance(spec);
@@ -1589,8 +1149,8 @@ function createDocsInstance(spec) {
1589
1149
  const normalizedTag = tagName.startsWith("@") ? tagName : `@${tagName}`;
1590
1150
  return exportsByTag.get(normalizedTag) ?? [];
1591
1151
  },
1592
- search(query) {
1593
- const lowerQuery = query.toLowerCase();
1152
+ search(query2) {
1153
+ const lowerQuery = query2.toLowerCase();
1594
1154
  return spec.exports.filter((exp) => {
1595
1155
  if (exp.name.toLowerCase().includes(lowerQuery))
1596
1156
  return true;
@@ -1654,6 +1214,221 @@ function extractModuleName(exp) {
1654
1214
  }
1655
1215
  return;
1656
1216
  }
1217
+ // src/render/react.ts
1218
+ import * as fs3 from "node:fs";
1219
+ import * as path2 from "node:path";
1220
+ function generateFullLayout(spec, componentsPath) {
1221
+ const pkgName = spec.meta.name;
1222
+ return `'use client';
1223
+
1224
+ import type { OpenPkg, SpecExport } from '@openpkg-ts/spec';
1225
+ import spec from './openpkg.json';
1226
+
1227
+ // Add components via: openpkg docs add function-section class-section interface-section
1228
+ // Then uncomment the imports below and customize as needed.
1229
+
1230
+ // import { FunctionSection } from '${componentsPath}/function-section';
1231
+ // import { ClassSection } from '${componentsPath}/class-section';
1232
+ // import { InterfaceSection } from '${componentsPath}/interface-section';
1233
+ // import { VariableSection } from '${componentsPath}/variable-section';
1234
+ // import { EnumSection } from '${componentsPath}/enum-section';
1235
+
1236
+ /**
1237
+ * Renders a single export based on its kind.
1238
+ * Customize this to match your design system.
1239
+ */
1240
+ function ExportSection({ exp }: { exp: SpecExport }) {
1241
+ // Uncomment the switch once you've added components:
1242
+ // switch (exp.kind) {
1243
+ // case 'function':
1244
+ // return <FunctionSection key={exp.id} export={exp} spec={spec as OpenPkg} />;
1245
+ // case 'class':
1246
+ // return <ClassSection key={exp.id} export={exp} spec={spec as OpenPkg} />;
1247
+ // case 'interface':
1248
+ // case 'type':
1249
+ // return <InterfaceSection key={exp.id} export={exp} spec={spec as OpenPkg} />;
1250
+ // case 'variable':
1251
+ // return <VariableSection key={exp.id} export={exp} spec={spec as OpenPkg} />;
1252
+ // case 'enum':
1253
+ // return <EnumSection key={exp.id} export={exp} spec={spec as OpenPkg} />;
1254
+ // default:
1255
+ // return null;
1256
+ // }
1257
+
1258
+ // Placeholder: replace with component imports above
1259
+ return (
1260
+ <section id={exp.id} className="py-8 border-b">
1261
+ <h2 className="text-xl font-semibold">{exp.name}</h2>
1262
+ <p className="text-muted-foreground">{exp.description || 'No description'}</p>
1263
+ <code className="text-sm">{exp.kind}</code>
1264
+ </section>
1265
+ );
1266
+ }
1267
+
1268
+ /**
1269
+ * Full API Reference Page for ${pkgName}
1270
+ *
1271
+ * This layout renders all exports on a single page.
1272
+ * Customize the grouping, styling, and components to match your docs.
1273
+ */
1274
+ export default function APIReferencePage() {
1275
+ const typedSpec = spec as OpenPkg;
1276
+ const exports = typedSpec.exports;
1277
+
1278
+ // Group exports by kind
1279
+ const functions = exports.filter((e) => e.kind === 'function');
1280
+ const classes = exports.filter((e) => e.kind === 'class');
1281
+ const interfaces = exports.filter((e) => e.kind === 'interface' || e.kind === 'type');
1282
+ const variables = exports.filter((e) => e.kind === 'variable');
1283
+ const enums = exports.filter((e) => e.kind === 'enum');
1284
+
1285
+ return (
1286
+ <div className="max-w-4xl mx-auto px-4 py-8">
1287
+ <header className="mb-12">
1288
+ <h1 className="text-3xl font-bold">{typedSpec.meta.name}</h1>
1289
+ {typedSpec.meta.description && (
1290
+ <p className="text-lg text-muted-foreground mt-2">{typedSpec.meta.description}</p>
1291
+ )}
1292
+ {typedSpec.meta.version && (
1293
+ <p className="text-sm text-muted-foreground">v{typedSpec.meta.version}</p>
1294
+ )}
1295
+ </header>
1296
+
1297
+ {functions.length > 0 && (
1298
+ <section className="mb-12">
1299
+ <h2 className="text-2xl font-bold mb-6">Functions</h2>
1300
+ {functions.map((exp) => (
1301
+ <ExportSection key={exp.id} exp={exp} />
1302
+ ))}
1303
+ </section>
1304
+ )}
1305
+
1306
+ {classes.length > 0 && (
1307
+ <section className="mb-12">
1308
+ <h2 className="text-2xl font-bold mb-6">Classes</h2>
1309
+ {classes.map((exp) => (
1310
+ <ExportSection key={exp.id} exp={exp} />
1311
+ ))}
1312
+ </section>
1313
+ )}
1314
+
1315
+ {interfaces.length > 0 && (
1316
+ <section className="mb-12">
1317
+ <h2 className="text-2xl font-bold mb-6">Types & Interfaces</h2>
1318
+ {interfaces.map((exp) => (
1319
+ <ExportSection key={exp.id} exp={exp} />
1320
+ ))}
1321
+ </section>
1322
+ )}
1323
+
1324
+ {variables.length > 0 && (
1325
+ <section className="mb-12">
1326
+ <h2 className="text-2xl font-bold mb-6">Variables</h2>
1327
+ {variables.map((exp) => (
1328
+ <ExportSection key={exp.id} exp={exp} />
1329
+ ))}
1330
+ </section>
1331
+ )}
1332
+
1333
+ {enums.length > 0 && (
1334
+ <section className="mb-12">
1335
+ <h2 className="text-2xl font-bold mb-6">Enums</h2>
1336
+ {enums.map((exp) => (
1337
+ <ExportSection key={exp.id} exp={exp} />
1338
+ ))}
1339
+ </section>
1340
+ )}
1341
+ </div>
1342
+ );
1343
+ }
1344
+
1345
+ export { spec };
1346
+ `;
1347
+ }
1348
+ function generateIndexLayout(spec, componentsPath) {
1349
+ const pkgName = spec.meta.name;
1350
+ return `'use client';
1351
+
1352
+ import type { OpenPkg } from '@openpkg-ts/spec';
1353
+ import spec from './openpkg.json';
1354
+
1355
+ // Add the export-card component: openpkg docs add export-card
1356
+ // import { ExportCard } from '${componentsPath}/export-card';
1357
+
1358
+ /**
1359
+ * API Reference Index Page for ${pkgName}
1360
+ *
1361
+ * Links to individual export pages. Best with file-based routing.
1362
+ * Customize the card component and links to match your docs.
1363
+ */
1364
+ export default function APIReferenceIndex() {
1365
+ const typedSpec = spec as OpenPkg;
1366
+ const exports = typedSpec.exports;
1367
+
1368
+ // Group exports by kind
1369
+ const groups = [
1370
+ { title: 'Functions', items: exports.filter((e) => e.kind === 'function') },
1371
+ { title: 'Classes', items: exports.filter((e) => e.kind === 'class') },
1372
+ { title: 'Types & Interfaces', items: exports.filter((e) => e.kind === 'interface' || e.kind === 'type') },
1373
+ { title: 'Variables', items: exports.filter((e) => e.kind === 'variable') },
1374
+ { title: 'Enums', items: exports.filter((e) => e.kind === 'enum') },
1375
+ ].filter((g) => g.items.length > 0);
1376
+
1377
+ return (
1378
+ <div className="max-w-4xl mx-auto px-4 py-8">
1379
+ <header className="mb-12">
1380
+ <h1 className="text-3xl font-bold">{typedSpec.meta.name}</h1>
1381
+ {typedSpec.meta.description && (
1382
+ <p className="text-lg text-muted-foreground mt-2">{typedSpec.meta.description}</p>
1383
+ )}
1384
+ </header>
1385
+
1386
+ {groups.map((group) => (
1387
+ <section key={group.title} className="mb-12">
1388
+ <h2 className="text-2xl font-bold mb-6">{group.title}</h2>
1389
+ <div className="grid gap-4 md:grid-cols-2">
1390
+ {group.items.map((exp) => (
1391
+ // Replace with ExportCard once installed:
1392
+ // <ExportCard key={exp.id} export={exp} href={\`/api/\${exp.name}\`} />
1393
+ <a
1394
+ key={exp.id}
1395
+ href={\`/api/\${exp.name}\`}
1396
+ className="block p-4 border rounded-lg hover:bg-muted transition-colors"
1397
+ >
1398
+ <h3 className="font-semibold">{exp.name}</h3>
1399
+ <p className="text-sm text-muted-foreground line-clamp-2">
1400
+ {exp.description || 'No description'}
1401
+ </p>
1402
+ <span className="text-xs bg-muted px-2 py-1 rounded mt-2 inline-block">
1403
+ {exp.kind}
1404
+ </span>
1405
+ </a>
1406
+ ))}
1407
+ </div>
1408
+ </section>
1409
+ ))}
1410
+ </div>
1411
+ );
1412
+ }
1413
+
1414
+ export { spec };
1415
+ `;
1416
+ }
1417
+ async function toReact(spec, options) {
1418
+ const { outDir, variant = "full", componentsPath = "@/components/api" } = options;
1419
+ if (!fs3.existsSync(outDir)) {
1420
+ fs3.mkdirSync(outDir, { recursive: true });
1421
+ }
1422
+ const specPath = path2.join(outDir, "openpkg.json");
1423
+ fs3.writeFileSync(specPath, JSON.stringify(spec, null, 2));
1424
+ const layoutContent = variant === "index" ? generateIndexLayout(spec, componentsPath) : generateFullLayout(spec, componentsPath);
1425
+ const layoutPath = path2.join(outDir, "page.tsx");
1426
+ fs3.writeFileSync(layoutPath, layoutContent);
1427
+ }
1428
+ function toReactString(spec, options = {}) {
1429
+ const { variant = "full", componentsPath = "@/components/api" } = options;
1430
+ return variant === "index" ? generateIndexLayout(spec, componentsPath) : generateFullLayout(spec, componentsPath);
1431
+ }
1657
1432
  // src/primitives/filter.ts
1658
1433
  function matchesExport(exp, criteria) {
1659
1434
  if (criteria.kinds && criteria.kinds.length > 0) {
@@ -1761,8 +1536,8 @@ function filterSpec(spec, criteria) {
1761
1536
  import ts11 from "typescript";
1762
1537
 
1763
1538
  // src/compiler/program.ts
1764
- import * as fs3 from "node:fs";
1765
- import * as path2 from "node:path";
1539
+ import * as fs4 from "node:fs";
1540
+ import * as path3 from "node:path";
1766
1541
  import ts from "typescript";
1767
1542
  function isJsFile(file) {
1768
1543
  return /\.(js|mjs|cjs|jsx)$/.test(file);
@@ -1788,16 +1563,16 @@ function resolveProjectReferences(configPath, parsedConfig) {
1788
1563
  if (!parsedConfig.projectReferences?.length) {
1789
1564
  return additionalFiles;
1790
1565
  }
1791
- const configDir = path2.dirname(configPath);
1566
+ const configDir = path3.dirname(configPath);
1792
1567
  for (const ref of parsedConfig.projectReferences) {
1793
- const refPath = path2.resolve(configDir, ref.path);
1794
- const refConfigPath = fs3.existsSync(path2.join(refPath, "tsconfig.json")) ? path2.join(refPath, "tsconfig.json") : refPath;
1795
- if (!fs3.existsSync(refConfigPath))
1568
+ const refPath = path3.resolve(configDir, ref.path);
1569
+ const refConfigPath = fs4.existsSync(path3.join(refPath, "tsconfig.json")) ? path3.join(refPath, "tsconfig.json") : refPath;
1570
+ if (!fs4.existsSync(refConfigPath))
1796
1571
  continue;
1797
1572
  const refConfigFile = ts.readConfigFile(refConfigPath, ts.sys.readFile);
1798
1573
  if (refConfigFile.error)
1799
1574
  continue;
1800
- const refParsed = ts.parseJsonConfigFileContent(refConfigFile.config, ts.sys, path2.dirname(refConfigPath));
1575
+ const refParsed = ts.parseJsonConfigFileContent(refConfigFile.config, ts.sys, path3.dirname(refConfigPath));
1801
1576
  additionalFiles.push(...refParsed.fileNames);
1802
1577
  }
1803
1578
  return additionalFiles;
@@ -1830,10 +1605,10 @@ function buildWorkspaceMap(baseDir) {
1830
1605
  let rootDir;
1831
1606
  let workspaceGlobs = [];
1832
1607
  for (let i = 0;i < 10; i++) {
1833
- const pnpmPath = path2.join(currentDir, "pnpm-workspace.yaml");
1834
- if (fs3.existsSync(pnpmPath)) {
1608
+ const pnpmPath = path3.join(currentDir, "pnpm-workspace.yaml");
1609
+ if (fs4.existsSync(pnpmPath)) {
1835
1610
  try {
1836
- const yamlContent = fs3.readFileSync(pnpmPath, "utf-8");
1611
+ const yamlContent = fs4.readFileSync(pnpmPath, "utf-8");
1837
1612
  workspaceGlobs = parsePnpmWorkspace(yamlContent);
1838
1613
  if (workspaceGlobs.length > 0) {
1839
1614
  rootDir = currentDir;
@@ -1841,10 +1616,10 @@ function buildWorkspaceMap(baseDir) {
1841
1616
  }
1842
1617
  } catch {}
1843
1618
  }
1844
- const pkgPath = path2.join(currentDir, "package.json");
1845
- if (fs3.existsSync(pkgPath)) {
1619
+ const pkgPath = path3.join(currentDir, "package.json");
1620
+ if (fs4.existsSync(pkgPath)) {
1846
1621
  try {
1847
- const pkg = JSON.parse(fs3.readFileSync(pkgPath, "utf-8"));
1622
+ const pkg = JSON.parse(fs4.readFileSync(pkgPath, "utf-8"));
1848
1623
  if (pkg.workspaces) {
1849
1624
  rootDir = currentDir;
1850
1625
  workspaceGlobs = Array.isArray(pkg.workspaces) ? pkg.workspaces : pkg.workspaces?.packages || [];
@@ -1852,7 +1627,7 @@ function buildWorkspaceMap(baseDir) {
1852
1627
  }
1853
1628
  } catch {}
1854
1629
  }
1855
- const parent = path2.dirname(currentDir);
1630
+ const parent = path3.dirname(currentDir);
1856
1631
  if (parent === currentDir)
1857
1632
  break;
1858
1633
  currentDir = parent;
@@ -1861,21 +1636,21 @@ function buildWorkspaceMap(baseDir) {
1861
1636
  return;
1862
1637
  const packages = new Map;
1863
1638
  for (const glob of workspaceGlobs) {
1864
- const globDir = path2.join(rootDir, glob.replace(/\/\*$/, ""));
1865
- if (!fs3.existsSync(globDir) || !fs3.statSync(globDir).isDirectory())
1639
+ const globDir = path3.join(rootDir, glob.replace(/\/\*$/, ""));
1640
+ if (!fs4.existsSync(globDir) || !fs4.statSync(globDir).isDirectory())
1866
1641
  continue;
1867
- const entries = fs3.readdirSync(globDir, { withFileTypes: true });
1642
+ const entries = fs4.readdirSync(globDir, { withFileTypes: true });
1868
1643
  for (const entry of entries) {
1869
1644
  if (!entry.isDirectory())
1870
1645
  continue;
1871
- const pkgDir = path2.join(globDir, entry.name);
1872
- const pkgJsonPath = path2.join(pkgDir, "package.json");
1873
- if (!fs3.existsSync(pkgJsonPath))
1646
+ const pkgDir = path3.join(globDir, entry.name);
1647
+ const pkgJsonPath = path3.join(pkgDir, "package.json");
1648
+ if (!fs4.existsSync(pkgJsonPath))
1874
1649
  continue;
1875
1650
  try {
1876
- const pkg = JSON.parse(fs3.readFileSync(pkgJsonPath, "utf-8"));
1651
+ const pkg = JSON.parse(fs4.readFileSync(pkgJsonPath, "utf-8"));
1877
1652
  if (pkg.name) {
1878
- const srcDir = fs3.existsSync(path2.join(pkgDir, "src")) ? path2.join(pkgDir, "src") : pkgDir;
1653
+ const srcDir = fs4.existsSync(path3.join(pkgDir, "src")) ? path3.join(pkgDir, "src") : pkgDir;
1879
1654
  packages.set(pkg.name, srcDir);
1880
1655
  }
1881
1656
  } catch {}
@@ -1885,7 +1660,7 @@ function buildWorkspaceMap(baseDir) {
1885
1660
  }
1886
1661
  function createProgram({
1887
1662
  entryFile,
1888
- baseDir = path2.dirname(entryFile),
1663
+ baseDir = path3.dirname(entryFile),
1889
1664
  content
1890
1665
  }) {
1891
1666
  let configPath = ts.findConfigFile(baseDir, ts.sys.fileExists, "tsconfig.json");
@@ -1896,9 +1671,11 @@ function createProgram({
1896
1671
  let additionalRootFiles = [];
1897
1672
  if (configPath) {
1898
1673
  const configFile = ts.readConfigFile(configPath, ts.sys.readFile);
1899
- const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path2.dirname(configPath));
1674
+ const parsedConfig = ts.parseJsonConfigFileContent(configFile.config, ts.sys, path3.dirname(configPath));
1900
1675
  compilerOptions = { ...compilerOptions, ...parsedConfig.options };
1901
1676
  additionalRootFiles = resolveProjectReferences(configPath, parsedConfig);
1677
+ const sourceFiles = parsedConfig.fileNames.filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("/dist/") && !f.includes("/node_modules/"));
1678
+ additionalRootFiles.push(...sourceFiles);
1902
1679
  }
1903
1680
  if (isJsFile(entryFile)) {
1904
1681
  compilerOptions = {
@@ -1922,8 +1699,8 @@ function createProgram({
1922
1699
  return moduleNames.map((moduleName) => {
1923
1700
  const srcDir = workspaceMap.packages.get(moduleName);
1924
1701
  if (srcDir) {
1925
- const indexFile = path2.join(srcDir, "index.ts");
1926
- if (fs3.existsSync(indexFile)) {
1702
+ const indexFile = path3.join(srcDir, "index.ts");
1703
+ if (fs4.existsSync(indexFile)) {
1927
1704
  return { resolvedFileName: indexFile, isExternalLibraryImport: false };
1928
1705
  }
1929
1706
  }
@@ -4815,7 +4592,7 @@ function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportN
4815
4592
  return result;
4816
4593
  }
4817
4594
  // src/primitives/list.ts
4818
- import * as path3 from "node:path";
4595
+ import * as path4 from "node:path";
4819
4596
  import ts12 from "typescript";
4820
4597
  async function listExports(options) {
4821
4598
  const { entryFile, baseDir, content } = options;
@@ -4863,7 +4640,7 @@ function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
4863
4640
  return {
4864
4641
  name,
4865
4642
  kind: "namespace",
4866
- file: path3.relative(path3.dirname(entryFile), declaration.fileName),
4643
+ file: path4.relative(path4.dirname(entryFile), declaration.fileName),
4867
4644
  line: 1,
4868
4645
  reexport: true
4869
4646
  };
@@ -4877,7 +4654,7 @@ function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
4877
4654
  return {
4878
4655
  name,
4879
4656
  kind,
4880
- file: path3.relative(path3.dirname(entryFile), sourceFile.fileName),
4657
+ file: path4.relative(path4.dirname(entryFile), sourceFile.fileName),
4881
4658
  line: line + 1,
4882
4659
  ...description ? { description } : {},
4883
4660
  ...deprecated ? { deprecated: true } : {},
@@ -4929,8 +4706,8 @@ function getDescriptionPreview(symbol, checker) {
4929
4706
  return `${firstLine.slice(0, 77)}...`;
4930
4707
  }
4931
4708
  // src/builder/spec-builder.ts
4932
- import * as fs6 from "node:fs";
4933
- import * as path6 from "node:path";
4709
+ import * as fs7 from "node:fs";
4710
+ import * as path7 from "node:path";
4934
4711
  import { SCHEMA_URL, SCHEMA_VERSION } from "@openpkg-ts/spec";
4935
4712
  import ts15 from "typescript";
4936
4713
 
@@ -4966,9 +4743,9 @@ function resolveExportTarget2(symbol, checker) {
4966
4743
 
4967
4744
  // src/schema/standard-schema.ts
4968
4745
  import { spawn, spawnSync } from "node:child_process";
4969
- import * as fs4 from "node:fs";
4746
+ import * as fs5 from "node:fs";
4970
4747
  import * as os from "node:os";
4971
- import * as path4 from "node:path";
4748
+ import * as path5 from "node:path";
4972
4749
  function isStandardJSONSchema(obj) {
4973
4750
  if (typeof obj !== "object" || obj === null)
4974
4751
  return false;
@@ -5214,21 +4991,21 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
5214
4991
  result.errors.push("No TypeScript runtime available. Install bun, tsx, or ts-node, or use Node 22+.");
5215
4992
  return result;
5216
4993
  }
5217
- if (!fs4.existsSync(tsFilePath)) {
4994
+ if (!fs5.existsSync(tsFilePath)) {
5218
4995
  result.errors.push(`TypeScript file not found: ${tsFilePath}`);
5219
4996
  return result;
5220
4997
  }
5221
4998
  const tempDir = os.tmpdir();
5222
- const workerPath = path4.join(tempDir, `openpkg-extract-worker-${Date.now()}.ts`);
4999
+ const workerPath = path5.join(tempDir, `openpkg-extract-worker-${Date.now()}.ts`);
5223
5000
  try {
5224
- fs4.writeFileSync(workerPath, TS_WORKER_SCRIPT);
5001
+ fs5.writeFileSync(workerPath, TS_WORKER_SCRIPT);
5225
5002
  const optionsJson = JSON.stringify({ target, libraryOptions });
5226
5003
  const args = [...runtime.args, workerPath, tsFilePath, optionsJson];
5227
5004
  return await new Promise((resolve2) => {
5228
5005
  const child = spawn(runtime.cmd, args, {
5229
5006
  timeout,
5230
5007
  stdio: ["ignore", "pipe", "pipe"],
5231
- cwd: path4.dirname(tsFilePath)
5008
+ cwd: path5.dirname(tsFilePath)
5232
5009
  });
5233
5010
  let stdout = "";
5234
5011
  let stderr = "";
@@ -5240,7 +5017,7 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
5240
5017
  });
5241
5018
  child.on("close", (code) => {
5242
5019
  try {
5243
- fs4.unlinkSync(workerPath);
5020
+ fs5.unlinkSync(workerPath);
5244
5021
  } catch {}
5245
5022
  if (code !== 0) {
5246
5023
  result.errors.push(`Extraction failed (${runtime.name}): ${stderr || `exit code ${code}`}`);
@@ -5269,7 +5046,7 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
5269
5046
  });
5270
5047
  child.on("error", (err) => {
5271
5048
  try {
5272
- fs4.unlinkSync(workerPath);
5049
+ fs5.unlinkSync(workerPath);
5273
5050
  } catch {}
5274
5051
  result.errors.push(`Subprocess error: ${err.message}`);
5275
5052
  resolve2(result);
@@ -5277,19 +5054,19 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
5277
5054
  });
5278
5055
  } catch (e) {
5279
5056
  try {
5280
- fs4.unlinkSync(workerPath);
5057
+ fs5.unlinkSync(workerPath);
5281
5058
  } catch {}
5282
5059
  result.errors.push(`Failed to create worker script: ${e}`);
5283
5060
  return result;
5284
5061
  }
5285
5062
  }
5286
5063
  function readTsconfigOutDir(baseDir) {
5287
- const tsconfigPath = path4.join(baseDir, "tsconfig.json");
5064
+ const tsconfigPath = path5.join(baseDir, "tsconfig.json");
5288
5065
  try {
5289
- if (!fs4.existsSync(tsconfigPath)) {
5066
+ if (!fs5.existsSync(tsconfigPath)) {
5290
5067
  return null;
5291
5068
  }
5292
- const content = fs4.readFileSync(tsconfigPath, "utf-8");
5069
+ const content = fs5.readFileSync(tsconfigPath, "utf-8");
5293
5070
  const stripped = content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
5294
5071
  const tsconfig = JSON.parse(stripped);
5295
5072
  if (tsconfig.compilerOptions?.outDir) {
@@ -5299,7 +5076,7 @@ function readTsconfigOutDir(baseDir) {
5299
5076
  return null;
5300
5077
  }
5301
5078
  function resolveCompiledPath(tsPath, baseDir) {
5302
- const relativePath = path4.relative(baseDir, tsPath);
5079
+ const relativePath = path5.relative(baseDir, tsPath);
5303
5080
  const withoutExt = relativePath.replace(/\.tsx?$/, "");
5304
5081
  const srcPrefix = withoutExt.replace(/^src\//, "");
5305
5082
  const tsconfigOutDir = readTsconfigOutDir(baseDir);
@@ -5307,7 +5084,7 @@ function resolveCompiledPath(tsPath, baseDir) {
5307
5084
  const candidates = [];
5308
5085
  if (tsconfigOutDir) {
5309
5086
  for (const ext of extensions) {
5310
- candidates.push(path4.join(baseDir, tsconfigOutDir, `${srcPrefix}${ext}`));
5087
+ candidates.push(path5.join(baseDir, tsconfigOutDir, `${srcPrefix}${ext}`));
5311
5088
  }
5312
5089
  }
5313
5090
  const commonOutDirs = ["dist", "build", "lib", "out"];
@@ -5315,21 +5092,21 @@ function resolveCompiledPath(tsPath, baseDir) {
5315
5092
  if (outDir === tsconfigOutDir)
5316
5093
  continue;
5317
5094
  for (const ext of extensions) {
5318
- candidates.push(path4.join(baseDir, outDir, `${srcPrefix}${ext}`));
5095
+ candidates.push(path5.join(baseDir, outDir, `${srcPrefix}${ext}`));
5319
5096
  }
5320
5097
  }
5321
5098
  for (const ext of extensions) {
5322
- candidates.push(path4.join(baseDir, `${withoutExt}${ext}`));
5099
+ candidates.push(path5.join(baseDir, `${withoutExt}${ext}`));
5323
5100
  }
5324
5101
  const workspaceMatch = baseDir.match(/^(.+\/packages\/[^/]+)$/);
5325
5102
  if (workspaceMatch) {
5326
5103
  const pkgRoot = workspaceMatch[1];
5327
5104
  for (const ext of extensions) {
5328
- candidates.push(path4.join(pkgRoot, "dist", `${srcPrefix}${ext}`));
5105
+ candidates.push(path5.join(pkgRoot, "dist", `${srcPrefix}${ext}`));
5329
5106
  }
5330
5107
  }
5331
5108
  for (const candidate of candidates) {
5332
- if (fs4.existsSync(candidate)) {
5109
+ if (fs5.existsSync(candidate)) {
5333
5110
  return candidate;
5334
5111
  }
5335
5112
  }
@@ -5341,7 +5118,7 @@ async function extractStandardSchemas(compiledJsPath, options = {}) {
5341
5118
  schemas: new Map,
5342
5119
  errors: []
5343
5120
  };
5344
- if (!fs4.existsSync(compiledJsPath)) {
5121
+ if (!fs5.existsSync(compiledJsPath)) {
5345
5122
  result.errors.push(`Compiled JS not found: ${compiledJsPath}`);
5346
5123
  return result;
5347
5124
  }
@@ -5423,8 +5200,8 @@ async function extractStandardSchemasFromProject(entryFile, baseDir, options = {
5423
5200
  }
5424
5201
 
5425
5202
  // src/builder/external-resolver.ts
5426
- import * as fs5 from "node:fs";
5427
- import * as path5 from "node:path";
5203
+ import * as fs6 from "node:fs";
5204
+ import * as path6 from "node:path";
5428
5205
  import picomatch from "picomatch";
5429
5206
  import ts14 from "typescript";
5430
5207
  function matchesExternalPattern(packageName, include, exclude) {
@@ -5458,20 +5235,20 @@ function findPackageJson(resolvedPath, packageName) {
5458
5235
  const isScoped = packageName.startsWith("@");
5459
5236
  const packageParts = isScoped ? packageName.split("/").slice(0, 2) : [packageName.split("/")[0]];
5460
5237
  const packageDir = packageParts.join("/");
5461
- let dir = path5.dirname(resolvedPath);
5238
+ let dir = path6.dirname(resolvedPath);
5462
5239
  const maxDepth = 10;
5463
5240
  for (let i = 0;i < maxDepth; i++) {
5464
5241
  if (dir.endsWith(`node_modules/${packageDir}`)) {
5465
- const pkgPath = path5.join(dir, "package.json");
5466
- if (fs5.existsSync(pkgPath)) {
5242
+ const pkgPath = path6.join(dir, "package.json");
5243
+ if (fs6.existsSync(pkgPath)) {
5467
5244
  try {
5468
- return JSON.parse(fs5.readFileSync(pkgPath, "utf-8"));
5245
+ return JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
5469
5246
  } catch {
5470
5247
  return;
5471
5248
  }
5472
5249
  }
5473
5250
  }
5474
- const parent = path5.dirname(dir);
5251
+ const parent = path6.dirname(dir);
5475
5252
  if (parent === dir)
5476
5253
  break;
5477
5254
  dir = parent;
@@ -5916,7 +5693,7 @@ async function extract(options) {
5916
5693
  const verification = buildVerificationSummary(exportedSymbols.length, exports.length, exportTracker);
5917
5694
  const meta = await getPackageMeta(entryFile, baseDir);
5918
5695
  const types = ctx.typeRegistry.getAll();
5919
- const projectBaseDir = baseDir ?? path6.dirname(entryFile);
5696
+ const projectBaseDir = baseDir ?? path7.dirname(entryFile);
5920
5697
  const definedTypes = new Set(types.map((t) => t.id));
5921
5698
  const forgottenExports = collectForgottenExports(exports, types, program, sourceFile, exportedIds, projectBaseDir, definedTypes);
5922
5699
  for (const forgotten of forgottenExports) {
@@ -5949,7 +5726,7 @@ async function extract(options) {
5949
5726
  }
5950
5727
  let runtimeMetadata;
5951
5728
  if (options.schemaExtraction === "hybrid") {
5952
- const projectBaseDir2 = baseDir || path6.dirname(entryFile);
5729
+ const projectBaseDir2 = baseDir || path7.dirname(entryFile);
5953
5730
  const runtimeResult = await extractStandardSchemasFromProject(entryFile, projectBaseDir2, {
5954
5731
  target: options.schemaTarget || "draft-2020-12",
5955
5732
  timeout: 15000
@@ -6099,8 +5876,8 @@ function isExternalType2(definedIn, baseDir) {
6099
5876
  return true;
6100
5877
  if (definedIn.includes("node_modules"))
6101
5878
  return true;
6102
- const normalizedDefined = path6.resolve(definedIn);
6103
- const normalizedBase = path6.resolve(baseDir);
5879
+ const normalizedDefined = path7.resolve(definedIn);
5880
+ const normalizedBase = path7.resolve(baseDir);
6104
5881
  return !normalizedDefined.startsWith(normalizedBase);
6105
5882
  }
6106
5883
  function hasInternalTag(typeName, program, sourceFile) {
@@ -6402,7 +6179,7 @@ function createEmptySpec(entryFile, includeSchema, isDtsSource) {
6402
6179
  return {
6403
6180
  ...includeSchema ? { $schema: SCHEMA_URL } : {},
6404
6181
  openpkg: SCHEMA_VERSION,
6405
- meta: { name: path6.basename(entryFile, path6.extname(entryFile)) },
6182
+ meta: { name: path7.basename(entryFile, path7.extname(entryFile)) },
6406
6183
  exports: [],
6407
6184
  generation: {
6408
6185
  generator: "@openpkg-ts/sdk",
@@ -6415,19 +6192,19 @@ function createEmptySpec(entryFile, includeSchema, isDtsSource) {
6415
6192
  };
6416
6193
  }
6417
6194
  async function getPackageMeta(entryFile, baseDir) {
6418
- const searchDir = baseDir ?? path6.dirname(entryFile);
6419
- const pkgPath = path6.join(searchDir, "package.json");
6195
+ const searchDir = baseDir ?? path7.dirname(entryFile);
6196
+ const pkgPath = path7.join(searchDir, "package.json");
6420
6197
  try {
6421
- if (fs6.existsSync(pkgPath)) {
6422
- const pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
6198
+ if (fs7.existsSync(pkgPath)) {
6199
+ const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
6423
6200
  return {
6424
- name: pkg.name ?? path6.basename(searchDir),
6201
+ name: pkg.name ?? path7.basename(searchDir),
6425
6202
  version: pkg.version,
6426
6203
  description: pkg.description
6427
6204
  };
6428
6205
  }
6429
6206
  } catch {}
6430
- return { name: path6.basename(searchDir) };
6207
+ return { name: path7.basename(searchDir) };
6431
6208
  }
6432
6209
 
6433
6210
  // src/primitives/spec.ts
@@ -6453,6 +6230,8 @@ export {
6453
6230
  typeboxAdapter,
6454
6231
  toSearchIndexJSON,
6455
6232
  toSearchIndex,
6233
+ toReactString,
6234
+ toReact,
6456
6235
  toPagefindRecords,
6457
6236
  toNavigation,
6458
6237
  toMarkdown,
@@ -6477,6 +6256,7 @@ export {
6477
6256
  registerReferencedTypes,
6478
6257
  registerAdapter,
6479
6258
  recommendSemverBump,
6259
+ query,
6480
6260
  normalizeType,
6481
6261
  normalizeSchema,
6482
6262
  normalizeMembers,
@@ -6545,6 +6325,7 @@ export {
6545
6325
  arktypeAdapter,
6546
6326
  analyzeSpec,
6547
6327
  TypeRegistry,
6328
+ QueryBuilder,
6548
6329
  CONFIG_FILENAME,
6549
6330
  BUILTIN_TYPE_SCHEMAS,
6550
6331
  ARRAY_PROTOTYPE_METHODS