@openpkg-ts/sdk 0.55.0 → 0.55.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/sdk",
3
- "version": "0.55.0",
3
+ "version": "0.55.1",
4
4
  "description": "TypeScript API extraction SDK - programmatic primitives for OpenPkg specs",
5
5
  "keywords": [
6
6
  "openpkg",
@@ -1,519 +0,0 @@
1
- // src/core/format.ts
2
- function getMemberBadges(member) {
3
- const badges = [];
4
- const visibility = member.visibility ?? "public";
5
- if (visibility !== "public") {
6
- badges.push(visibility);
7
- }
8
- const flags = member.flags;
9
- if (flags?.static)
10
- badges.push("static");
11
- if (flags?.readonly)
12
- badges.push("readonly");
13
- if (flags?.async)
14
- badges.push("async");
15
- if (flags?.abstract)
16
- badges.push("abstract");
17
- return badges;
18
- }
19
- function formatBadges(badges) {
20
- return badges.join(" ");
21
- }
22
-
23
- // src/core/query.ts
24
- import {
25
- DISPLAY_KIND_ORDER
26
- } from "@openpkg-ts/spec";
27
- function formatFunctionSchema(schema) {
28
- const sigs = schema["x-ts-signatures"];
29
- if (!sigs?.length)
30
- return "(...args: unknown[]) => unknown";
31
- const sig = sigs[0];
32
- const params = formatParameters(sig);
33
- const ret = sig.returns ? formatSchema(sig.returns.schema) : "void";
34
- return `${params} => ${ret}`;
35
- }
36
- function formatSchema(schema, options) {
37
- if (!schema)
38
- return "unknown";
39
- if (typeof schema === "string")
40
- return schema;
41
- const depth = options?._depth ?? 0;
42
- const maxDepth = options?.maxDepth ?? 3;
43
- if (depth >= maxDepth)
44
- return "...";
45
- const nextOpts = { ...options, _depth: depth + 1 };
46
- const withPackage = (typeStr) => {
47
- if (options?.includePackage && typeof schema === "object" && "x-ts-package" in schema) {
48
- const pkg = schema["x-ts-package"];
49
- return `${typeStr} (from ${pkg})`;
50
- }
51
- return typeStr;
52
- };
53
- if (typeof schema === "object" && schema !== null) {
54
- if ("x-ts-type" in schema && typeof schema["x-ts-type"] === "string") {
55
- const tsType = schema["x-ts-type"];
56
- if (tsType === "function" || schema["x-ts-function"]) {
57
- return withPackage(formatFunctionSchema(schema));
58
- }
59
- return withPackage(tsType);
60
- }
61
- if ("x-ts-function" in schema && schema["x-ts-function"]) {
62
- return withPackage(formatFunctionSchema(schema));
63
- }
64
- if ("x-ts-type-predicate" in schema) {
65
- const pred = schema["x-ts-type-predicate"];
66
- return `${pred.parameterName} is ${formatSchema(pred.type, nextOpts)}`;
67
- }
68
- if ("$ref" in schema && typeof schema.$ref === "string") {
69
- const baseName = schema.$ref.replace("#/types/", "");
70
- if ("x-ts-type-arguments" in schema && Array.isArray(schema["x-ts-type-arguments"])) {
71
- const args = schema["x-ts-type-arguments"].map((s) => formatSchema(s, nextOpts)).join(", ");
72
- return withPackage(`${baseName}<${args}>`);
73
- }
74
- return withPackage(baseName);
75
- }
76
- if ("anyOf" in schema && Array.isArray(schema.anyOf)) {
77
- const threshold = options?.collapseUnionThreshold ?? 5;
78
- const members = schema.anyOf;
79
- if (members.length > threshold) {
80
- const shown = members.slice(0, 3);
81
- const remaining = members.length - 3;
82
- const shownStr = shown.map((s) => formatSchema(s, nextOpts)).join(" | ");
83
- return `${shownStr} | ... and ${remaining} more`;
84
- }
85
- return members.map((s) => formatSchema(s, nextOpts)).join(" | ");
86
- }
87
- if ("allOf" in schema && Array.isArray(schema.allOf)) {
88
- return schema.allOf.map((s) => formatSchema(s, nextOpts)).join(" & ");
89
- }
90
- if ("type" in schema && schema.type === "array") {
91
- const items = "items" in schema ? formatSchema(schema.items, nextOpts) : "unknown";
92
- return `${items}[]`;
93
- }
94
- if ("type" in schema && schema.type === "tuple" && "items" in schema) {
95
- const items = schema.items.map((s) => formatSchema(s, nextOpts)).join(", ");
96
- return `[${items}]`;
97
- }
98
- if ("type" in schema && schema.type === "object") {
99
- if ("properties" in schema && schema.properties) {
100
- const required = new Set(Array.isArray(schema.required) ? schema.required : []);
101
- const props = Object.entries(schema.properties).map(([k, v]) => `${k}${required.has(k) ? "" : "?"}: ${formatSchema(v, nextOpts)}`).join("; ");
102
- return `{ ${props} }`;
103
- }
104
- return "object";
105
- }
106
- if ("const" in schema && schema.const !== undefined) {
107
- const v = schema.const;
108
- return withPackage(typeof v === "string" ? `"${v}"` : String(v));
109
- }
110
- if ("enum" in schema && Array.isArray(schema.enum)) {
111
- const vals = schema.enum.map((v) => typeof v === "string" ? `"${v}"` : String(v));
112
- return withPackage(vals.join(" | "));
113
- }
114
- if ("type" in schema && typeof schema.type === "string") {
115
- return withPackage(schema.type);
116
- }
117
- }
118
- return "unknown";
119
- }
120
- function formatTypeParameters(typeParams) {
121
- if (!typeParams?.length)
122
- return "";
123
- const params = typeParams.map((tp) => {
124
- let str = "";
125
- if ("const" in tp && tp.const)
126
- str += "const ";
127
- if (tp.variance === "in")
128
- str += "in ";
129
- else if (tp.variance === "out")
130
- str += "out ";
131
- else if (tp.variance === "inout")
132
- str += "in out ";
133
- str += tp.name;
134
- if (tp.constraint)
135
- str += ` extends ${tp.constraint}`;
136
- if (tp.default)
137
- str += ` = ${tp.default}`;
138
- return str;
139
- });
140
- return `<${params.join(", ")}>`;
141
- }
142
- function formatParameters(sig) {
143
- if (!sig?.parameters?.length)
144
- return "()";
145
- const params = sig.parameters.map((p) => {
146
- const optional = p.required === false ? "?" : "";
147
- const rest = p.rest ? "..." : "";
148
- const type = formatSchema(p.schema);
149
- return `${rest}${p.name}${optional}: ${type}`;
150
- });
151
- return `(${params.join(", ")})`;
152
- }
153
- function formatReturnType(sig) {
154
- if (!sig?.returns)
155
- return "void";
156
- return formatSchema(sig.returns.schema);
157
- }
158
- function buildSignatureString(exp, sigIndex = 0) {
159
- const sig = exp.signatures?.[sigIndex];
160
- const typeParams = formatTypeParameters(exp.typeParameters || sig?.typeParameters);
161
- switch (exp.kind) {
162
- case "function": {
163
- const params = formatParameters(sig);
164
- const returnType = formatReturnType(sig);
165
- return `function ${exp.name}${typeParams}${params}: ${returnType}`;
166
- }
167
- case "class": {
168
- const ext = exp.extends ? ` extends ${exp.extends}` : "";
169
- const impl = exp.implements?.length ? ` implements ${exp.implements.join(", ")}` : "";
170
- return `class ${exp.name}${typeParams}${ext}${impl}`;
171
- }
172
- case "interface": {
173
- const ext = exp.extends ? ` extends ${exp.extends}` : "";
174
- return `interface ${exp.name}${typeParams}${ext}`;
175
- }
176
- case "type": {
177
- const typeValue = typeof exp.type === "string" ? exp.type : formatSchema(exp.schema);
178
- return `type ${exp.name}${typeParams} = ${typeValue}`;
179
- }
180
- case "enum": {
181
- return `enum ${exp.name}`;
182
- }
183
- case "variable": {
184
- const typeValue = typeof exp.type === "string" ? exp.type : formatSchema(exp.schema);
185
- return `const ${exp.name}: ${typeValue}`;
186
- }
187
- default:
188
- return exp.name;
189
- }
190
- }
191
- function resolveTypeRef(ref, spec) {
192
- const id = ref.replace("#/types/", "");
193
- return spec.types?.find((t) => t.id === id);
194
- }
195
- function isMethod(member) {
196
- return !!member.signatures?.length;
197
- }
198
- function isProperty(member) {
199
- return !member.signatures?.length;
200
- }
201
- function getMethods(members) {
202
- return members?.filter(isMethod) ?? [];
203
- }
204
- function getProperties(members) {
205
- return members?.filter(isProperty) ?? [];
206
- }
207
- function groupByVisibility(members) {
208
- const groups = {
209
- public: [],
210
- protected: [],
211
- private: []
212
- };
213
- for (const member of members ?? []) {
214
- const visibility = member.visibility ?? "public";
215
- groups[visibility].push(member);
216
- }
217
- return groups;
218
- }
219
- function sortByName(items) {
220
- return [...items].sort((a, b) => a.name.localeCompare(b.name));
221
- }
222
- var KIND_ORDER = [
223
- ...DISPLAY_KIND_ORDER,
224
- "namespace",
225
- "module",
226
- "reference",
227
- "external"
228
- ];
229
- function groupByKind(items) {
230
- const groups = {};
231
- for (const item of items) {
232
- if (!groups[item.kind])
233
- groups[item.kind] = [];
234
- groups[item.kind].push(item);
235
- }
236
- return groups;
237
- }
238
- function formatConditionalType(condType) {
239
- const check = formatSchema(condType.checkType);
240
- const ext = formatSchema(condType.extendsType);
241
- const trueT = formatSchema(condType.trueType);
242
- const falseT = formatSchema(condType.falseType);
243
- return `${check} extends ${ext} ? ${trueT} : ${falseT}`;
244
- }
245
- function formatMappedType(mappedType) {
246
- const keyStr = formatSchema(mappedType.keyType);
247
- const valueStr = formatSchema(mappedType.valueType);
248
- let readonlyMod = "";
249
- if (mappedType.readonly === true || mappedType.readonly === "add") {
250
- readonlyMod = "readonly ";
251
- } else if (mappedType.readonly === "remove") {
252
- readonlyMod = "-readonly ";
253
- }
254
- let optionalMod = "";
255
- if (mappedType.optional === true || mappedType.optional === "add") {
256
- optionalMod = "?";
257
- } else if (mappedType.optional === "remove") {
258
- optionalMod = "-?";
259
- }
260
- return `{ ${readonlyMod}[${keyStr}]${optionalMod}: ${valueStr} }`;
261
- }
262
- function findExport(spec, name) {
263
- const exp = spec.exports.find((e) => e.name === name || e.id === name);
264
- if (!exp)
265
- throw new Error(`Export not found: ${name}`);
266
- return exp;
267
- }
268
- function filterExports(spec, names) {
269
- const ids = new Set(names);
270
- return spec.exports.filter((e) => ids.has(e.name) || ids.has(e.id));
271
- }
272
-
273
- // src/core/search.ts
274
- import { KIND_LABELS } from "@openpkg-ts/spec";
275
- var defaultSlugify = (name) => name.toLowerCase().replace(/[^a-z0-9]+/g, "-");
276
- function extractKeywords(exp, options = {}) {
277
- const keywords = new Set;
278
- keywords.add(exp.name);
279
- keywords.add(exp.name.toLowerCase());
280
- const camelParts = exp.name.split(/(?=[A-Z])/);
281
- for (const part of camelParts) {
282
- if (part.length > 2)
283
- keywords.add(part.toLowerCase());
284
- }
285
- if (exp.tags) {
286
- for (const tag of exp.tags) {
287
- keywords.add(tag.name.replace("@", ""));
288
- const tagWords = tag.text.split(/\s+/);
289
- for (const word of tagWords) {
290
- if (word.length > 2)
291
- keywords.add(word.toLowerCase());
292
- }
293
- }
294
- }
295
- if (exp.description) {
296
- const descWords = exp.description.toLowerCase().split(/\W+/).filter((w) => w.length > 2);
297
- for (const word of descWords) {
298
- keywords.add(word);
299
- }
300
- }
301
- if (options.includeMembers && exp.members) {
302
- for (const member of exp.members) {
303
- if (member.name) {
304
- keywords.add(member.name.toLowerCase());
305
- }
306
- }
307
- }
308
- if (options.includeParameters && exp.signatures) {
309
- for (const sig of exp.signatures) {
310
- for (const param of sig.parameters || []) {
311
- keywords.add(param.name.toLowerCase());
312
- }
313
- }
314
- }
315
- return Array.from(keywords);
316
- }
317
- function buildContent(exp, options = {}) {
318
- const parts = [];
319
- parts.push(exp.name);
320
- if (exp.description) {
321
- parts.push(exp.description);
322
- }
323
- if (options.includeSignatures !== false) {
324
- parts.push(buildSignatureString(exp));
325
- }
326
- if (exp.tags) {
327
- parts.push(...exp.tags.map((t) => `${t.name} ${t.text}`));
328
- }
329
- if (options.includeMembers !== false && exp.members) {
330
- const props = getProperties(exp.members);
331
- const methods = getMethods(exp.members);
332
- for (const prop of props) {
333
- if (prop.name) {
334
- parts.push(prop.name);
335
- if (prop.description)
336
- parts.push(prop.description);
337
- }
338
- }
339
- for (const method of methods) {
340
- if (method.name) {
341
- parts.push(method.name);
342
- if (method.description)
343
- parts.push(method.description);
344
- }
345
- }
346
- }
347
- if (options.includeParameters !== false && exp.signatures) {
348
- for (const sig of exp.signatures) {
349
- for (const param of sig.parameters || []) {
350
- parts.push(param.name);
351
- if (param.description)
352
- parts.push(param.description);
353
- }
354
- }
355
- }
356
- return parts.join(" ");
357
- }
358
- function createSearchRecord(exp, options = {}) {
359
- const { baseUrl = "/api", slugify = defaultSlugify } = options;
360
- return {
361
- id: exp.id,
362
- name: exp.name,
363
- kind: exp.kind,
364
- signature: buildSignatureString(exp),
365
- description: exp.description,
366
- content: buildContent(exp, options),
367
- keywords: extractKeywords(exp, options),
368
- url: `${baseUrl}/${slugify(exp.name)}`,
369
- deprecated: exp.deprecated === true
370
- };
371
- }
372
- function toSearchIndex(spec, options = {}) {
373
- const records = spec.exports.map((exp) => createSearchRecord(exp, options));
374
- return {
375
- records,
376
- version: spec.meta.version || "0.0.0",
377
- generatedAt: new Date().toISOString(),
378
- packageName: spec.meta.name
379
- };
380
- }
381
- function toPagefindRecords(spec, options = {}) {
382
- const { baseUrl = "/api", slugify = defaultSlugify, weights = {} } = options;
383
- const { name: nameWeight = 10, description: descWeight = 5, signature: sigWeight = 3 } = weights;
384
- return spec.exports.map((exp) => {
385
- const content = buildContent(exp, options);
386
- const signature = buildSignatureString(exp);
387
- const filters = {
388
- kind: [exp.kind]
389
- };
390
- if (exp.deprecated) {
391
- filters.deprecated = ["true"];
392
- }
393
- if (exp.tags?.length) {
394
- filters.tags = exp.tags.map((t) => t.name.replace("@", ""));
395
- }
396
- return {
397
- url: `${baseUrl}/${slugify(exp.name)}`,
398
- content,
399
- word_count: content.split(/\s+/).length,
400
- filters,
401
- meta: {
402
- title: exp.name,
403
- kind: exp.kind,
404
- description: exp.description?.slice(0, 160),
405
- signature
406
- },
407
- weighted_sections: [
408
- { weight: nameWeight, text: exp.name },
409
- ...exp.description ? [{ weight: descWeight, text: exp.description }] : [],
410
- { weight: sigWeight, text: signature }
411
- ]
412
- };
413
- });
414
- }
415
- function toAlgoliaRecords(spec, options = {}) {
416
- const { baseUrl = "/api", slugify = defaultSlugify } = options;
417
- return spec.exports.map((exp) => ({
418
- objectID: exp.id,
419
- name: exp.name,
420
- kind: exp.kind,
421
- description: exp.description,
422
- signature: buildSignatureString(exp),
423
- content: buildContent(exp, options),
424
- tags: (exp.tags || []).map((t) => t.name.replace("@", "")),
425
- deprecated: exp.deprecated === true,
426
- url: `${baseUrl}/${slugify(exp.name)}`,
427
- hierarchy: {
428
- lvl0: spec.meta.name,
429
- lvl1: KIND_LABELS[exp.kind],
430
- lvl2: exp.name
431
- }
432
- }));
433
- }
434
- function toSearchIndexJSON(spec, options = {}) {
435
- const index = toSearchIndex(spec, options);
436
- return options.pretty ? JSON.stringify(index, null, 2) : JSON.stringify(index);
437
- }
438
-
439
- // src/core/query-builder.ts
440
- class QueryBuilder {
441
- spec;
442
- predicates = [];
443
- constructor(spec) {
444
- this.spec = spec;
445
- }
446
- byKind(...kinds) {
447
- if (kinds.length > 0) {
448
- this.predicates.push((exp) => kinds.includes(exp.kind));
449
- }
450
- return this;
451
- }
452
- byName(pattern) {
453
- if (typeof pattern === "string") {
454
- this.predicates.push((exp) => exp.name === pattern);
455
- } else {
456
- this.predicates.push((exp) => pattern.test(exp.name));
457
- }
458
- return this;
459
- }
460
- byTag(...tags) {
461
- if (tags.length > 0) {
462
- this.predicates.push((exp) => {
463
- const expTags = exp.tags?.map((t) => t.name) ?? [];
464
- return tags.some((tag) => expTags.includes(tag));
465
- });
466
- }
467
- return this;
468
- }
469
- deprecated(include) {
470
- if (include !== undefined) {
471
- this.predicates.push((exp) => (exp.deprecated ?? false) === include);
472
- }
473
- return this;
474
- }
475
- withDescription() {
476
- this.predicates.push((exp) => Boolean(exp.description?.trim()));
477
- return this;
478
- }
479
- search(term) {
480
- const lower = term.toLowerCase();
481
- this.predicates.push((exp) => exp.name.toLowerCase().includes(lower) || (exp.description?.toLowerCase().includes(lower) ?? false));
482
- return this;
483
- }
484
- where(predicate) {
485
- this.predicates.push(predicate);
486
- return this;
487
- }
488
- byModule(modulePath) {
489
- this.predicates.push((exp) => exp.source?.file?.includes(modulePath) ?? false);
490
- return this;
491
- }
492
- matches(exp) {
493
- return this.predicates.every((p) => p(exp));
494
- }
495
- find() {
496
- return this.spec.exports.filter((exp) => this.matches(exp));
497
- }
498
- first() {
499
- return this.spec.exports.find((exp) => this.matches(exp));
500
- }
501
- count() {
502
- return this.spec.exports.filter((exp) => this.matches(exp)).length;
503
- }
504
- ids() {
505
- return this.find().map((exp) => exp.id);
506
- }
507
- toSpec() {
508
- return {
509
- ...this.spec,
510
- exports: this.find(),
511
- types: this.spec.types ? [...this.spec.types] : undefined
512
- };
513
- }
514
- }
515
- function query(spec) {
516
- return new QueryBuilder(spec);
517
- }
518
-
519
- export { getMemberBadges, formatBadges, formatSchema, formatTypeParameters, formatParameters, formatReturnType, buildSignatureString, resolveTypeRef, isMethod, isProperty, getMethods, getProperties, groupByVisibility, sortByName, KIND_ORDER, groupByKind, formatConditionalType, formatMappedType, findExport, filterExports, toSearchIndex, toPagefindRecords, toAlgoliaRecords, toSearchIndexJSON, QueryBuilder, query };