@pagepocket/cli 0.10.1 → 0.11.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 (49) hide show
  1. package/dist/commands/archive.js +146 -76
  2. package/dist/commands/plugin/add.js +19 -25
  3. package/dist/commands/plugin/doctor.js +22 -28
  4. package/dist/commands/plugin/ls.js +16 -22
  5. package/dist/commands/plugin/prune.js +13 -19
  6. package/dist/commands/plugin/remove.js +16 -22
  7. package/dist/commands/plugin/set.js +13 -19
  8. package/dist/commands/plugin/uninstall.js +29 -35
  9. package/dist/commands/plugin/update.js +22 -28
  10. package/dist/commands/strategy/add.js +14 -20
  11. package/dist/commands/strategy/doctor.js +11 -17
  12. package/dist/commands/strategy/ls.js +22 -0
  13. package/dist/commands/strategy/pin.js +10 -16
  14. package/dist/commands/strategy/remove.js +10 -16
  15. package/dist/commands/strategy/update.js +21 -27
  16. package/dist/commands/view.js +36 -42
  17. package/dist/index.js +9 -7
  18. package/dist/lib/filename.js +1 -5
  19. package/dist/services/config-service.js +24 -30
  20. package/dist/services/load-configured-plugins.js +8 -12
  21. package/dist/services/plugin-installer.js +6 -12
  22. package/dist/services/plugin-store.js +27 -68
  23. package/dist/services/strategy/builtin-strategy-registry.js +23 -0
  24. package/dist/services/strategy/strategy-analyze.js +10 -20
  25. package/dist/services/strategy/strategy-config.js +6 -13
  26. package/dist/services/strategy/strategy-fetch.js +11 -18
  27. package/dist/services/strategy/strategy-io.js +15 -25
  28. package/dist/services/strategy/strategy-normalize.js +4 -8
  29. package/dist/services/strategy/strategy-pack-read.js +10 -17
  30. package/dist/services/strategy/strategy-pack-store.js +12 -18
  31. package/dist/services/strategy/strategy-service.js +79 -82
  32. package/dist/services/strategy/types.js +1 -2
  33. package/dist/services/units/unit-store.js +16 -20
  34. package/dist/services/units/unit-validate.js +20 -5
  35. package/dist/services/user-packages/parse-pinned-spec.js +6 -6
  36. package/dist/services/user-packages/user-package-installer.js +4 -9
  37. package/dist/services/user-packages/user-package-store.js +19 -57
  38. package/dist/stages/prepare-output.js +6 -13
  39. package/dist/units/network-observer-unit.js +7 -10
  40. package/dist/utils/array.js +3 -0
  41. package/dist/utils/normalize-argv.js +3 -8
  42. package/dist/utils/parse-json.js +1 -5
  43. package/dist/utils/parse-plugin-options.js +1 -5
  44. package/dist/utils/parse-plugin-spec.js +6 -6
  45. package/dist/utils/validate-plugin-default-export.js +1 -5
  46. package/dist/utils/with-spinner.js +3 -10
  47. package/dist/view.js +12 -19
  48. package/package.json +12 -11
  49. package/dist/services/strategy/read-installed-package-version.js +0 -28
@@ -1,28 +1,71 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
1
+ import { createRequire } from "node:module";
2
+ import { pathToFileURL } from "node:url";
3
+ import { Args, Command, Flags } from "@oclif/core";
4
+ import { ga, ns, PagePocket } from "@pagepocket/lib";
5
+ import chalk from "chalk";
6
+ import { loadConfiguredPlugins } from "../services/load-configured-plugins.js";
7
+ import { ConfigService } from "../services/config-service.js";
8
+ import { readBuiltinStrategy, listBuiltinStrategyNames } from "../services/strategy/builtin-strategy-registry.js";
9
+ import { StrategyService } from "../services/strategy/strategy-service.js";
10
+ import { normalizeStrategyUnits } from "../services/strategy/strategy-normalize.js";
11
+ import { parsePinnedSpec } from "../services/user-packages/parse-pinned-spec.js";
12
+ import { isUnitLike, resolveUnitConstructor } from "../services/units/unit-validate.js";
13
+ import { UnitStore } from "../services/units/unit-store.js";
14
+ import { uniq } from "../utils/array.js";
15
+ import { withSpinner } from "../utils/with-spinner.js";
16
+ const buildMissingStrategyError = (input) => {
17
+ const available = uniq([...input.installedNames, ...listBuiltinStrategyNames()])
18
+ .filter((name) => name.trim().length > 0)
19
+ .sort((left, right) => left.localeCompare(right));
20
+ const suffix = available.length > 0
21
+ ? ` Available strategies: ${available.join(", ")}`
22
+ : " No strategies found.";
23
+ return new Error(`Strategy not found: ${input.strategyName}.${suffix}`);
4
24
  };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const core_1 = require("@oclif/core");
