@openpkg-ts/cli 0.6.0 → 0.6.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.
Files changed (2) hide show
  1. package/dist/bin/openpkg.js +59 -41
  2. package/package.json +4 -4
@@ -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.0",
12
+ version: "0.6.1",
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,14 +32,14 @@ var package_default = {
32
32
  test: "bun test"
33
33
  },
34
34
  dependencies: {
35
- "@openpkg-ts/adapters": "^0.3.3",
36
- "@openpkg-ts/sdk": "^0.34.0",
35
+ "@openpkg-ts/adapters": "^0.3.4",
36
+ "@openpkg-ts/sdk": "^0.34.1",
37
37
  commander: "^14.0.0"
38
38
  },
39
39
  devDependencies: {
40
40
  "@types/bun": "latest",
41
41
  "@types/node": "^20.0.0",
42
- bunup: "latest"
42
+ bunup: "^0.16.20"
43
43
  },
44
44
  publishConfig: {
45
45
  access: "public"
@@ -344,11 +344,15 @@ import * as path5 from "node:path";
344
344
  import { loadSpec as loadSpec4, query, toReact } from "@openpkg-ts/sdk";
345
345
  import { Command as Command5 } from "commander";
346
346
  async function readStdin() {
347
- const chunks = [];
348
- for await (const chunk of process.stdin) {
349
- chunks.push(chunk);
347
+ try {
348
+ const chunks = [];
349
+ for await (const chunk of process.stdin) {
350
+ chunks.push(chunk);
351
+ }
352
+ return Buffer.concat(chunks).toString("utf-8");
353
+ } catch (err) {
354
+ throw new Error(`stdin read failed: ${err instanceof Error ? err.message : String(err)}`);
350
355
  }
351
- return Buffer.concat(chunks).toString("utf-8");
352
356
  }
353
357
  function getExtension(format) {
354
358
  switch (format) {
@@ -511,8 +515,14 @@ Next: Add components with 'openpkg docs add function-section'`);
511
515
  }
512
516
  const exports = docs.getAllExports();
513
517
  for (const exp of exports) {
514
- const filename = `${exp.name}${getExtension(format)}`;
518
+ const filename = path5.basename(`${exp.name}${getExtension(format)}`);
515
519
  const filePath = path5.join(outDir, filename);
520
+ const resolvedPath = path5.resolve(filePath);
521
+ const resolvedOutDir = path5.resolve(outDir);
522
+ if (!resolvedPath.startsWith(resolvedOutDir + path5.sep)) {
523
+ console.error(JSON.stringify({ error: `Path traversal detected: ${exp.name}` }));
524
+ process.exit(1);
525
+ }
516
526
  const content = renderExport(docs, exp.id, format, collapseUnionThreshold);
517
527
  fs5.writeFileSync(filePath, content);
518
528
  }
@@ -687,8 +697,24 @@ var VALID_KINDS = [
687
697
  ];
688
698
  function loadSpec6(filePath) {
689
699
  const resolved = path8.resolve(filePath);
690
- const content = fs8.readFileSync(resolved, "utf-8");
691
- return JSON.parse(content);
700
+ let content;
701
+ let spec;
702
+ try {
703
+ content = fs8.readFileSync(resolved, "utf-8");
704
+ } catch (err) {
705
+ throw new Error(`Failed to read spec file: ${err instanceof Error ? err.message : String(err)}`);
706
+ }
707
+ try {
708
+ spec = JSON.parse(content);
709
+ } catch (err) {
710
+ throw new Error(`Invalid JSON in spec file: ${err instanceof Error ? err.message : String(err)}`);
711
+ }
712
+ const errors = getValidationErrors(spec);
713
+ if (errors.length > 0) {
714
+ const details = errors.slice(0, 5).map((e) => `${e.instancePath || "/"}: ${e.message}`).join("; ");
715
+ throw new Error(`Invalid OpenPkg spec: ${details}`);
716
+ }
717
+ return spec;
692
718
  }
693
719
  function parseList(val) {
694
720
  if (!val)
@@ -940,34 +966,26 @@ program.addCommand(createBreakingCommand());
940
966
  program.addCommand(createChangelogCommand());
941
967
  program.addCommand(createSemverCommand());
942
968
  var specCmd = program.commands.find((c) => c.name() === "spec");
943
- var snapshotAlias = new Command12("snapshot").description("(alias) → openpkg spec snapshot").allowUnknownOption().allowExcessArguments().action(async () => {
944
- const args = process.argv.slice(3);
945
- await specCmd.commands.find((c) => c.name() === "snapshot").parseAsync(args, { from: "user" });
946
- });
947
- program.addCommand(snapshotAlias);
948
- var listAlias = new Command12("list").description("(alias) → openpkg spec list").allowUnknownOption().allowExcessArguments().action(async () => {
949
- const args = process.argv.slice(3);
950
- await specCmd.commands.find((c) => c.name() === "list").parseAsync(args, { from: "user" });
951
- });
952
- program.addCommand(listAlias);
953
- var getAlias = new Command12("get").description("(alias) → openpkg spec get").allowUnknownOption().allowExcessArguments().action(async () => {
954
- const args = process.argv.slice(3);
955
- await specCmd.commands.find((c) => c.name() === "get").parseAsync(args, { from: "user" });
956
- });
957
- program.addCommand(getAlias);
958
- var validateAlias = new Command12("validate").description("(alias) → openpkg spec validate").allowUnknownOption().allowExcessArguments().action(async () => {
959
- const args = process.argv.slice(3);
960
- await specCmd.commands.find((c) => c.name() === "validate").parseAsync(args, { from: "user" });
961
- });
962
- program.addCommand(validateAlias);
963
- var filterAlias = new Command12("filter").description("(alias) → openpkg spec filter").allowUnknownOption().allowExcessArguments().action(async () => {
964
- const args = process.argv.slice(3);
965
- await specCmd.commands.find((c) => c.name() === "filter").parseAsync(args, { from: "user" });
966
- });
967
- program.addCommand(filterAlias);
968
- var diagnosticsAlias = new Command12("diagnostics").description("(alias) → openpkg spec lint").allowUnknownOption().allowExcessArguments().action(async () => {
969
- const args = process.argv.slice(3);
970
- await specCmd.commands.find((c) => c.name() === "lint").parseAsync(args, { from: "user" });
971
- });
972
- program.addCommand(diagnosticsAlias);
969
+ if (!specCmd) {
970
+ throw new Error("Internal error: spec command not found");
971
+ }
972
+ function getSubcommand(parent, name) {
973
+ const cmd = parent.commands.find((c) => c.name() === name);
974
+ if (!cmd) {
975
+ throw new Error(`Internal error: ${name} subcommand not found`);
976
+ }
977
+ return cmd;
978
+ }
979
+ function createAlias(aliasName, targetName, description) {
980
+ return new Command12(aliasName).description(description).allowUnknownOption().allowExcessArguments().action(async () => {
981
+ const args = process.argv.slice(3);
982
+ await getSubcommand(specCmd, targetName).parseAsync(args, { from: "user" });
983
+ });
984
+ }
985
+ program.addCommand(createAlias("snapshot", "snapshot", "(alias) → openpkg spec snapshot"));
986
+ program.addCommand(createAlias("list", "list", "(alias) openpkg spec list"));
987
+ program.addCommand(createAlias("get", "get", "(alias) → openpkg spec get"));
988
+ program.addCommand(createAlias("validate", "validate", "(alias) → openpkg spec validate"));
989
+ program.addCommand(createAlias("filter", "filter", "(alias) → openpkg spec filter"));
990
+ program.addCommand(createAlias("diagnostics", "lint", "(alias) → openpkg spec lint"));
973
991
  program.parse();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openpkg-ts/cli",
3
- "version": "0.6.0",
3
+ "version": "0.6.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,14 +23,14 @@
23
23
  "test": "bun test"
24
24
  },
25
25
  "dependencies": {
26
- "@openpkg-ts/adapters": "^0.3.3",
27
- "@openpkg-ts/sdk": "^0.34.0",
26
+ "@openpkg-ts/adapters": "^0.3.4",
27
+ "@openpkg-ts/sdk": "^0.34.1",
28
28
  "commander": "^14.0.0"
29
29
  },
30
30
  "devDependencies": {
31
31
  "@types/bun": "latest",
32
32
  "@types/node": "^20.0.0",
33
- "bunup": "latest"
33
+ "bunup": "^0.16.20"
34
34
  },
35
35
  "publishConfig": {
36
36
  "access": "public"