@openpkg-ts/cli 0.6.1 → 0.6.2

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.
Files changed (2) hide show
  1. package/dist/bin/openpkg.js +79 -14
  2. package/package.json +3 -3
@@ -9,7 +9,7 @@ import { Command as Command12 } from "commander";
9
9
  // package.json
10
10
  var package_default = {
11
11
  name: "@openpkg-ts/cli",
12
- version: "0.6.1",
12
+ version: "0.6.2",
13
13
  description: "CLI for OpenPkg TypeScript API extraction and documentation generation",
14
14
  homepage: "https://github.com/ryanwaits/openpkg-ts#readme",
15
15
  repository: {
@@ -32,8 +32,8 @@ var package_default = {
32
32
  test: "bun test"
33
33
  },
34
34
  dependencies: {
35
- "@openpkg-ts/adapters": "^0.3.4",
36
- "@openpkg-ts/sdk": "^0.34.1",
35
+ "@openpkg-ts/adapters": "^0.3.5",
36
+ "@openpkg-ts/sdk": "^0.35.0",
37
37
  commander: "^14.0.0"
38
38
  },
39
39
  devDependencies: {
@@ -366,14 +366,33 @@ function getExtension(format) {
366
366
  return ".md";
367
367
  }
368
368
  }
369
+ var VALID_KINDS = [
370
+ "function",
371
+ "class",
372
+ "variable",
373
+ "interface",
374
+ "type",
375
+ "enum",
376
+ "module",
377
+ "namespace",
378
+ "reference",
379
+ "external"
380
+ ];
369
381
  function applyFilters(spec, options) {
370
382
  let qb = query(spec);
371
383
  if (options.kind) {
372
- const kinds = options.kind.split(",").map((k) => k.trim());
384
+ const kinds = options.kind.split(",").map((k) => k.trim()).filter(Boolean);
385
+ const invalid = kinds.filter((k) => !VALID_KINDS.includes(k));
386
+ if (invalid.length) {
387
+ throw new Error(`Invalid kind(s): ${invalid.join(", ")}. Valid: ${VALID_KINDS.join(", ")}`);
388
+ }
373
389
  qb = qb.byKind(...kinds);
374
390
  }
375
391
  if (options.tag) {
376
- const tags = options.tag.split(",").map((t) => t.trim());
392
+ const tags = options.tag.split(",").map((t) => t.trim()).filter(Boolean);
393
+ if (tags.length === 0) {
394
+ throw new Error("--tag requires at least one non-empty tag");
395
+ }
377
396
  qb = qb.byTag(...tags);
378
397
  }
379
398
  if (options.search) {
@@ -418,6 +437,13 @@ function createGenerateCommand() {
418
437
  return new Command5("generate").description("Generate documentation from OpenPkg spec").argument("<spec>", "Path to openpkg.json spec file (use - for stdin)").option("-o, --output <path>", "Output file or directory (default: stdout)").option("-f, --format <format>", "Output format: md, json, html, react (default: md)", "md").option("--split", "Output one file per export (requires --output as directory)").option("-e, --export <name>", "Generate docs for a single export by name").option("-a, --adapter <name>", "Use adapter for generation (default: raw)").option("--collapse-unions <n>", "Collapse unions with more than N members").option("-k, --kind <kinds>", "Filter by kind(s), comma-separated").option("-t, --tag <tags>", "Filter by tag(s), comma-separated").option("-s, --search <term>", "Search name and description").option("--deprecated", "Only include deprecated exports").option("--no-deprecated", "Exclude deprecated exports").option("--variant <variant>", "React layout variant: full (single page) or index (links)", "full").option("--components-path <path>", "React components import path", "@/components/api").action(async (specPath, options) => {
419
438
  const format = options.format || "md";
420
439
  try {
440
+ if (options.collapseUnions) {
441
+ const n = parseInt(options.collapseUnions, 10);
442
+ if (Number.isNaN(n) || n < 1) {
443
+ console.error(JSON.stringify({ error: "--collapse-unions must be a positive integer" }));
444
+ process.exit(1);
445
+ }
446
+ }
421
447
  if (options.adapter && options.adapter !== "raw") {
422
448
  let getAdapter;
423
449
  try {
@@ -440,14 +466,24 @@ function createGenerateCommand() {
440
466
  let spec2;
441
467
  if (specPath === "-") {
442
468
  const input = await readStdin();
443
- spec2 = JSON.parse(input);
469
+ try {
470
+ spec2 = JSON.parse(input);
471
+ } catch (err) {
472
+ const msg = err instanceof SyntaxError ? err.message : String(err);
473
+ throw new Error(`Invalid JSON in stdin: ${msg}`);
474
+ }
444
475
  } else {
445
476
  const specFile = path5.resolve(specPath);
446
477
  if (!fs5.existsSync(specFile)) {
447
478
  console.error(JSON.stringify({ error: `Spec file not found: ${specFile}` }));
448
479
  process.exit(1);
449
480
  }
450
- spec2 = JSON.parse(fs5.readFileSync(specFile, "utf-8"));
481
+ try {
482
+ spec2 = JSON.parse(fs5.readFileSync(specFile, "utf-8"));
483
+ } catch (err) {
484
+ const msg = err instanceof SyntaxError ? err.message : String(err);
485
+ throw new Error(`Invalid JSON in ${specPath}: ${msg}`);
486
+ }
451
487
  }
452
488
  spec2 = applyFilters(spec2, options);
453
489
  await adapter.generate(spec2, path5.resolve(options.output));
@@ -457,14 +493,24 @@ function createGenerateCommand() {
457
493
  let spec;
458
494
  if (specPath === "-") {
459
495
  const input = await readStdin();
460
- spec = JSON.parse(input);
496
+ try {
497
+ spec = JSON.parse(input);
498
+ } catch (err) {
499
+ const msg = err instanceof SyntaxError ? err.message : String(err);
500
+ throw new Error(`Invalid JSON in stdin: ${msg}`);
501
+ }
461
502
  } else {
462
503
  const specFile = path5.resolve(specPath);
463
504
  if (!fs5.existsSync(specFile)) {
464
505
  console.error(JSON.stringify({ error: `Spec file not found: ${specFile}` }));
465
506
  process.exit(1);
466
507
  }
467
- spec = JSON.parse(fs5.readFileSync(specFile, "utf-8"));
508
+ try {
509
+ spec = JSON.parse(fs5.readFileSync(specFile, "utf-8"));
510
+ } catch (err) {
511
+ const msg = err instanceof SyntaxError ? err.message : String(err);
512
+ throw new Error(`Invalid JSON in ${specPath}: ${msg}`);
513
+ }
468
514
  }
469
515
  spec = applyFilters(spec, options);
470
516
  const docs = loadSpec4(spec);
@@ -555,7 +601,11 @@ function loadComponentsJson() {
555
601
  const configPath = path6.resolve(COMPONENTS_JSON);
556
602
  if (!fs6.existsSync(configPath))
557
603
  return null;
558
- return JSON.parse(fs6.readFileSync(configPath, "utf-8"));
604
+ try {
605
+ return JSON.parse(fs6.readFileSync(configPath, "utf-8"));
606
+ } catch {
607
+ return null;
608
+ }
559
609
  }
560
610
  function createInitCommand() {
561
611
  return new Command6("init").description("Add @openpkg registry to components.json for shadcn CLI").option("--registry <url>", "Custom registry URL", REGISTRY_URL).action(async (options) => {
@@ -683,7 +733,7 @@ import {
683
733
  } from "@openpkg-ts/sdk";
684
734
  import { getValidationErrors } from "@openpkg-ts/spec";
685
735
  import { Command as Command11 } from "commander";
686
- var VALID_KINDS = [
736
+ var VALID_KINDS2 = [
687
737
  "function",
688
738
  "class",
689
739
  "variable",
@@ -722,9 +772,9 @@ function parseList(val) {
722
772
  return val.split(",").map((s) => s.trim()).filter(Boolean);
723
773
  }
724
774
  function validateKinds(kinds) {
725
- const invalid = kinds.filter((k) => !VALID_KINDS.includes(k));
775
+ const invalid = kinds.filter((k) => !VALID_KINDS2.includes(k));
726
776
  if (invalid.length > 0) {
727
- throw new Error(`Invalid kind(s): ${invalid.join(", ")}. Valid kinds: ${VALID_KINDS.join(", ")}`);
777
+ throw new Error(`Invalid kind(s): ${invalid.join(", ")}. Valid kinds: ${VALID_KINDS2.join(", ")}`);
728
778
  }
729
779
  return kinds;
730
780
  }
@@ -738,7 +788,7 @@ function formatDiagnostics(diagnostics) {
738
788
  }));
739
789
  }
740
790
  function createSnapshotSubcommand() {
741
- return new Command11("snapshot").description("Generate full OpenPkg spec from TypeScript entry point").argument("<entry>", "Entry point file path").option("-o, --output <file>", "Output file (default: openpkg.json)", "openpkg.json").option("--max-depth <n>", "Max type depth (default: 4)", "4").option("--skip-resolve", "Skip external type resolution").option("--runtime", "Enable Standard Schema runtime extraction").option("--only <exports>", "Filter exports (comma-separated)").option("--ignore <exports>", "Ignore exports (comma-separated)").option("--verify", "Exit 1 if any exports fail").option("--verbose", "Show detailed output").option("--include-private", "Include private/protected class members").option("--external-include <patterns...>", "Resolve re-exports from these packages").option("--external-exclude <patterns...>", "Never resolve from these packages").option("--external-depth <n>", "Max transitive depth for external resolution", "1").action(async (entry, options) => {
791
+ return new Command11("snapshot").description("Generate full OpenPkg spec from TypeScript entry point").argument("<entry>", "Entry point file path").option("-o, --output <file>", "Output file (default: openpkg.json)", "openpkg.json").option("--max-depth <n>", "Max type depth (default: 4)", "4").option("--skip-resolve", "Skip external type resolution").option("--runtime", "Enable Standard Schema runtime extraction").option("--only <exports>", "Filter exports (comma-separated)").option("--ignore <exports>", "Ignore exports (comma-separated)").option("--verify", "Exit 1 if any exports fail").option("--verbose", "Show detailed output").option("--quiet", "Suppress extraction warnings").option("--strict", "Exit 1 if any extraction warnings").option("--include-private", "Include private/protected class members").option("--external-include <patterns...>", "Resolve re-exports from these packages").option("--external-exclude <patterns...>", "Never resolve from these packages").option("--external-depth <n>", "Max transitive depth for external resolution", "1").action(async (entry, options) => {
742
792
  const entryFile = path8.resolve(entry);
743
793
  const entryDir = path8.dirname(entryFile);
744
794
  const fileConfig = loadConfig(entryDir);
@@ -781,6 +831,21 @@ function createSnapshotSubcommand() {
781
831
  ...externalExports.length > 0 && { external: { count: externalExports.length } }
782
832
  };
783
833
  console.error(JSON.stringify(summary, null, 2));
834
+ const extractionWarnings = result.runtimeSchemas?.warnings ?? [];
835
+ if (extractionWarnings.length > 0 && !options.quiet) {
836
+ console.error(`
837
+ Skipped ${extractionWarnings.length} schema(s) with extraction errors:`);
838
+ for (const w of extractionWarnings) {
839
+ console.error(` - ${w.exportName ?? "unknown"}: ${w.code} - ${w.message}`);
840
+ }
841
+ }
842
+ if (options.strict && extractionWarnings.length > 0) {
843
+ console.error(JSON.stringify({
844
+ error: "Extraction warnings present (--strict mode)",
845
+ warnings: extractionWarnings
846
+ }, null, 2));
847
+ process.exit(1);
848
+ }
784
849
  if (options.verify && result.verification && result.verification.failed > 0) {
785
850
  console.error(JSON.stringify({
786
851
  error: "Export verification failed",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/cli",
3
- "version": "0.6.1",
3
+ "version": "0.6.2",
4
4
  "description": "CLI for OpenPkg TypeScript API extraction and documentation generation",
5
5
  "homepage": "https://github.com/ryanwaits/openpkg-ts#readme",
6
6
  "repository": {
@@ -23,8 +23,8 @@
23
23
  "test": "bun test"
24
24
  },
25
25
  "dependencies": {
26
- "@openpkg-ts/adapters": "^0.3.4",
27
- "@openpkg-ts/sdk": "^0.34.1",
26
+ "@openpkg-ts/adapters": "^0.3.5",
27
+ "@openpkg-ts/sdk": "^0.35.0",
28
28
  "commander": "^14.0.0"
29
29
  },
30
30
  "devDependencies": {