@openpkg-ts/sdk 0.33.1 → 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,7 +1671,7 @@ 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);
1902
1677
  const sourceFiles = parsedConfig.fileNames.filter((f) => !f.includes(".test.") && !f.includes(".spec.") && !f.includes("/dist/") && !f.includes("/node_modules/"));
@@ -1924,8 +1699,8 @@ function createProgram({
1924
1699
  return moduleNames.map((moduleName) => {
1925
1700
  const srcDir = workspaceMap.packages.get(moduleName);
1926
1701
  if (srcDir) {
1927
- const indexFile = path2.join(srcDir, "index.ts");
1928
- if (fs3.existsSync(indexFile)) {
1702
+ const indexFile = path3.join(srcDir, "index.ts");
1703
+ if (fs4.existsSync(indexFile)) {
1929
1704
  return { resolvedFileName: indexFile, isExternalLibraryImport: false };
1930
1705
  }
1931
1706
  }
@@ -4817,7 +4592,7 @@ function serializeDeclaration(declaration, _exportSymbol, _targetSymbol, exportN
4817
4592
  return result;
4818
4593
  }
4819
4594
  // src/primitives/list.ts
4820
- import * as path3 from "node:path";
4595
+ import * as path4 from "node:path";
4821
4596
  import ts12 from "typescript";
4822
4597
  async function listExports(options) {
4823
4598
  const { entryFile, baseDir, content } = options;
@@ -4865,7 +4640,7 @@ function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
4865
4640
  return {
4866
4641
  name,
4867
4642
  kind: "namespace",
4868
- file: path3.relative(path3.dirname(entryFile), declaration.fileName),
4643
+ file: path4.relative(path4.dirname(entryFile), declaration.fileName),
4869
4644
  line: 1,
4870
4645
  reexport: true
4871
4646
  };
@@ -4879,7 +4654,7 @@ function extractExportItem(symbol, checker, entryFile, entrySourceFile) {
4879
4654
  return {
4880
4655
  name,
4881
4656
  kind,
4882
- file: path3.relative(path3.dirname(entryFile), sourceFile.fileName),
4657
+ file: path4.relative(path4.dirname(entryFile), sourceFile.fileName),
4883
4658
  line: line + 1,
4884
4659
  ...description ? { description } : {},
4885
4660
  ...deprecated ? { deprecated: true } : {},
@@ -4931,8 +4706,8 @@ function getDescriptionPreview(symbol, checker) {
4931
4706
  return `${firstLine.slice(0, 77)}...`;
4932
4707
  }
4933
4708
  // src/builder/spec-builder.ts
4934
- import * as fs6 from "node:fs";
4935
- import * as path6 from "node:path";
4709
+ import * as fs7 from "node:fs";
4710
+ import * as path7 from "node:path";
4936
4711
  import { SCHEMA_URL, SCHEMA_VERSION } from "@openpkg-ts/spec";
4937
4712
  import ts15 from "typescript";
4938
4713
 
@@ -4968,9 +4743,9 @@ function resolveExportTarget2(symbol, checker) {
4968
4743
 
4969
4744
  // src/schema/standard-schema.ts
4970
4745
  import { spawn, spawnSync } from "node:child_process";
4971
- import * as fs4 from "node:fs";
4746
+ import * as fs5 from "node:fs";
4972
4747
  import * as os from "node:os";
4973
- import * as path4 from "node:path";
4748
+ import * as path5 from "node:path";
4974
4749
  function isStandardJSONSchema(obj) {
4975
4750
  if (typeof obj !== "object" || obj === null)
4976
4751
  return false;
@@ -5216,21 +4991,21 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
5216
4991
  result.errors.push("No TypeScript runtime available. Install bun, tsx, or ts-node, or use Node 22+.");
5217
4992
  return result;
5218
4993
  }
5219
- if (!fs4.existsSync(tsFilePath)) {
4994
+ if (!fs5.existsSync(tsFilePath)) {
5220
4995
  result.errors.push(`TypeScript file not found: ${tsFilePath}`);
5221
4996
  return result;
5222
4997
  }
5223
4998
  const tempDir = os.tmpdir();
5224
- const workerPath = path4.join(tempDir, `openpkg-extract-worker-${Date.now()}.ts`);
4999
+ const workerPath = path5.join(tempDir, `openpkg-extract-worker-${Date.now()}.ts`);
5225
5000
  try {
5226
- fs4.writeFileSync(workerPath, TS_WORKER_SCRIPT);
5001
+ fs5.writeFileSync(workerPath, TS_WORKER_SCRIPT);
5227
5002
  const optionsJson = JSON.stringify({ target, libraryOptions });
5228
5003
  const args = [...runtime.args, workerPath, tsFilePath, optionsJson];
5229
5004
  return await new Promise((resolve2) => {
5230
5005
  const child = spawn(runtime.cmd, args, {
5231
5006
  timeout,
5232
5007
  stdio: ["ignore", "pipe", "pipe"],
5233
- cwd: path4.dirname(tsFilePath)
5008
+ cwd: path5.dirname(tsFilePath)
5234
5009
  });
5235
5010
  let stdout = "";
5236
5011
  let stderr = "";
@@ -5242,7 +5017,7 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
5242
5017
  });
5243
5018
  child.on("close", (code) => {
5244
5019
  try {
5245
- fs4.unlinkSync(workerPath);
5020
+ fs5.unlinkSync(workerPath);
5246
5021
  } catch {}
5247
5022
  if (code !== 0) {
5248
5023
  result.errors.push(`Extraction failed (${runtime.name}): ${stderr || `exit code ${code}`}`);
@@ -5271,7 +5046,7 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
5271
5046
  });
5272
5047
  child.on("error", (err) => {
5273
5048
  try {
5274
- fs4.unlinkSync(workerPath);
5049
+ fs5.unlinkSync(workerPath);
5275
5050
  } catch {}
5276
5051
  result.errors.push(`Subprocess error: ${err.message}`);
5277
5052
  resolve2(result);
@@ -5279,19 +5054,19 @@ async function extractStandardSchemasFromTs(tsFilePath, options = {}) {
5279
5054
  });
5280
5055
  } catch (e) {
5281
5056
  try {
5282
- fs4.unlinkSync(workerPath);
5057
+ fs5.unlinkSync(workerPath);
5283
5058
  } catch {}
5284
5059
  result.errors.push(`Failed to create worker script: ${e}`);
5285
5060
  return result;
5286
5061
  }
5287
5062
  }
5288
5063
  function readTsconfigOutDir(baseDir) {
5289
- const tsconfigPath = path4.join(baseDir, "tsconfig.json");
5064
+ const tsconfigPath = path5.join(baseDir, "tsconfig.json");
5290
5065
  try {
5291
- if (!fs4.existsSync(tsconfigPath)) {
5066
+ if (!fs5.existsSync(tsconfigPath)) {
5292
5067
  return null;
5293
5068
  }
5294
- const content = fs4.readFileSync(tsconfigPath, "utf-8");
5069
+ const content = fs5.readFileSync(tsconfigPath, "utf-8");
5295
5070
  const stripped = content.replace(/\/\*[\s\S]*?\*\//g, "").replace(/\/\/.*$/gm, "");
5296
5071
  const tsconfig = JSON.parse(stripped);
5297
5072
  if (tsconfig.compilerOptions?.outDir) {
@@ -5301,7 +5076,7 @@ function readTsconfigOutDir(baseDir) {
5301
5076
  return null;
5302
5077
  }
5303
5078
  function resolveCompiledPath(tsPath, baseDir) {
5304
- const relativePath = path4.relative(baseDir, tsPath);
5079
+ const relativePath = path5.relative(baseDir, tsPath);
5305
5080
  const withoutExt = relativePath.replace(/\.tsx?$/, "");
5306
5081
  const srcPrefix = withoutExt.replace(/^src\//, "");
5307
5082
  const tsconfigOutDir = readTsconfigOutDir(baseDir);
@@ -5309,7 +5084,7 @@ function resolveCompiledPath(tsPath, baseDir) {
5309
5084
  const candidates = [];
5310
5085
  if (tsconfigOutDir) {
5311
5086
  for (const ext of extensions) {
5312
- candidates.push(path4.join(baseDir, tsconfigOutDir, `${srcPrefix}${ext}`));
5087
+ candidates.push(path5.join(baseDir, tsconfigOutDir, `${srcPrefix}${ext}`));
5313
5088
  }
5314
5089
  }
5315
5090
  const commonOutDirs = ["dist", "build", "lib", "out"];
@@ -5317,21 +5092,21 @@ function resolveCompiledPath(tsPath, baseDir) {
5317
5092
  if (outDir === tsconfigOutDir)
5318
5093
  continue;
5319
5094
  for (const ext of extensions) {
5320
- candidates.push(path4.join(baseDir, outDir, `${srcPrefix}${ext}`));
5095
+ candidates.push(path5.join(baseDir, outDir, `${srcPrefix}${ext}`));
5321
5096
  }
5322
5097
  }
5323
5098
  for (const ext of extensions) {
5324
- candidates.push(path4.join(baseDir, `${withoutExt}${ext}`));
5099
+ candidates.push(path5.join(baseDir, `${withoutExt}${ext}`));
5325
5100
  }
5326
5101
  const workspaceMatch = baseDir.match(/^(.+\/packages\/[^/]+)$/);
5327
5102
  if (workspaceMatch) {
5328
5103
  const pkgRoot = workspaceMatch[1];
5329
5104
  for (const ext of extensions) {
5330
- candidates.push(path4.join(pkgRoot, "dist", `${srcPrefix}${ext}`));
5105
+ candidates.push(path5.join(pkgRoot, "dist", `${srcPrefix}${ext}`));
5331
5106
  }
5332
5107
  }
5333
5108
  for (const candidate of candidates) {
5334
- if (fs4.existsSync(candidate)) {
5109
+ if (fs5.existsSync(candidate)) {
5335
5110
  return candidate;
5336
5111
  }
5337
5112
  }
@@ -5343,7 +5118,7 @@ async function extractStandardSchemas(compiledJsPath, options = {}) {
5343
5118
  schemas: new Map,
5344
5119
  errors: []
5345
5120
  };
5346
- if (!fs4.existsSync(compiledJsPath)) {
5121
+ if (!fs5.existsSync(compiledJsPath)) {
5347
5122
  result.errors.push(`Compiled JS not found: ${compiledJsPath}`);
5348
5123
  return result;
5349
5124
  }
@@ -5425,8 +5200,8 @@ async function extractStandardSchemasFromProject(entryFile, baseDir, options = {
5425
5200
  }
5426
5201
 
5427
5202
  // src/builder/external-resolver.ts
5428
- import * as fs5 from "node:fs";
5429
- import * as path5 from "node:path";
5203
+ import * as fs6 from "node:fs";
5204
+ import * as path6 from "node:path";
5430
5205
  import picomatch from "picomatch";
5431
5206
  import ts14 from "typescript";
5432
5207
  function matchesExternalPattern(packageName, include, exclude) {
@@ -5460,20 +5235,20 @@ function findPackageJson(resolvedPath, packageName) {
5460
5235
  const isScoped = packageName.startsWith("@");
5461
5236
  const packageParts = isScoped ? packageName.split("/").slice(0, 2) : [packageName.split("/")[0]];
5462
5237
  const packageDir = packageParts.join("/");
5463
- let dir = path5.dirname(resolvedPath);
5238
+ let dir = path6.dirname(resolvedPath);
5464
5239
  const maxDepth = 10;
5465
5240
  for (let i = 0;i < maxDepth; i++) {
5466
5241
  if (dir.endsWith(`node_modules/${packageDir}`)) {
5467
- const pkgPath = path5.join(dir, "package.json");
5468
- if (fs5.existsSync(pkgPath)) {
5242
+ const pkgPath = path6.join(dir, "package.json");
5243
+ if (fs6.existsSync(pkgPath)) {
5469
5244
  try {
5470
- return JSON.parse(fs5.readFileSync(pkgPath, "utf-8"));
5245
+ return JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
5471
5246
  } catch {
5472
5247
  return;
5473
5248
  }
5474
5249
  }
5475
5250
  }
5476
- const parent = path5.dirname(dir);
5251
+ const parent = path6.dirname(dir);
5477
5252
  if (parent === dir)
5478
5253
  break;
5479
5254
  dir = parent;
@@ -5918,7 +5693,7 @@ async function extract(options) {
5918
5693
  const verification = buildVerificationSummary(exportedSymbols.length, exports.length, exportTracker);
5919
5694
  const meta = await getPackageMeta(entryFile, baseDir);
5920
5695
  const types = ctx.typeRegistry.getAll();
5921
- const projectBaseDir = baseDir ?? path6.dirname(entryFile);
5696
+ const projectBaseDir = baseDir ?? path7.dirname(entryFile);
5922
5697
  const definedTypes = new Set(types.map((t) => t.id));
5923
5698
  const forgottenExports = collectForgottenExports(exports, types, program, sourceFile, exportedIds, projectBaseDir, definedTypes);
5924
5699
  for (const forgotten of forgottenExports) {
@@ -5951,7 +5726,7 @@ async function extract(options) {
5951
5726
  }
5952
5727
  let runtimeMetadata;
5953
5728
  if (options.schemaExtraction === "hybrid") {
5954
- const projectBaseDir2 = baseDir || path6.dirname(entryFile);
5729
+ const projectBaseDir2 = baseDir || path7.dirname(entryFile);
5955
5730
  const runtimeResult = await extractStandardSchemasFromProject(entryFile, projectBaseDir2, {
5956
5731
  target: options.schemaTarget || "draft-2020-12",
5957
5732
  timeout: 15000
@@ -6101,8 +5876,8 @@ function isExternalType2(definedIn, baseDir) {
6101
5876
  return true;
6102
5877
  if (definedIn.includes("node_modules"))
6103
5878
  return true;
6104
- const normalizedDefined = path6.resolve(definedIn);
6105
- const normalizedBase = path6.resolve(baseDir);
5879
+ const normalizedDefined = path7.resolve(definedIn);
5880
+ const normalizedBase = path7.resolve(baseDir);
6106
5881
  return !normalizedDefined.startsWith(normalizedBase);
6107
5882
  }
6108
5883
  function hasInternalTag(typeName, program, sourceFile) {
@@ -6404,7 +6179,7 @@ function createEmptySpec(entryFile, includeSchema, isDtsSource) {
6404
6179
  return {
6405
6180
  ...includeSchema ? { $schema: SCHEMA_URL } : {},
6406
6181
  openpkg: SCHEMA_VERSION,
6407
- meta: { name: path6.basename(entryFile, path6.extname(entryFile)) },
6182
+ meta: { name: path7.basename(entryFile, path7.extname(entryFile)) },
6408
6183
  exports: [],
6409
6184
  generation: {
6410
6185
  generator: "@openpkg-ts/sdk",
@@ -6417,19 +6192,19 @@ function createEmptySpec(entryFile, includeSchema, isDtsSource) {
6417
6192
  };
6418
6193
  }
6419
6194
  async function getPackageMeta(entryFile, baseDir) {
6420
- const searchDir = baseDir ?? path6.dirname(entryFile);
6421
- const pkgPath = path6.join(searchDir, "package.json");
6195
+ const searchDir = baseDir ?? path7.dirname(entryFile);
6196
+ const pkgPath = path7.join(searchDir, "package.json");
6422
6197
  try {
6423
- if (fs6.existsSync(pkgPath)) {
6424
- const pkg = JSON.parse(fs6.readFileSync(pkgPath, "utf-8"));
6198
+ if (fs7.existsSync(pkgPath)) {
6199
+ const pkg = JSON.parse(fs7.readFileSync(pkgPath, "utf-8"));
6425
6200
  return {
6426
- name: pkg.name ?? path6.basename(searchDir),
6201
+ name: pkg.name ?? path7.basename(searchDir),
6427
6202
  version: pkg.version,
6428
6203
  description: pkg.description
6429
6204
  };
6430
6205
  }
6431
6206
  } catch {}
6432
- return { name: path6.basename(searchDir) };
6207
+ return { name: path7.basename(searchDir) };
6433
6208
  }
6434
6209
 
6435
6210
  // src/primitives/spec.ts
@@ -6455,6 +6230,8 @@ export {
6455
6230
  typeboxAdapter,
6456
6231
  toSearchIndexJSON,
6457
6232
  toSearchIndex,
6233
+ toReactString,
6234
+ toReact,
6458
6235
  toPagefindRecords,
6459
6236
  toNavigation,
6460
6237
  toMarkdown,
@@ -6479,6 +6256,7 @@ export {
6479
6256
  registerReferencedTypes,
6480
6257
  registerAdapter,
6481
6258
  recommendSemverBump,
6259
+ query,
6482
6260
  normalizeType,
6483
6261
  normalizeSchema,
6484
6262
  normalizeMembers,
@@ -6547,6 +6325,7 @@ export {
6547
6325
  arktypeAdapter,
6548
6326
  analyzeSpec,
6549
6327
  TypeRegistry,
6328
+ QueryBuilder,
6550
6329
  CONFIG_FILENAME,
6551
6330
  BUILTIN_TYPE_SCHEMAS,
6552
6331
  ARRAY_PROTOTYPE_METHODS