7
- const lib_1 = require("@pagepocket/lib");
8
- const chalk_1 = __importDefault(require("chalk"));
9
- const load_configured_plugins_1 = require("../services/load-configured-plugins");
10
- const config_service_1 = require("../services/config-service");
11
- const read_installed_package_version_1 = require("../services/strategy/read-installed-package-version");
12
- const strategy_service_1 = require("../services/strategy/strategy-service");
13
- const strategy_normalize_1 = require("../services/strategy/strategy-normalize");
14
- const parse_pinned_spec_1 = require("../services/user-packages/parse-pinned-spec");
15
- const unit_store_1 = require("../services/units/unit-store");
16
- const with_spinner_1 = require("../utils/with-spinner");
17
- const loadStrategyUnits = async (input) => {
18
- const strategyService = new strategy_service_1.StrategyService(input.configService);
19
- const unitStore = new unit_store_1.UnitStore(input.configService);
25
+ const resolveStrategy = (input) => {
26
+ const installedNames = input.strategyService.listInstalledStrategyNames();
27
+ if (installedNames.includes(input.strategyName)) {
28
+ return {
29
+ name: input.strategyName,
30
+ strategyFile: input.strategyService.readStrategy(input.strategyName),
31
+ source: "installed"
32
+ };
33
+ }
34
+ const builtin = readBuiltinStrategy(input.strategyName);
35
+ if (builtin) {
36
+ return {
37
+ name: input.strategyName,
38
+ strategyFile: builtin,
39
+ source: "builtin"
40
+ };
41
+ }
42
+ throw buildMissingStrategyError({
43
+ strategyName: input.strategyName,
44
+ installedNames
45
+ });
46
+ };
47
+ const assertNoDuplicateUnitIds = (input) => {
48
+ const seen = new Set();
49
+ const dup = input.units.find((u) => {
50
+ if (seen.has(u.id)) {
51
+ return true;
52
+ }
53
+ seen.add(u.id);
54
+ return false;
55
+ });
56
+ if (dup) {
57
+ throw new Error(`Duplicate unit id detected in strategy ${input.strategyName}: ${dup.id}`);
58
+ }
59
+ };
60
+ const loadInstalledStrategyUnits = async (input) => {
61
+ const strategyService = new StrategyService(input.configService);
62
+ const unitStore = new UnitStore(input.configService);
20
63
  strategyService.ensureConfigFileExists();
21
64
  const strategyFile = strategyService.readStrategy(input.strategyName);
22
- const normalized = (0, strategy_normalize_1.normalizeStrategyUnits)(strategyFile);
65
+ const normalized = normalizeStrategyUnits(strategyFile);
23
66
  const installed = unitStore.readInstalledDependencyVersions();
24
67
  const drift = normalized.flatMap((u) => {
25
- const pinned = (0, parse_pinned_spec_1.parsePinnedSpec)(u.ref);
68
+ const pinned = parsePinnedSpec(u.ref);
26
69
  const installedVersion = installed[pinned.name];
27
70
  if (!installedVersion || installedVersion !== pinned.version) {
28
71
  return [
@@ -45,48 +88,100 @@ const loadStrategyUnits = async (input) => {
45
88
  throw new Error(`Strategy drift detected (${input.strategyName}). ${details}. ` +
46
89
  `Fix: pp strategy update ${input.strategyName} OR pp strategy pin ${input.strategyName}`);
47
90
  }
48
- const loadedUnits = await Promise.all(normalized.map(async (u) => unitStore.instantiateFromRef(u.ref, u.args)));
49
- const seen = new Set();
50
- const dup = loadedUnits.find((u) => {
51
- if (seen.has(u.id)) {
52
- return true;
53
- }
54
- seen.add(u.id);
55
- return false;
91
+ const units = await Promise.all(normalized.map(async (u) => unitStore.instantiateFromRef(u.ref, u.args)));
92
+ assertNoDuplicateUnitIds({
93
+ strategyName: input.strategyName,
94
+ units
56
95
  });
57
- if (dup) {
58
- throw new Error(`Duplicate unit id detected in strategy ${input.strategyName}: ${dup.id}`);
96
+ return units;
97
+ };
98
+ const instantiateBuiltinUnit = async (input) => {
99
+ const req = createRequire(import.meta.url);
100
+ const pinned = parsePinnedSpec(input.ref);
101
+ const resolved = req.resolve(pinned.name);
102
+ const mod = (await import(pathToFileURL(resolved).href));
103
+ const ctor = resolveUnitConstructor(mod);
104
+ if (!ctor) {
105
+ throw new Error(`Unit ${pinned.name} does not export a Unit constructor.`);
106
+ }
107
+ const instance = new ctor(...input.args);
108
+ if (!isUnitLike(instance)) {
109
+ throw new Error(`Unit ${pinned.name} exported constructor did not produce a Unit.`);
110
+ }
111
+ return instance;
112
+ };
113
+ const loadBuiltinStrategyUnits = async (input) => {
114
+ const normalized = normalizeStrategyUnits(input.strategyFile);
115
+ const units = await Promise.all(normalized.map(async (u) => instantiateBuiltinUnit({
116
+ ref: u.ref,
117
+ args: u.args
118
+ })));
119
+ assertNoDuplicateUnitIds({
120
+ strategyName: input.strategyName,
121
+ units
122
+ });
123
+ return units;
124
+ };
125
+ const loadStrategyUnits = async (input) => {
126
+ if (input.strategy.source === "installed") {
127
+ return loadInstalledStrategyUnits({
128
+ strategyName: input.strategy.name,
129
+ configService: input.configService
130
+ });
59
131
  }
60
- return loadedUnits;
132
+ return loadBuiltinStrategyUnits({
133
+ strategyName: input.strategy.name,
134
+ strategyFile: input.strategy.strategyFile
135
+ });
61
136
  };
62
- class ArchiveCommand extends core_1.Command {
137
+ export default class ArchiveCommand extends Command {
138
+ static description = "Archive a web page as an offline snapshot.";
139
+ static args = {
140
+ url: Args.string({
141
+ description: "URL to archive",
142
+ required: true
143
+ })
144
+ };
145
+ static flags = {
146
+ help: Flags.help({
147
+ char: "h"
148
+ }),
149
+ timeout: Flags.integer({
150
+ char: "t",
151
+ description: "Network idle duration in milliseconds before capture stops",
152
+ required: false
153
+ }),
154
+ maxDuration: Flags.integer({
155
+ description: "Hard max capture duration in milliseconds",
156
+ required: false
157
+ }),
158
+ strategy: Flags.string({
159
+ description: "Run an installed or built-in strategy (unit pipeline) by name"
160
+ })
161
+ };
63
162
  async run() {
64
163
  const { args, flags } = await this.parse(ArchiveCommand);
65
164
  const targetUrl = args.url;
66
165
  const timeoutMs = typeof flags.timeout === "number" ? flags.timeout : undefined;
67
166
  const maxDurationMs = typeof flags.maxDuration === "number" ? flags.maxDuration : undefined;
68
167
  const strategyName = typeof flags.strategy === "string" ? flags.strategy.trim() : undefined;
69
- const pagepocket = lib_1.PagePocket.fromURL(targetUrl);
70
- const result = await (0, with_spinner_1.withSpinner)(async (spinner) => {
168
+ const pagepocket = PagePocket.fromURL(targetUrl);
169
+ const result = await withSpinner(async (spinner) => {
71
170
  {
72
- const configService = new config_service_1.ConfigService();
171
+ const configService = new ConfigService();
73
172
  const name = strategyName && strategyName.length > 0 ? strategyName : "default";
74
- const strategyService = new strategy_service_1.StrategyService(configService);
173
+ const strategyService = new StrategyService(configService);
75
174
  strategyService.ensureConfigFileExists();
76
- const installedNames = strategyService.listInstalledStrategyNames();
77
- if (installedNames.length === 0) {
78
- const v = (0, read_installed_package_version_1.readInstalledPackageVersion)("@pagepocket/builtin-strategy");
79
- await strategyService.addStrategy({
80
- source: `@pagepocket/builtin-strategy@${v}`,
81
- force: false
82
- });
83
- }
84
- const units = await loadStrategyUnits({
175
+ const strategy = resolveStrategy({
85
176
  strategyName: name,
177
+ strategyService
178
+ });
179
+ const units = await loadStrategyUnits({
180
+ strategy,
86
181
  configService
87
182
  });
88
183
  const entryTarget = pagepocket;
89
- const strategyFile = strategyService.readStrategy(name);
184
+ const strategyFile = strategy.strategyFile;
90
185
  const captureOptions = strategyFile.pipeline.captureOptions;
91
186
  const effectiveTimeoutMs = typeof timeoutMs === "number" ? timeoutMs : captureOptions?.timeoutMs;
92
187
  const effectiveMaxDurationMs = typeof maxDurationMs === "number" ? maxDurationMs : captureOptions?.maxDurationMs;
@@ -95,45 +190,20 @@ class ArchiveCommand extends core_1.Command {
95
190
  ...(typeof effectiveMaxDurationMs === "number"
96
191
  ? { maxDurationMs: effectiveMaxDurationMs }
97
192
  : {}),
98
- blacklist: [...lib_1.ga, ...lib_1.ns],
193
+ blacklist: [...ga, ...ns],
99
194
  units,
100
- plugins: await (0, load_configured_plugins_1.loadConfiguredPlugins)().catch(() => [])
195
+ plugins: await loadConfiguredPlugins().catch(() => [])
101
196
  });
102
197
  return result;
103
198
  }
104
199
  }, "Freezing page");
105
- this.log(chalk_1.default.green("All done! Snapshot created."));
200
+ this.log(chalk.green("All done! Snapshot created."));
106
201
  if (result.kind === "zip") {
107
- this.log(`Snapshot saved to ${chalk_1.default.cyan(result.zip.outputPath)}`);
202
+ this.log(`Snapshot saved to ${chalk.cyan(result.zip.outputPath)}`);
108
203
  }
109
204
  else if (result.kind === "raw") {
110
- this.log(`Snapshot saved to ${chalk_1.default.cyan(result.outputDir)}`);
205
+ this.log(`Snapshot saved to ${chalk.cyan(result.outputDir)}`);
111
206
  }
112
207
  process.exit();
113
208
  }
114
209
  }
115
- ArchiveCommand.description = "Archive a web page as an offline snapshot.";
116
- ArchiveCommand.args = {
117
- url: core_1.Args.string({
118
- description: "URL to archive",
119
- required: true
120
- })
121
- };
122
- ArchiveCommand.flags = {
123
- help: core_1.Flags.help({
124
- char: "h"
125
- }),
126
- timeout: core_1.Flags.integer({
127
- char: "t",
128
- description: "Network idle duration in milliseconds before capture stops",
129
- required: false
130
- }),
131
- maxDuration: core_1.Flags.integer({
132
- description: "Hard max capture duration in milliseconds",
133
- required: false
134
- }),
135
- strategy: core_1.Flags.string({
136
- description: "Run an installed strategy (unit pipeline) by name"
137
- })
138
- };
139
- exports.default = ArchiveCommand;
@@ -1,17 +1,14 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const core_1 = require("@oclif/core");
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const config_service_1 = require("../../services/config-service");
9
- const plugin_installer_1 = require("../../services/plugin-installer");
10
- const plugin_store_1 = require("../../services/plugin-store");
11
- const parse_plugin_options_1 = require("../../utils/parse-plugin-options");
12
- const parse_plugin_spec_1 = require("../../utils/parse-plugin-spec");
13
- const validate_plugin_default_export_1 = require("../../utils/validate-plugin-default-export");
14
- class PluginAddCommand extends core_1.Command {
1
+ import { Command } from "@oclif/core";
2
+ import chalk from "chalk";
3
+ import { ConfigService } from "../../services/config-service.js";
4
+ import { installPluginPackage } from "../../services/plugin-installer.js";
5
+ import { PluginStore } from "../../services/plugin-store.js";
6
+ import { parsePluginOptions } from "../../utils/parse-plugin-options.js";
7
+ import { parsePluginSpec } from "../../utils/parse-plugin-spec.js";
8
+ import { validatePluginDefaultExport } from "../../utils/validate-plugin-default-export.js";
9
+ export default class PluginAddCommand extends Command {
10
+ static description = "Install a plugin package, add it to config, and run its optional setup().";
11
+ static strict = false;
15
12
  async run() {
16
13
  const [name, ...rest] = this.argv;
17
14
  if (!name) {
@@ -21,24 +18,24 @@ class PluginAddCommand extends core_1.Command {
21
18
  this.log("Usage: pp plugin add <plugin-name> [--option-* <value> ...] [--option <value> ...]");
22
19
  return;
23
20
  }
24
- const parsedSpec = (0, parse_plugin_spec_1.parsePluginSpec)(name);
25
- const configService = new config_service_1.ConfigService();
26
- const store = new plugin_store_1.PluginStore(configService);
21
+ const parsedSpec = parsePluginSpec(name);
22
+ const configService = new ConfigService();
23
+ const store = new PluginStore(configService);
27
24
  configService.ensureConfigFileExists();
28
25
  const config = configService.readConfigOrDefault();
29
26
  if (store.hasPlugin(config, parsedSpec.name)) {
30
- this.log(chalk_1.default.gray(`Plugin already exists in config: ${parsedSpec.name}`));
27
+ this.log(chalk.gray(`Plugin already exists in config: ${parsedSpec.name}`));
31
28
  return;
32
29
  }
33
- const parsed = (0, parse_plugin_options_1.parsePluginOptions)(rest);
30
+ const parsed = parsePluginOptions(rest);
34
31
  const entry = parsed.kind === "none"
35
32
  ? parsedSpec.name
36
33
  : parsed.kind === "array"
37
34
  ? { name: parsedSpec.name, spec: parsedSpec.spec, options: parsed.value }
38
35
  : { name: parsedSpec.name, spec: parsedSpec.spec, options: parsed.value };
39
- (0, plugin_installer_1.installPluginPackage)(store, { packageName: parsedSpec.spec });
36
+ installPluginPackage(store, { packageName: parsedSpec.spec });
40
37
  const mod = await store.importPluginModule(parsedSpec.name);
41
- const validation = (0, validate_plugin_default_export_1.validatePluginDefaultExport)({
38
+ const validation = validatePluginDefaultExport({
42
39
  pluginName: parsedSpec.name,
43
40
  moduleExports: mod,
44
41
  options: parsed.kind === "none" ? undefined : parsed.value
@@ -49,9 +46,6 @@ class PluginAddCommand extends core_1.Command {
49
46
  const nextConfig = store.addPluginToConfig(config, entry);
50
47
  configService.writeConfig(nextConfig);
51
48
  await store.runOptionalSetup(parsedSpec.name);
52
- this.log(chalk_1.default.green(`Added plugin: ${parsedSpec.name}`));
49
+ this.log(chalk.green(`Added plugin: ${parsedSpec.name}`));
53
50
  }
54
51
  }
55
- PluginAddCommand.description = "Install a plugin package, add it to config, and run its optional setup().";
56
- PluginAddCommand.strict = false;
57
- exports.default = PluginAddCommand;
@@ -1,13 +1,8 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const core_1 = require("@oclif/core");
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const config_service_1 = require("../../services/config-service");
9
- const plugin_store_1 = require("../../services/plugin-store");
10
- const parse_plugin_spec_1 = require("../../utils/parse-plugin-spec");
1
+ import { Args, Command } from "@oclif/core";
2
+ import chalk from "chalk";
3
+ import { ConfigService } from "../../services/config-service.js";
4
+ import { PluginStore, normalizePluginConfigEntry } from "../../services/plugin-store.js";
5
+ import { parsePluginSpec } from "../../utils/parse-plugin-spec.js";
11
6
  /**
12
7
  * Validate one configured plugin can be loaded and instantiated.
13
8
  *
@@ -41,16 +36,23 @@ const runDoctorCheck = async (store, spec) => {
41
36
  };
42
37
  }
43
38
  };
44
- class PluginDoctorCommand extends core_1.Command {
39
+ export default class PluginDoctorCommand extends Command {
40
+ static description = "Validate configured plugins are installed and loadable.";
41
+ static args = {
42
+ name: Args.string({
43
+ description: "npm package name (optional; if omitted checks all configured plugins)",
44
+ required: false
45
+ })
46
+ };
45
47
  async run() {
46
48
  const { args } = await this.parse(PluginDoctorCommand);
47
- const configService = new config_service_1.ConfigService();
48
- const store = new plugin_store_1.PluginStore(configService);
49
+ const configService = new ConfigService();
50
+ const store = new PluginStore(configService);
49
51
  configService.ensureConfigFileExists();
50
52
  const config = store.readConfig();
51
- const targetName = args.name ? (0, parse_plugin_spec_1.parsePluginSpec)(args.name).name : undefined;
53
+ const targetName = args.name ? parsePluginSpec(args.name).name : undefined;
52
54
  const configured = config.plugins
53
- .map((entry) => (0, plugin_store_1.normalizePluginConfigEntry)(entry))
55
+ .map((entry) => normalizePluginConfigEntry(entry))
54
56
  .filter((entry) => {
55
57
  if (!targetName) {
56
58
  return true;
@@ -59,33 +61,25 @@ class PluginDoctorCommand extends core_1.Command {
59
61
  });
60
62
  if (configured.length === 0) {
61
63
  if (targetName) {
62
- this.log(chalk_1.default.gray(`Plugin not found in config: ${targetName}`));
64
+ this.log(chalk.gray(`Plugin not found in config: ${targetName}`));
63
65
  return;
64
66
  }
65
- this.log(chalk_1.default.gray("No plugins configured."));
67
+ this.log(chalk.gray("No plugins configured."));
66
68
  return;
67
69
  }
68
70
  const checks = await Promise.all(configured.map((entry) => runDoctorCheck(store, entry)));
69
71
  const failed = checks.filter((item) => !item.installed || !item.loadable);
70
72
  checks.forEach((item) => {
71
73
  if (item.installed && item.loadable) {
72
- this.log(chalk_1.default.green(`[OK] ${item.plugin}`));
74
+ this.log(chalk.green(`[OK] ${item.plugin}`));
73
75
  return;
74
76
  }
75
- this.log(chalk_1.default.red(`[FAIL] ${item.plugin}: ${item.error ?? "unknown error"}`));
77
+ this.log(chalk.red(`[FAIL] ${item.plugin}: ${item.error ?? "unknown error"}`));
76
78
  });
77
79
  if (failed.length === 0) {
78
- this.log(chalk_1.default.green("Plugin doctor checks passed."));
80
+ this.log(chalk.green("Plugin doctor checks passed."));
79
81
  return;
80
82
  }
81
83
  throw new Error(`${failed.length} plugin(s) failed doctor checks.`);
82
84
  }
83
85
  }
84
- PluginDoctorCommand.description = "Validate configured plugins are installed and loadable.";
85
- PluginDoctorCommand.args = {
86
- name: core_1.Args.string({
87
- description: "npm package name (optional; if omitted checks all configured plugins)",
88
- required: false
89
- })
90
- };
91
- exports.default = PluginDoctorCommand;
@@ -1,21 +1,17 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const core_1 = require("@oclif/core");
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const config_service_1 = require("../../services/config-service");
9
- const plugin_store_1 = require("../../services/plugin-store");
10
- class PluginLsCommand extends core_1.Command {
1
+ import { Command } from "@oclif/core";
2
+ import chalk from "chalk";
3
+ import { ConfigService } from "../../services/config-service.js";
4
+ import { PluginStore } from "../../services/plugin-store.js";
5
+ export default class PluginLsCommand extends Command {
6
+ static description = "List configured plugins.";
11
7
  async run() {
12
- const configService = new config_service_1.ConfigService();
13
- const store = new plugin_store_1.PluginStore(configService);
8
+ const configService = new ConfigService();
9
+ const store = new PluginStore(configService);
14
10
  configService.ensureConfigFileExists();
15
11
  const config = configService.readConfigOrDefault();
16
12
  const entries = config.plugins;
17
13
  if (entries.length === 0) {
18
- this.log(chalk_1.default.gray("No plugins configured."));
14
+ this.log(chalk.gray("No plugins configured."));
19
15
  return;
20
16
  }
21
17
  entries
@@ -28,18 +24,16 @@ class PluginLsCommand extends core_1.Command {
28
24
  : undefined;
29
25
  const meta = store.readInstalledPackageMeta(name);
30
26
  if (!meta) {
31
- const specText = configuredSpec ? chalk_1.default.gray(`(configured: ${configuredSpec})`) : "";
32
- return `${chalk_1.default.yellow(name)} ${chalk_1.default.gray("(not installed)")} ${specText}`.trim();
27
+ const specText = configuredSpec ? chalk.gray(`(configured: ${configuredSpec})`) : "";
28
+ return `${chalk.yellow(name)} ${chalk.gray("(not installed)")} ${specText}`.trim();
33
29
  }
34
- const specText = configuredSpec ? chalk_1.default.gray(`(configured: ${configuredSpec})`) : "";
30
+ const specText = configuredSpec ? chalk.gray(`(configured: ${configuredSpec})`) : "";
35
31
  const desc = meta.description
36
- ? chalk_1.default.gray(meta.description)
37
- : chalk_1.default.gray("(no description)");
38
- const version = meta.version ? chalk_1.default.cyan(`v${meta.version}`) : chalk_1.default.gray("(no version)");
39
- return `${chalk_1.default.green(meta.name)} ${version} ${specText} ${desc}`.replace(/\s{2,}/g, " ");
32
+ ? chalk.gray(meta.description)
33
+ : chalk.gray("(no description)");
34
+ const version = meta.version ? chalk.cyan(`v${meta.version}`) : chalk.gray("(no version)");
35
+ return `${chalk.green(meta.name)} ${version} ${specText} ${desc}`.replace(/\s{2,}/g, " ");
40
36
  })
41
37
  .forEach((line) => this.log(line));
42
38
  }
43
39
  }
44
- PluginLsCommand.description = "List configured plugins.";
45
- exports.default = PluginLsCommand;
@@ -1,13 +1,8 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const core_1 = require("@oclif/core");
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const config_service_1 = require("../../services/config-service");
9
- const plugin_installer_1 = require("../../services/plugin-installer");
10
- const plugin_store_1 = require("../../services/plugin-store");
1
+ import { Command } from "@oclif/core";
2
+ import chalk from "chalk";
3
+ import { ConfigService } from "../../services/config-service.js";
4
+ import { uninstallPluginPackage } from "../../services/plugin-installer.js";
5
+ import { PluginStore, normalizePluginConfigEntry } from "../../services/plugin-store.js";
11
6
  /**
12
7
  * Get configured plugin names from config.
13
8
  *
@@ -17,27 +12,26 @@ const plugin_store_1 = require("../../services/plugin-store");
17
12
  const getConfiguredPluginNames = (store) => {
18
13
  const config = store.readConfig();
19
14
  const names = config.plugins
20
- .map((entry) => (0, plugin_store_1.normalizePluginConfigEntry)(entry).name)
15
+ .map((entry) => normalizePluginConfigEntry(entry).name)
21
16
  .filter((name) => name.trim().length > 0);
22
17
  return new Set(names);
23
18
  };
24
- class PluginPruneCommand extends core_1.Command {
19
+ export default class PluginPruneCommand extends Command {
20
+ static description = "Uninstall plugin packages that are not referenced by config.";
25
21
  async run() {
26
- const configService = new config_service_1.ConfigService();
27
- const store = new plugin_store_1.PluginStore(configService);
22
+ const configService = new ConfigService();
23
+ const store = new PluginStore(configService);
28
24
  configService.ensureConfigFileExists();
29
25
  const configured = getConfiguredPluginNames(store);
30
26
  const installed = store.readInstalledDependencyNames();
31
27
  const orphans = installed.filter((name) => !configured.has(name));
32
28
  if (orphans.length === 0) {
33
- this.log(chalk_1.default.gray("No orphan plugin packages found."));
29
+ this.log(chalk.gray("No orphan plugin packages found."));
34
30
  return;
35
31
  }
36
32
  orphans.forEach((name) => {
37
- (0, plugin_installer_1.uninstallPluginPackage)(store, { packageName: name });
38
- this.log(chalk_1.default.green(`Pruned plugin package: ${name}`));
33
+ uninstallPluginPackage(store, { packageName: name });
34
+ this.log(chalk.green(`Pruned plugin package: ${name}`));
39
35
  });
40
36
  }
41
37
  }
42
- PluginPruneCommand.description = "Uninstall plugin packages that are not referenced by config.";
43
- exports.default = PluginPruneCommand;
@@ -1,34 +1,28 @@
1
- "use strict";
2
- var __importDefault = (this && this.__importDefault) || function (mod) {
3
- return (mod && mod.__esModule) ? mod : { "default": mod };
4
- };
5
- Object.defineProperty(exports, "__esModule", { value: true });
6
- const core_1 = require("@oclif/core");
7
- const chalk_1 = __importDefault(require("chalk"));
8
- const config_service_1 = require("../../services/config-service");
9
- const plugin_store_1 = require("../../services/plugin-store");
10
- class PluginRemoveCommand extends core_1.Command {
1
+ import { Args, Command } from "@oclif/core";
2
+ import chalk from "chalk";
3
+ import { ConfigService } from "../../services/config-service.js";
4
+ import { PluginStore } from "../../services/plugin-store.js";
5
+ export default class PluginRemoveCommand extends Command {
6
+ static description = "Remove a plugin from config (does not uninstall).";
7
+ static args = {
8
+ name: Args.string({
9
+ description: "npm package name",
10
+ required: true
11
+ })
12
+ };
11
13
  async run() {
12
14
  const { args } = await this.parse(PluginRemoveCommand);
13
15
  const name = args.name;
14
- const configService = new config_service_1.ConfigService();
15
- const store = new plugin_store_1.PluginStore(configService);
16
+ const configService = new ConfigService();
17
+ const store = new PluginStore(configService);
16
18
  configService.ensureConfigFileExists();
17
19
  const config = configService.readConfigOrDefault();
18
20
  const out = store.removePluginFromConfig(config, name);
19
21
  if (!out.removed) {
20
- this.log(chalk_1.default.gray(`Plugin not found in config: ${name}`));
22
+ this.log(chalk.gray(`Plugin not found in config: ${name}`));
21
23
  return;
22
24
  }
23
25
  configService.writeConfig(out.config);
24
- this.log(chalk_1.default.green(`Removed from config: ${name}`));
26
+ this.log(chalk.green(`Removed from config: ${name}`));
25
27
  }
26
28
  }
27
- PluginRemoveCommand.description = "Remove a plugin from config (does not uninstall).";
28
- PluginRemoveCommand.args = {
29
- name: core_1.Args.string({
30
- description: "npm package name",
31
- required: true
32
- })
33
- };
34
- exports.default = PluginRemoveCommand;