@openpkg-ts/cli 0.4.2 → 0.5.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.
@@ -11,7 +11,7 @@ import { Command as Command10 } from "commander";
11
11
  // package.json
12
12
  var package_default = {
13
13
  name: "@openpkg-ts/cli",
14
- version: "0.4.2",
14
+ version: "0.5.1",
15
15
  description: "CLI for OpenPkg TypeScript API extraction and documentation generation",
16
16
  homepage: "https://github.com/ryanwaits/openpkg-ts#readme",
17
17
  repository: {
@@ -34,8 +34,8 @@ var package_default = {
34
34
  test: "bun test"
35
35
  },
36
36
  dependencies: {
37
- "@openpkg-ts/adapters": "^0.3.1",
38
- "@openpkg-ts/sdk": "^0.32.1",
37
+ "@openpkg-ts/adapters": "^0.3.2",
38
+ "@openpkg-ts/sdk": "^0.33.1",
39
39
  commander: "^14.0.0"
40
40
  },
41
41
  devDependencies: {
@@ -264,18 +264,45 @@ function loadJSON(filePath) {
264
264
  return JSON.parse(content);
265
265
  }
266
266
  function createDiagnosticsCommand() {
267
- return new Command4("diagnostics").description("Analyze spec for quality issues (missing docs, deprecated without reason)").argument("<spec>", "Path to spec file (JSON)").action(async (specPath) => {
267
+ return new Command4("diagnostics").description("Analyze spec for quality issues (missing docs, deprecated without reason)").argument("<spec>", "Path to spec file (JSON)").option("--verbose", "Show detailed information including skipped export details").action(async (specPath, options) => {
268
268
  try {
269
269
  const spec = loadJSON(specPath);
270
270
  const diagnostics = analyzeSpec(spec);
271
+ const generation = spec.generation;
272
+ const skipped = generation?.skipped ?? [];
273
+ const externalExports = spec.exports.filter((e) => e.kind === "external");
274
+ const byReason = {};
275
+ for (const skip of skipped) {
276
+ byReason[skip.reason] = (byReason[skip.reason] ?? 0) + 1;
277
+ }
271
278
  const result = {
272
279
  summary: {
273
280
  total: diagnostics.missingDescriptions.length + diagnostics.deprecatedNoReason.length + diagnostics.missingParamDocs.length,
274
281
  missingDescriptions: diagnostics.missingDescriptions.length,
275
282
  deprecatedNoReason: diagnostics.deprecatedNoReason.length,
276
- missingParamDocs: diagnostics.missingParamDocs.length
283
+ missingParamDocs: diagnostics.missingParamDocs.length,
284
+ ...skipped.length > 0 && { skippedExports: skipped.length },
285
+ ...externalExports.length > 0 && { externalExports: externalExports.length }
286
+ },
287
+ diagnostics,
288
+ ...skipped.length > 0 && {
289
+ skippedExports: {
290
+ total: skipped.length,
291
+ byReason,
292
+ ...options.verbose && { details: skipped }
293
+ }
277
294
  },
278
- diagnostics
295
+ ...externalExports.length > 0 && {
296
+ externalExports: {
297
+ count: externalExports.length,
298
+ ...options.verbose && {
299
+ details: externalExports.map((e) => ({
300
+ name: e.name,
301
+ package: e.source?.package
302
+ }))
303
+ }
304
+ }
305
+ }
279
306
  };
280
307
  console.log(JSON.stringify(result, null, 2));
281
308
  process.exit(0);
@@ -562,7 +589,11 @@ function createSemverCommand() {
562
589
  // src/commands/snapshot.ts
563
590
  import * as fs8 from "node:fs";
564
591
  import * as path8 from "node:path";
565
- import { extractSpec } from "@openpkg-ts/sdk";
592
+ import {
593
+ extractSpec,
594
+ loadConfig,
595
+ mergeConfig
596
+ } from "@openpkg-ts/sdk";
566
597
  import { Command as Command8 } from "commander";
567
598
  function parseFilter(value) {
568
599
  if (!value)
@@ -579,8 +610,21 @@ function formatDiagnostics(diagnostics) {
579
610
  }));
580
611
  }
581
612
  function createSnapshotCommand() {
582
- return new Command8("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, use - for stdout)", "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, wildcards supported)").option("--ignore <exports>", "Ignore exports (comma-separated, wildcards supported)").option("--verify", "Exit 1 if any exports fail").option("--verbose", "Show detailed output including skipped exports").option("--include-private", "Include private/protected class members").action(async (entry, options) => {
613
+ return new Command8("snapshot").description(`Generate full OpenPkg spec from TypeScript entry point
614
+
615
+ ` + `Config: Reads from openpkg.config.json or package.json "openpkg" field.
616
+ ` + "CLI flags override config file settings.").argument("<entry>", "Entry point file path").option("-o, --output <file>", "Output file (default: openpkg.json, use - for stdout)", "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, wildcards supported)").option("--ignore <exports>", "Ignore exports (comma-separated, wildcards supported)").option("--verify", "Exit 1 if any exports fail").option("--verbose", "Show detailed output including skipped exports").option("--include-private", "Include private/protected class members").option("--external-include <patterns...>", "Resolve re-exports from these packages (globs supported)").option("--external-exclude <patterns...>", "Never resolve from these packages").option("--external-depth <n>", "Max transitive depth for external resolution (default: 1)", "1").action(async (entry, options) => {
583
617
  const entryFile = path8.resolve(entry);
618
+ const entryDir = path8.dirname(entryFile);
619
+ const fileConfig = loadConfig(entryDir);
620
+ const cliConfig = options.externalInclude ? {
621
+ externals: {
622
+ include: options.externalInclude,
623
+ exclude: options.externalExclude,
624
+ depth: parseInt(options.externalDepth ?? "1", 10)
625
+ }
626
+ } : {};
627
+ const mergedConfig = mergeConfig(fileConfig, cliConfig);
584
628
  const extractOptions = {
585
629
  entryFile,
586
630
  maxTypeDepth: parseInt(options.maxDepth ?? "4", 10),
@@ -588,10 +632,12 @@ function createSnapshotCommand() {
588
632
  schemaExtraction: options.runtime ? "hybrid" : "static",
589
633
  only: parseFilter(options.only),
590
634
  ignore: parseFilter(options.ignore),
591
- includePrivate: options.includePrivate
635
+ includePrivate: options.includePrivate,
636
+ ...mergedConfig.externals && { externals: mergedConfig.externals }
592
637
  };
593
638
  try {
594
639
  const result = await extractSpec(extractOptions);
640
+ const externalExports = result.spec.exports.filter((e) => e.kind === "external");
595
641
  const summary = {
596
642
  exports: result.spec.exports.length,
597
643
  types: result.spec.types?.length ?? 0,
@@ -607,6 +653,17 @@ function createSnapshotCommand() {
607
653
  }
608
654
  }
609
655
  },
656
+ ...externalExports.length > 0 && {
657
+ external: {
658
+ count: externalExports.length,
659
+ ...options.verbose && {
660
+ exports: externalExports.map((e) => ({
661
+ name: e.name,
662
+ package: e.source?.package
663
+ }))
664
+ }
665
+ }
666
+ },
610
667
  ...result.runtimeSchemas && {
611
668
  runtime: {
612
669
  extracted: result.runtimeSchemas.extracted,
@@ -616,6 +673,31 @@ function createSnapshotCommand() {
616
673
  }
617
674
  };
618
675
  console.error(JSON.stringify(summary, null, 2));
676
+ if (externalExports.length > 0 || (result.verification?.skipped ?? 0) > 0) {
677
+ console.error("");
678
+ if (externalExports.length > 0) {
679
+ if (options.verbose) {
680
+ console.error(`⚠ ${externalExports.length} external re-export(s) (install dependencies for full type info):`);
681
+ for (const exp of externalExports) {
682
+ console.error(` - ${exp.name} from "${exp.source?.package}"`);
683
+ }
684
+ } else {
685
+ console.error(`⚠ ${externalExports.length} external re-export(s) (install dependencies for full type info)`);
686
+ }
687
+ }
688
+ const skipped = result.verification?.details.skipped ?? [];
689
+ if (skipped.length > 0) {
690
+ if (options.verbose) {
691
+ console.error(`⚠ ${skipped.length} export(s) skipped:`);
692
+ for (const skip of skipped) {
693
+ const pkgInfo = skip.package ? ` from "${skip.package}"` : "";
694
+ console.error(` - ${skip.name} (${skip.reason})${pkgInfo}`);
695
+ }
696
+ } else {
697
+ console.error(`⚠ ${skipped.length} export(s) skipped (use --verbose for details)`);
698
+ }
699
+ }
700
+ }
619
701
  if (options.verify && result.verification && result.verification.failed > 0) {
620
702
  const errorOutput = {
621
703
  error: "Export verification failed",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/cli",
3
- "version": "0.4.2",
3
+ "version": "0.5.1",
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.1",
27
- "@openpkg-ts/sdk": "^0.32.1",
26
+ "@openpkg-ts/adapters": "^0.3.2",
27
+ "@openpkg-ts/sdk": "^0.33.1",
28
28
  "commander": "^14.0.0"
29
29
  },
30
30
  "devDependencies": {