@vltpkg/cli-sdk 0.0.0-16 → 0.0.0-18

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 (48) hide show
  1. package/dist/esm/commands/config.d.ts.map +1 -1
  2. package/dist/esm/commands/config.js +106 -35
  3. package/dist/esm/commands/config.js.map +1 -1
  4. package/dist/esm/commands/init.d.ts +3 -3
  5. package/dist/esm/commands/init.d.ts.map +1 -1
  6. package/dist/esm/commands/init.js +95 -9
  7. package/dist/esm/commands/init.js.map +1 -1
  8. package/dist/esm/commands/list.d.ts.map +1 -1
  9. package/dist/esm/commands/list.js +88 -36
  10. package/dist/esm/commands/list.js.map +1 -1
  11. package/dist/esm/commands/pack.d.ts +20 -0
  12. package/dist/esm/commands/pack.d.ts.map +1 -0
  13. package/dist/esm/commands/pack.js +81 -0
  14. package/dist/esm/commands/pack.js.map +1 -0
  15. package/dist/esm/commands/pkg.d.ts +1 -1
  16. package/dist/esm/commands/pkg.d.ts.map +1 -1
  17. package/dist/esm/commands/pkg.js +135 -35
  18. package/dist/esm/commands/pkg.js.map +1 -1
  19. package/dist/esm/commands/publish.d.ts +21 -0
  20. package/dist/esm/commands/publish.d.ts.map +1 -0
  21. package/dist/esm/commands/publish.js +169 -0
  22. package/dist/esm/commands/publish.js.map +1 -0
  23. package/dist/esm/commands/query.d.ts +1 -1
  24. package/dist/esm/commands/query.d.ts.map +1 -1
  25. package/dist/esm/commands/query.js +79 -23
  26. package/dist/esm/commands/query.js.map +1 -1
  27. package/dist/esm/commands/version.d.ts +22 -0
  28. package/dist/esm/commands/version.d.ts.map +1 -0
  29. package/dist/esm/commands/version.js +151 -0
  30. package/dist/esm/commands/version.js.map +1 -0
  31. package/dist/esm/config/definition.d.ts +35 -2
  32. package/dist/esm/config/definition.d.ts.map +1 -1
  33. package/dist/esm/config/definition.js +34 -4
  34. package/dist/esm/config/definition.js.map +1 -1
  35. package/dist/esm/exec-command.js +2 -2
  36. package/dist/esm/exec-command.js.map +1 -1
  37. package/dist/esm/index.d.ts.map +1 -1
  38. package/dist/esm/index.js +2 -1
  39. package/dist/esm/index.js.map +1 -1
  40. package/dist/esm/pack-tarball.d.ts +22 -0
  41. package/dist/esm/pack-tarball.d.ts.map +1 -0
  42. package/dist/esm/pack-tarball.js +247 -0
  43. package/dist/esm/pack-tarball.js.map +1 -0
  44. package/dist/esm/start-gui.d.ts +1 -0
  45. package/dist/esm/start-gui.d.ts.map +1 -1
  46. package/dist/esm/start-gui.js +5 -3
  47. package/dist/esm/start-gui.js.map +1 -1
  48. package/package.json +28 -22
@@ -0,0 +1,169 @@
1
+ import { error } from '@vltpkg/error-cause';
2
+ import { RegistryClient } from '@vltpkg/registry-client';
3
+ import { run } from '@vltpkg/run';
4
+ import { commandUsage } from "../config/usage.js";
5
+ import { packTarball } from "../pack-tarball.js";
6
+ import assert from 'node:assert';
7
+ import { asError } from '@vltpkg/types';
8
+ import { dirname } from 'node:path';
9
+ import prettyBytes from 'pretty-bytes';
10
+ export const usage = () => commandUsage({
11
+ command: 'publish',
12
+ usage: '',
13
+ description: `Create a tarball from a package and publish it to the configured registry.
14
+
15
+ This command will pack the package in the current directory or specified folder,
16
+ and then upload it to the configured registry.`,
17
+ options: {
18
+ tag: {
19
+ description: 'Publish the package with the given tag',
20
+ value: '<tag>',
21
+ },
22
+ access: {
23
+ description: 'Set access level (public or restricted)',
24
+ value: '<level>',
25
+ },
26
+ otp: {
27
+ description: `Provide an OTP to use when publishing a package.`,
28
+ value: '<otp>',
29
+ },
30
+ },
31
+ });
32
+ export const views = {
33
+ human: r => {
34
+ const lines = [
35
+ `📦 Package: ${r.id}`,
36
+ `🏷️ Tag: ${r.tag}`,
37
+ `📡 Registry: ${r.registry}`,
38
+ `📁 ${r.files.length} Files`,
39
+ ...r.files.map(f => ` - ${f}`),
40
+ `📊 Package Size: ${prettyBytes(r.size)}`,
41
+ `📂 Unpacked Size: ${prettyBytes(r.unpackedSize)}`,
42
+ ];
43
+ if (r.shasum)
44
+ lines.push(`🔒 Shasum: ${r.shasum}`);
45
+ if (r.integrity)
46
+ lines.push(`🔐 Integrity: ${r.integrity}`);
47
+ return lines.join('\n');
48
+ },
49
+ json: r => r,
50
+ };
51
+ export const command = async (conf) => {
52
+ const manifestPath = conf.options.packageJson.find();
53
+ assert(manifestPath, 'No package.json found');
54
+ const manifestDir = dirname(manifestPath);
55
+ const manifest = conf.options.packageJson.read(manifestDir);
56
+ assert(!manifest.private, error('Package has been marked as private'));
57
+ const { tag = 'latest', access, registry, 'dry-run': dry = false, otp, } = conf.options;
58
+ const registryUrl = new URL(registry);
59
+ const runOptions = {
60
+ cwd: manifestDir,
61
+ projectRoot: conf.projectRoot,
62
+ packageJson: conf.options.packageJson,
63
+ manifest,
64
+ ignoreMissing: true,
65
+ ignorePrePost: true,
66
+ };
67
+ await run({
68
+ ...runOptions,
69
+ arg0: 'prepublishOnly',
70
+ });
71
+ await run({
72
+ ...runOptions,
73
+ arg0: 'prepublish',
74
+ });
75
+ await run({
76
+ ...runOptions,
77
+ arg0: 'prepack',
78
+ });
79
+ await run({
80
+ ...runOptions,
81
+ arg0: 'prepare',
82
+ });
83
+ const { name, version, tarballName, tarballData, unpackedSize, files, integrity, shasum, } = await packTarball(manifest, manifestDir, conf);
84
+ await run({
85
+ ...runOptions,
86
+ arg0: 'postpack',
87
+ });
88
+ await run({
89
+ ...runOptions,
90
+ arg0: 'publish',
91
+ });
92
+ const publishMetadata = {
93
+ _id: name,
94
+ name,
95
+ description: manifest.description || '',
96
+ 'dist-tags': {
97
+ [tag]: version,
98
+ },
99
+ versions: {
100
+ [version]: {
101
+ ...manifest,
102
+ _id: `${name}@${version}`,
103
+ _nodeVersion: process.versions.node,
104
+ dist: {
105
+ ...manifest.dist,
106
+ integrity,
107
+ shasum,
108
+ tarball: new URL(`${name}/-/${tarballName}`, registryUrl)
109
+ .href,
110
+ },
111
+ },
112
+ },
113
+ access,
114
+ _attachments: {
115
+ [tarballName]: {
116
+ content_type: 'application/octet-stream',
117
+ data: tarballData.toString('base64'),
118
+ length: tarballData.length,
119
+ },
120
+ },
121
+ };
122
+ const rc = new RegistryClient(conf.options);
123
+ const publishUrl = new URL(name.startsWith('@') ? name.replace('/', '%2F') : name, registryUrl);
124
+ if (!dry) {
125
+ let response;
126
+ try {
127
+ response = await rc.request(publishUrl, {
128
+ method: 'PUT',
129
+ headers: {
130
+ 'content-type': 'application/json',
131
+ // These control what type of OTP auth flow is used
132
+ 'npm-auth-type': 'web',
133
+ 'npm-command': 'publish',
134
+ },
135
+ body: JSON.stringify(publishMetadata),
136
+ otp,
137
+ });
138
+ }
139
+ catch (err) {
140
+ throw error('Failed to publish package', {
141
+ cause: asError(err),
142
+ });
143
+ }
144
+ if (response.statusCode !== 200 && response.statusCode !== 201) {
145
+ throw error('Failed to publish package', {
146
+ url: publishUrl,
147
+ response,
148
+ });
149
+ }
150
+ }
151
+ await run({
152
+ ...runOptions,
153
+ arg0: 'postpublish',
154
+ });
155
+ return {
156
+ id: `${name}@${version}`,
157
+ name,
158
+ version,
159
+ tag,
160
+ access,
161
+ registry: registryUrl.origin,
162
+ integrity,
163
+ shasum,
164
+ size: tarballData.length,
165
+ unpackedSize,
166
+ files,
167
+ };
168
+ };
169
+ //# sourceMappingURL=publish.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"publish.js","sourceRoot":"","sources":["../../../src/commands/publish.ts"],"names":[],"mappings":"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","sourcesContent":["import { error } from '@vltpkg/error-cause'\nimport { RegistryClient } from '@vltpkg/registry-client'\nimport type { CacheEntry } from '@vltpkg/registry-client'\nimport { run } from '@vltpkg/run'\nimport { commandUsage } from '../config/usage.ts'\nimport type { CommandFn, CommandUsage } from '../index.ts'\nimport { packTarball } from '../pack-tarball.ts'\nimport type { Views } from '../view.ts'\nimport assert from 'node:assert'\nimport { asError } from '@vltpkg/types'\nimport { dirname } from 'node:path'\nimport prettyBytes from 'pretty-bytes'\n\nexport const usage: CommandUsage = () =>\n commandUsage({\n command: 'publish',\n usage: '',\n description: `Create a tarball from a package and publish it to the configured registry.\n \n This command will pack the package in the current directory or specified folder,\n and then upload it to the configured registry.`,\n options: {\n tag: {\n description: 'Publish the package with the given tag',\n value: '<tag>',\n },\n access: {\n description: 'Set access level (public or restricted)',\n value: '<level>',\n },\n otp: {\n description: `Provide an OTP to use when publishing a package.`,\n value: '<otp>',\n },\n },\n })\n\nexport type CommandResult = {\n id: string\n name: string\n version: string\n tag: string\n registry: string\n shasum?: string\n integrity?: string\n size: number\n access: string\n unpackedSize: number\n files: string[]\n}\n\nexport const views = {\n human: r => {\n const lines = [\n `📦 Package: ${r.id}`,\n `🏷️ Tag: ${r.tag}`,\n `📡 Registry: ${r.registry}`,\n `📁 ${r.files.length} Files`,\n ...r.files.map(f => ` - ${f}`),\n `📊 Package Size: ${prettyBytes(r.size)}`,\n `📂 Unpacked Size: ${prettyBytes(r.unpackedSize)}`,\n ]\n if (r.shasum) lines.push(`🔒 Shasum: ${r.shasum}`)\n if (r.integrity) lines.push(`🔐 Integrity: ${r.integrity}`)\n\n return lines.join('\\n')\n },\n json: r => r,\n} as const satisfies Views<CommandResult>\n\nexport const command: CommandFn<CommandResult> = async conf => {\n const manifestPath = conf.options.packageJson.find()\n assert(manifestPath, 'No package.json found')\n const manifestDir = dirname(manifestPath)\n const manifest = conf.options.packageJson.read(manifestDir)\n\n assert(\n !manifest.private,\n error('Package has been marked as private'),\n )\n\n const {\n tag = 'latest',\n access,\n registry,\n 'dry-run': dry = false,\n otp,\n } = conf.options\n const registryUrl = new URL(registry)\n\n const runOptions = {\n cwd: manifestDir,\n projectRoot: conf.projectRoot,\n packageJson: conf.options.packageJson,\n manifest,\n ignoreMissing: true,\n ignorePrePost: true,\n }\n\n await run({\n ...runOptions,\n arg0: 'prepublishOnly',\n })\n\n await run({\n ...runOptions,\n arg0: 'prepublish',\n })\n\n await run({\n ...runOptions,\n arg0: 'prepack',\n })\n\n await run({\n ...runOptions,\n arg0: 'prepare',\n })\n\n const {\n name,\n version,\n tarballName,\n tarballData,\n unpackedSize,\n files,\n integrity,\n shasum,\n } = await packTarball(manifest, manifestDir, conf)\n\n await run({\n ...runOptions,\n arg0: 'postpack',\n })\n\n await run({\n ...runOptions,\n arg0: 'publish',\n })\n\n const publishMetadata = {\n _id: name,\n name,\n description: manifest.description || '',\n 'dist-tags': {\n [tag]: version,\n },\n versions: {\n [version]: {\n ...manifest,\n _id: `${name}@${version}`,\n _nodeVersion: process.versions.node,\n dist: {\n ...manifest.dist,\n integrity,\n shasum,\n tarball: new URL(`${name}/-/${tarballName}`, registryUrl)\n .href,\n },\n },\n },\n access,\n _attachments: {\n [tarballName]: {\n content_type: 'application/octet-stream',\n data: tarballData.toString('base64'),\n length: tarballData.length,\n },\n },\n }\n\n const rc = new RegistryClient(conf.options)\n const publishUrl = new URL(\n name.startsWith('@') ? name.replace('/', '%2F') : name,\n registryUrl,\n )\n\n if (!dry) {\n let response: CacheEntry\n try {\n response = await rc.request(publishUrl, {\n method: 'PUT',\n headers: {\n 'content-type': 'application/json',\n // These control what type of OTP auth flow is used\n 'npm-auth-type': 'web',\n 'npm-command': 'publish',\n },\n body: JSON.stringify(publishMetadata),\n otp,\n })\n } catch (err) {\n throw error('Failed to publish package', {\n cause: asError(err),\n })\n }\n\n if (response.statusCode !== 200 && response.statusCode !== 201) {\n throw error('Failed to publish package', {\n url: publishUrl,\n response,\n })\n }\n }\n\n await run({\n ...runOptions,\n arg0: 'postpublish',\n })\n\n return {\n id: `${name}@${version}`,\n name,\n version,\n tag,\n access,\n registry: registryUrl.origin,\n integrity,\n shasum,\n size: tarballData.length,\n unpackedSize,\n files,\n }\n}\n"]}
@@ -9,7 +9,7 @@ export declare const views: {
9
9
  readonly json: typeof jsonOutput;
10
10
  readonly mermaid: typeof mermaidOutput;
11
11
  readonly human: typeof humanReadableOutput;
12
- readonly gui: ({ queryString }: QueryResult, _: import("../view.ts").ViewOptions, conf: import("../config/index.js").ParsedConfig) => Promise<void>;
12
+ readonly gui: ({ queryString }: QueryResult, _: import("../view.ts").ViewOptions, conf: import("../config/index.ts").ParsedConfig) => Promise<void>;
13
13
  };
14
14
  export declare const command: CommandFn<QueryResult>;
15
15
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/commands/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,wBAAwB,EACxB,eAAe,EACf,kBAAkB,EAEnB,MAAM,eAAe,CAAA;AACtB,OAAO,EAEL,mBAAmB,EACnB,UAAU,EACV,aAAa,EAEd,MAAM,eAAe,CAAA;AAMtB,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK1D,eAAO,MAAM,KAAK,EAAE,YA4ChB,CAAA;AAEJ,KAAK,WAAW,GAAG,eAAe,GAChC,kBAAkB,GAClB,wBAAwB,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAA;AAqBpD,eAAO,MAAM,KAAK;;;;;CAUqB,CAAA;AAEvC,eAAO,MAAM,OAAO,EAAE,SAAS,CAAC,WAAW,CAqE1C,CAAA"}
1
+ {"version":3,"file":"query.d.ts","sourceRoot":"","sources":["../../../src/commands/query.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAEV,wBAAwB,EACxB,eAAe,EACf,kBAAkB,EAEnB,MAAM,eAAe,CAAA;AACtB,OAAO,EAGL,mBAAmB,EACnB,UAAU,EACV,aAAa,EAEd,MAAM,eAAe,CAAA;AAOtB,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAK1D,eAAO,MAAM,KAAK,EAAE,YA4EhB,CAAA;AAEJ,KAAK,WAAW,GAAG,eAAe,GAChC,kBAAkB,GAClB,wBAAwB,GAAG;IAAE,WAAW,EAAE,MAAM,CAAA;CAAE,CAAA;AAqBpD,eAAO,MAAM,KAAK;;;;;CAUqB,CAAA;AAEvC,eAAO,MAAM,OAAO,EAAE,SAAS,CAAC,WAAW,CAkG1C,CAAA"}
@@ -1,5 +1,6 @@
1
- import { actual, humanReadableOutput, jsonOutput, mermaidOutput, GraphModifier, } from '@vltpkg/graph';
1
+ import { actual, asNode, humanReadableOutput, jsonOutput, mermaidOutput, GraphModifier, } from '@vltpkg/graph';
2
2
  import { error } from '@vltpkg/error-cause';
3
+ import LZString from 'lz-string';
3
4
  import { Query } from '@vltpkg/query';
4
5
  import { SecurityArchive } from '@vltpkg/security-archive';
5
6
  import { commandUsage } from "../config/usage.js";
@@ -10,12 +11,22 @@ export const usage = () => commandUsage({
10
11
  '',
11
12
  '<query> --view=<human | json | mermaid | gui>',
12
13
  '<query> --expect-results=<comparison string>',
14
+ '--target=<query> --view=<human | json | mermaid | gui>',
13
15
  ],
14
16
  description: `List installed dependencies matching the provided query.
15
17
 
16
- The vlt Dependency Selector Syntax is a CSS-like query language that
17
- allows you to filter installed dependencies using a variety of metadata
18
- in the form of CSS-like attributes, pseudo selectors & combinators.`,
18
+ The vlt Dependency Selector Syntax is a CSS-like query language that
19
+ allows you to filter installed dependencies using a variety of metadata
20
+ in the form of CSS-like attributes, pseudo selectors & combinators.
21
+
22
+ The --scope and --target options accepts DSS query selectors to filter
23
+ packages. Using --scope, you can specify which packages to treat as the
24
+ top-level items in the output graph. The --target option can be used as
25
+ an alternative to positional arguments, it allows you to filter what
26
+ dependencies to include in the output. Using both options allows you to
27
+ render subgraphs of the dependency graph.
28
+
29
+ Defaults to listing all dependencies of the project root and workspaces.`,
19
30
  examples: {
20
31
  [`'#foo'`]: {
21
32
  description: 'Query dependencies declared as "foo"',
@@ -32,12 +43,29 @@ export const usage = () => commandUsage({
32
43
  [`'*:license(copyleft) --expect-results=0'`]: {
33
44
  description: 'Errors if a copyleft licensed package is found',
34
45
  },
46
+ '--scope=":root > #dependency-name"': {
47
+ description: 'Defines a direct dependency as the output top-level scope',
48
+ },
49
+ [`'--target="*"'`]: {
50
+ description: 'Query all dependencies using the target option',
51
+ },
52
+ [`'--target=":workspace > *:peer"'`]: {
53
+ description: 'Query all peer dependencies of workspaces using target option',
54
+ },
35
55
  },
36
56
  options: {
37
57
  'expect-results': {
38
58
  value: '[number | string]',
39
59
  description: 'Sets an expected number of resulting items. Errors if the number of resulting items does not match the set value. Accepts a specific numeric value or a string value starting with either ">", "<", ">=" or "<=" followed by a numeric value to be compared.',
40
60
  },
61
+ scope: {
62
+ value: '<query>',
63
+ description: 'Query selector to select top-level packages using the DSS query language syntax.',
64
+ },
65
+ target: {
66
+ value: '<query>',
67
+ description: 'Query selector to filter packages using DSS syntax.',
68
+ },
41
69
  view: {
42
70
  value: '[human | json | mermaid | gui]',
43
71
  description: 'Output format. Defaults to human-readable or json if no tty.',
@@ -68,7 +96,7 @@ export const views = {
68
96
  mermaid: mermaidOutput,
69
97
  human: humanReadableOutput,
70
98
  gui: async ({ queryString }, _, conf) => {
71
- await startGUI(conf, '/explore?query=' + encodeURIComponent(queryString));
99
+ await startGUI(conf, `/explore/${LZString.compressToEncodedURIComponent(queryString)}/overview`);
72
100
  },
73
101
  };
74
102
  export const command = async (conf) => {
@@ -83,13 +111,13 @@ export const command = async (conf) => {
83
111
  loadManifests: true,
84
112
  });
85
113
  const defaultQueryString = '*';
86
- const queryString = conf.positionals[0];
87
- const securityArchive = queryString && Query.hasSecuritySelectors(queryString) ?
88
- await SecurityArchive.start({
89
- graph,
90
- specOptions: conf.options,
91
- })
92
- : undefined;
114
+ const positionalQueryString = conf.positionals[0];
115
+ const targetQueryString = conf.get('target');
116
+ const queryString = targetQueryString || positionalQueryString;
117
+ const securityArchive = await SecurityArchive.start({
118
+ graph,
119
+ specOptions: conf.options,
120
+ });
93
121
  const query = new Query({
94
122
  graph,
95
123
  specOptions: conf.options,
@@ -97,20 +125,48 @@ export const command = async (conf) => {
97
125
  });
98
126
  const importers = new Set();
99
127
  const scopeIDs = [];
100
- if (monorepo) {
101
- for (const workspace of monorepo.filter(conf.values)) {
102
- const w = graph.nodes.get(workspace.id);
103
- if (w) {
104
- importers.add(w);
105
- scopeIDs.push(workspace.id);
106
- }
128
+ // Handle --scope option to add scope nodes as importers
129
+ const scopeQueryString = conf.get('scope');
130
+ let scopeNodes;
131
+ if (scopeQueryString) {
132
+ // Run scope query to get all matching nodes
133
+ const scopeQuery = new Query({
134
+ graph,
135
+ specOptions: conf.options,
136
+ securityArchive,
137
+ });
138
+ const { nodes } = await scopeQuery.search(scopeQueryString, {
139
+ signal: new AbortController().signal,
140
+ });
141
+ scopeNodes = nodes;
142
+ }
143
+ if (scopeQueryString && scopeNodes) {
144
+ // Add all scope nodes to importers Set (treat them as top-level items)
145
+ for (const queryNode of scopeNodes) {
146
+ importers.add(asNode(queryNode));
107
147
  }
108
148
  }
109
- if (importers.size === 0) {
110
- for (const importer of graph.importers) {
111
- importers.add(importer);
149
+ else {
150
+ // if in a workspace environment, select only the specified
151
+ // workspaces as top-level items
152
+ if (monorepo) {
153
+ for (const workspace of monorepo.filter(conf.values)) {
154
+ const w = graph.nodes.get(workspace.id);
155
+ if (w) {
156
+ importers.add(w);
157
+ scopeIDs.push(workspace.id);
158
+ }
159
+ }
160
+ }
161
+ // if no top-level item was set then by default
162
+ // we just set all importers as top-level items
163
+ if (importers.size === 0) {
164
+ for (const importer of graph.importers) {
165
+ importers.add(importer);
166
+ }
112
167
  }
113
168
  }
169
+ // retrieve the selected nodes and edges
114
170
  const { edges, nodes } = await query.search(queryString || defaultQueryString, {
115
171
  signal: new AbortController().signal,
116
172
  scopeIDs: scopeIDs.length > 0 ? scopeIDs : undefined,
@@ -125,7 +181,7 @@ export const command = async (conf) => {
125
181
  importers,
126
182
  edges,
127
183
  nodes,
128
- highlightSelection: !!queryString,
184
+ highlightSelection: !!(targetQueryString || positionalQueryString),
129
185
  queryString: queryString || defaultQueryString,
130
186
  };
131
187
  };
@@ -1 +1 @@
1
- {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/commands/query.ts"],"names":[],"mappings":"AAOA,OAAO,EACL,MAAM,EACN,mBAAmB,EACnB,UAAU,EACV,aAAa,EACb,aAAa,GACd,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,KAAK,EAAE,MAAM,eAAe,CAAA;AACrC,OAAO,EAAE,eAAe,EAAE,MAAM,0BAA0B,CAAA;AAE1D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAEjD,OAAO,EAAE,QAAQ,EAAE,MAAM,iBAAiB,CAAA;AAI1C,MAAM,CAAC,MAAM,KAAK,GAAiB,GAAG,EAAE,CACtC,YAAY,CAAC;IACX,OAAO,EAAE,OAAO;IAChB,KAAK,EAAE;QACL,EAAE;QACF,+CAA+C;QAC/C,8CAA8C;KAC/C;IACD,WAAW,EAAE;;;;2EAI0D;IACvE,QAAQ,EAAE;QACR,CAAC,QAAQ,CAAC,EAAE;YACV,WAAW,EAAE,sCAAsC;SACpD;QACD,CAAC,wBAAwB,CAAC,EAAE;YAC1B,WAAW,EAAE,2CAA2C;SACzD;QACD,CAAC,uCAAuC,CAAC,EAAE;YACzC,WAAW,EACT,6DAA6D;SAChE;QACD,CAAC,qBAAqB,CAAC,EAAE;YACvB,WAAW,EACT,mDAAmD;SACtD;QACD,CAAC,0CAA0C,CAAC,EAAE;YAC5C,WAAW,EAAE,gDAAgD;SAC9D;KACF;IACD,OAAO,EAAE;QACP,gBAAgB,EAAE;YAChB,KAAK,EAAE,mBAAmB;YAC1B,WAAW,EACT,8PAA8P;SACjQ;QACD,IAAI,EAAE;YACJ,KAAK,EAAE,gCAAgC;YACvC,WAAW,EACT,8DAA8D;SACjE;KACF;CACF,CAAC,CAAA;AAMJ,MAAM,sBAAsB,GAAG,CAC7B,IAAkB,EAClB,KAAiB,EACR,EAAE;IACX,MAAM,aAAa,GAAG,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC,CAAA;IACnD,IAAI,aAAa,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QACpC,OAAO,KAAK,CAAC,MAAM,IAAI,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IACpE,CAAC;SAAM,IAAI,aAAa,EAAE,UAAU,CAAC,IAAI,CAAC,EAAE,CAAC;QAC3C,OAAO,KAAK,CAAC,MAAM,IAAI,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IACpE,CAAC;SAAM,IAAI,aAAa,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IACnE,CAAC;SAAM,IAAI,aAAa,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC1C,OAAO,KAAK,CAAC,MAAM,GAAG,QAAQ,CAAC,aAAa,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IACnE,CAAC;SAAM,IAAI,aAAa,EAAE,CAAC;QACzB,OAAO,KAAK,CAAC,MAAM,KAAK,QAAQ,CAAC,aAAa,CAAC,IAAI,EAAE,EAAE,EAAE,CAAC,CAAA;IAC5D,CAAC;IACD,OAAO,IAAI,CAAA;AACb,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,aAAa;IACtB,KAAK,EAAE,mBAAmB;IAC1B,GAAG,EAAE,KAAK,EAAE,EAAE,WAAW,EAAE,EAAE,CAAC,EAAE,IAAI,EAAE,EAAE;QACtC,MAAM,QAAQ,CACZ,IAAI,EACJ,iBAAiB,GAAG,kBAAkB,CAAC,WAAW,CAAC,CACpD,CAAA;IACH,CAAC;CACoC,CAAA;AAEvC,MAAM,CAAC,MAAM,OAAO,GAA2B,KAAK,EAAC,IAAI,EAAC,EAAE;IAC1D,MAAM,SAAS,GAAG,aAAa,CAAC,SAAS,CAAC,IAAI,CAAC,OAAO,CAAC,CAAA;IACvD,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,QAAQ,CAAA;IACtC,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAChD,IAAI,CAAC,OAAO,CAAC,WAAW,CACzB,CAAA;IACD,MAAM,KAAK,GAAG,MAAM,CAAC,IAAI,CAAC;QACxB,GAAG,IAAI,CAAC,OAAO;QACf,YAAY;QACZ,SAAS;QACT,QAAQ;QACR,aAAa,EAAE,IAAI;KACpB,CAAC,CAAA;IAEF,MAAM,kBAAkB,GAAG,GAAG,CAAA;IAC9B,MAAM,WAAW,GAAG,IAAI,CAAC,WAAW,CAAC,CAAC,CAAC,CAAA;IACvC,MAAM,eAAe,GACnB,WAAW,IAAI,KAAK,CAAC,oBAAoB,CAAC,WAAW,CAAC,CAAC,CAAC;QACtD,MAAM,eAAe,CAAC,KAAK,CAAC;YAC1B,KAAK;YACL,WAAW,EAAE,IAAI,CAAC,OAAO;SAC1B,CAAC;QACJ,CAAC,CAAC,SAAS,CAAA;IACb,MAAM,KAAK,GAAG,IAAI,KAAK,CAAC;QACtB,KAAK;QACL,WAAW,EAAE,IAAI,CAAC,OAAO;QACzB,eAAe;KAChB,CAAC,CAAA;IAEF,MAAM,SAAS,GAAG,IAAI,GAAG,EAAQ,CAAA;IACjC,MAAM,QAAQ,GAAY,EAAE,CAAA;IAE5B,IAAI,QAAQ,EAAE,CAAC;QACb,KAAK,MAAM,SAAS,IAAI,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC;YACrD,MAAM,CAAC,GAAqB,KAAK,CAAC,KAAK,CAAC,GAAG,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;YACzD,IAAI,CAAC,EAAE,CAAC;gBACN,SAAS,CAAC,GAAG,CAAC,CAAC,CAAC,CAAA;gBAChB,QAAQ,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,CAAC,CAAA;YAC7B,CAAC;QACH,CAAC;IACH,CAAC;IACD,IAAI,SAAS,CAAC,IAAI,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,MAAM,QAAQ,IAAI,KAAK,CAAC,SAAS,EAAE,CAAC;YACvC,SAAS,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAA;QACzB,CAAC;IACH,CAAC;IAED,MAAM,EAAE,KAAK,EAAE,KAAK,EAAE,GAAG,MAAM,KAAK,CAAC,MAAM,CACzC,WAAW,IAAI,kBAAkB,EACjC;QACE,MAAM,EAAE,IAAI,eAAe,EAAE,CAAC,MAAM;QACpC,QAAQ,EAAE,QAAQ,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,SAAS;KACrD,CACF,CAAA;IAED,IAAI,CAAC,sBAAsB,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,CAAC;QACzC,MAAM,KAAK,CAAC,4BAA4B,EAAE;YACxC,KAAK,EAAE,KAAK,CAAC,MAAM;YACnB,MAAM,EAAE,IAAI,CAAC,MAAM,CAAC,gBAAgB,CAAC;SACtC,CAAC,CAAA;IACJ,CAAC;IAED,OAAO;QACL,SAAS;QACT,KAAK;QACL,KAAK;QACL,kBAAkB,EAAE,CAAC,CAAC,WAAW;QACjC,WAAW,EAAE,WAAW,IAAI,kBAAkB;KAC/C,CAAA;AACH,CAAC,CAAA","sourcesContent":["import type {\n EdgeLike,\n HumanReadableOutputGraph,\n JSONOutputGraph,\n MermaidOutputGraph,\n Node,\n} from '@vltpkg/graph'\nimport {\n actual,\n humanReadableOutput,\n jsonOutput,\n mermaidOutput,\n GraphModifier,\n} from '@vltpkg/graph'\nimport { error } from '@vltpkg/error-cause'\nimport { Query } from '@vltpkg/query'\nimport { SecurityArchive } from '@vltpkg/security-archive'\nimport type { DepID } from '@vltpkg/dep-id'\nimport { commandUsage } from '../config/usage.ts'\nimport type { CommandFn, CommandUsage } from '../index.ts'\nimport { startGUI } from '../start-gui.ts'\nimport type { Views } from '../view.ts'\nimport type { LoadedConfig } from '../config/index.js'\n\nexport const usage: CommandUsage = () =>\n commandUsage({\n command: 'query',\n usage: [\n '',\n '<query> --view=<human | json | mermaid | gui>',\n '<query> --expect-results=<comparison string>',\n ],\n description: `List installed dependencies matching the provided query.\n\n The vlt Dependency Selector Syntax is a CSS-like query language that\n allows you to filter installed dependencies using a variety of metadata\n in the form of CSS-like attributes, pseudo selectors & combinators.`,\n examples: {\n [`'#foo'`]: {\n description: 'Query dependencies declared as \"foo\"',\n },\n [`'*:workspace > *:peer'`]: {\n description: 'Query all peer dependencies of workspaces',\n },\n [`':project > *:attr(scripts, [build])'`]: {\n description:\n 'Query all direct project dependencies with a \"build\" script',\n },\n [`'[name^=\"@vltpkg\"]'`]: {\n description:\n 'Query packages with names starting with \"@vltpkg\"',\n },\n [`'*:license(copyleft) --expect-results=0'`]: {\n description: 'Errors if a copyleft licensed package is found',\n },\n },\n options: {\n 'expect-results': {\n value: '[number | string]',\n description:\n 'Sets an expected number of resulting items. Errors if the number of resulting items does not match the set value. Accepts a specific numeric value or a string value starting with either \">\", \"<\", \">=\" or \"<=\" followed by a numeric value to be compared.',\n },\n view: {\n value: '[human | json | mermaid | gui]',\n description:\n 'Output format. Defaults to human-readable or json if no tty.',\n },\n },\n })\n\ntype QueryResult = JSONOutputGraph &\n MermaidOutputGraph &\n HumanReadableOutputGraph & { queryString: string }\n\nconst validateExpectedResult = (\n conf: LoadedConfig,\n edges: EdgeLike[],\n): boolean => {\n const expectResults = conf.values['expect-results']\n if (expectResults?.startsWith('>=')) {\n return edges.length >= parseInt(expectResults.slice(2).trim(), 10)\n } else if (expectResults?.startsWith('<=')) {\n return edges.length <= parseInt(expectResults.slice(2).trim(), 10)\n } else if (expectResults?.startsWith('>')) {\n return edges.length > parseInt(expectResults.slice(1).trim(), 10)\n } else if (expectResults?.startsWith('<')) {\n return edges.length < parseInt(expectResults.slice(1).trim(), 10)\n } else if (expectResults) {\n return edges.length === parseInt(expectResults.trim(), 10)\n }\n return true\n}\n\nexport const views = {\n json: jsonOutput,\n mermaid: mermaidOutput,\n human: humanReadableOutput,\n gui: async ({ queryString }, _, conf) => {\n await startGUI(\n conf,\n '/explore?query=' + encodeURIComponent(queryString),\n )\n },\n} as const satisfies Views<QueryResult>\n\nexport const command: CommandFn<QueryResult> = async conf => {\n const modifiers = GraphModifier.maybeLoad(conf.options)\n const monorepo = conf.options.monorepo\n const mainManifest = conf.options.packageJson.read(\n conf.options.projectRoot,\n )\n const graph = actual.load({\n ...conf.options,\n mainManifest,\n modifiers,\n monorepo,\n loadManifests: true,\n })\n\n const defaultQueryString = '*'\n const queryString = conf.positionals[0]\n const securityArchive =\n queryString && Query.hasSecuritySelectors(queryString) ?\n await SecurityArchive.start({\n graph,\n specOptions: conf.options,\n })\n : undefined\n const query = new Query({\n graph,\n specOptions: conf.options,\n securityArchive,\n })\n\n const importers = new Set<Node>()\n const scopeIDs: DepID[] = []\n\n if (monorepo) {\n for (const workspace of monorepo.filter(conf.values)) {\n const w: Node | undefined = graph.nodes.get(workspace.id)\n if (w) {\n importers.add(w)\n scopeIDs.push(workspace.id)\n }\n }\n }\n if (importers.size === 0) {\n for (const importer of graph.importers) {\n importers.add(importer)\n }\n }\n\n const { edges, nodes } = await query.search(\n queryString || defaultQueryString,\n {\n signal: new AbortController().signal,\n scopeIDs: scopeIDs.length > 0 ? scopeIDs : undefined,\n },\n )\n\n if (!validateExpectedResult(conf, edges)) {\n throw error('Unexpected number of items', {\n found: edges.length,\n wanted: conf.values['expect-results'],\n })\n }\n\n return {\n importers,\n edges,\n nodes,\n highlightSelection: !!queryString,\n queryString: queryString || defaultQueryString,\n }\n}\n"]}
1
+ {"version":3,"file":"query.js","sourceRoot":"","sources":["../../../src/commands/query.ts"],"names":[],"mappings":"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","sourcesContent":["import type {\n EdgeLike,\n HumanReadableOutputGraph,\n JSONOutputGraph,\n MermaidOutputGraph,\n Node,\n} from '@vltpkg/graph'\nimport {\n actual,\n asNode,\n humanReadableOutput,\n jsonOutput,\n mermaidOutput,\n GraphModifier,\n} from '@vltpkg/graph'\nimport { error } from '@vltpkg/error-cause'\nimport LZString from 'lz-string'\nimport { Query } from '@vltpkg/query'\nimport { SecurityArchive } from '@vltpkg/security-archive'\nimport type { DepID } from '@vltpkg/dep-id'\nimport { commandUsage } from '../config/usage.ts'\nimport type { CommandFn, CommandUsage } from '../index.ts'\nimport { startGUI } from '../start-gui.ts'\nimport type { Views } from '../view.ts'\nimport type { LoadedConfig } from '../config/index.ts'\n\nexport const usage: CommandUsage = () =>\n commandUsage({\n command: 'query',\n usage: [\n '',\n '<query> --view=<human | json | mermaid | gui>',\n '<query> --expect-results=<comparison string>',\n '--target=<query> --view=<human | json | mermaid | gui>',\n ],\n description: `List installed dependencies matching the provided query.\n\n The vlt Dependency Selector Syntax is a CSS-like query language that\n allows you to filter installed dependencies using a variety of metadata\n in the form of CSS-like attributes, pseudo selectors & combinators.\n\n The --scope and --target options accepts DSS query selectors to filter\n packages. Using --scope, you can specify which packages to treat as the\n top-level items in the output graph. The --target option can be used as\n an alternative to positional arguments, it allows you to filter what\n dependencies to include in the output. Using both options allows you to\n render subgraphs of the dependency graph.\n\n Defaults to listing all dependencies of the project root and workspaces.`,\n\n examples: {\n [`'#foo'`]: {\n description: 'Query dependencies declared as \"foo\"',\n },\n [`'*:workspace > *:peer'`]: {\n description: 'Query all peer dependencies of workspaces',\n },\n [`':project > *:attr(scripts, [build])'`]: {\n description:\n 'Query all direct project dependencies with a \"build\" script',\n },\n [`'[name^=\"@vltpkg\"]'`]: {\n description:\n 'Query packages with names starting with \"@vltpkg\"',\n },\n [`'*:license(copyleft) --expect-results=0'`]: {\n description: 'Errors if a copyleft licensed package is found',\n },\n '--scope=\":root > #dependency-name\"': {\n description:\n 'Defines a direct dependency as the output top-level scope',\n },\n [`'--target=\"*\"'`]: {\n description: 'Query all dependencies using the target option',\n },\n [`'--target=\":workspace > *:peer\"'`]: {\n description:\n 'Query all peer dependencies of workspaces using target option',\n },\n },\n options: {\n 'expect-results': {\n value: '[number | string]',\n description:\n 'Sets an expected number of resulting items. Errors if the number of resulting items does not match the set value. Accepts a specific numeric value or a string value starting with either \">\", \"<\", \">=\" or \"<=\" followed by a numeric value to be compared.',\n },\n scope: {\n value: '<query>',\n description:\n 'Query selector to select top-level packages using the DSS query language syntax.',\n },\n target: {\n value: '<query>',\n description:\n 'Query selector to filter packages using DSS syntax.',\n },\n view: {\n value: '[human | json | mermaid | gui]',\n description:\n 'Output format. Defaults to human-readable or json if no tty.',\n },\n },\n })\n\ntype QueryResult = JSONOutputGraph &\n MermaidOutputGraph &\n HumanReadableOutputGraph & { queryString: string }\n\nconst validateExpectedResult = (\n conf: LoadedConfig,\n edges: EdgeLike[],\n): boolean => {\n const expectResults = conf.values['expect-results']\n if (expectResults?.startsWith('>=')) {\n return edges.length >= parseInt(expectResults.slice(2).trim(), 10)\n } else if (expectResults?.startsWith('<=')) {\n return edges.length <= parseInt(expectResults.slice(2).trim(), 10)\n } else if (expectResults?.startsWith('>')) {\n return edges.length > parseInt(expectResults.slice(1).trim(), 10)\n } else if (expectResults?.startsWith('<')) {\n return edges.length < parseInt(expectResults.slice(1).trim(), 10)\n } else if (expectResults) {\n return edges.length === parseInt(expectResults.trim(), 10)\n }\n return true\n}\n\nexport const views = {\n json: jsonOutput,\n mermaid: mermaidOutput,\n human: humanReadableOutput,\n gui: async ({ queryString }, _, conf) => {\n await startGUI(\n conf,\n `/explore/${LZString.compressToEncodedURIComponent(queryString)}/overview`,\n )\n },\n} as const satisfies Views<QueryResult>\n\nexport const command: CommandFn<QueryResult> = async conf => {\n const modifiers = GraphModifier.maybeLoad(conf.options)\n const monorepo = conf.options.monorepo\n const mainManifest = conf.options.packageJson.read(\n conf.options.projectRoot,\n )\n const graph = actual.load({\n ...conf.options,\n mainManifest,\n modifiers,\n monorepo,\n loadManifests: true,\n })\n\n const defaultQueryString = '*'\n const positionalQueryString = conf.positionals[0]\n const targetQueryString = conf.get('target')\n const queryString = targetQueryString || positionalQueryString\n const securityArchive = await SecurityArchive.start({\n graph,\n specOptions: conf.options,\n })\n const query = new Query({\n graph,\n specOptions: conf.options,\n securityArchive,\n })\n\n const importers = new Set<Node>()\n const scopeIDs: DepID[] = []\n\n // Handle --scope option to add scope nodes as importers\n const scopeQueryString = conf.get('scope')\n let scopeNodes\n if (scopeQueryString) {\n // Run scope query to get all matching nodes\n const scopeQuery = new Query({\n graph,\n specOptions: conf.options,\n securityArchive,\n })\n const { nodes } = await scopeQuery.search(scopeQueryString, {\n signal: new AbortController().signal,\n })\n scopeNodes = nodes\n }\n\n if (scopeQueryString && scopeNodes) {\n // Add all scope nodes to importers Set (treat them as top-level items)\n for (const queryNode of scopeNodes) {\n importers.add(asNode(queryNode))\n }\n } else {\n // if in a workspace environment, select only the specified\n // workspaces as top-level items\n if (monorepo) {\n for (const workspace of monorepo.filter(conf.values)) {\n const w: Node | undefined = graph.nodes.get(workspace.id)\n if (w) {\n importers.add(w)\n scopeIDs.push(workspace.id)\n }\n }\n }\n // if no top-level item was set then by default\n // we just set all importers as top-level items\n if (importers.size === 0) {\n for (const importer of graph.importers) {\n importers.add(importer)\n }\n }\n }\n\n // retrieve the selected nodes and edges\n const { edges, nodes } = await query.search(\n queryString || defaultQueryString,\n {\n signal: new AbortController().signal,\n scopeIDs: scopeIDs.length > 0 ? scopeIDs : undefined,\n },\n )\n\n if (!validateExpectedResult(conf, edges)) {\n throw error('Unexpected number of items', {\n found: edges.length,\n wanted: conf.values['expect-results'],\n })\n }\n\n return {\n importers,\n edges,\n nodes,\n highlightSelection: !!(\n targetQueryString || positionalQueryString\n ),\n queryString: queryString || defaultQueryString,\n }\n}\n"]}
@@ -0,0 +1,22 @@
1
+ import type { CommandFn, CommandUsage } from '../index.ts';
2
+ export type VersionOptions = {
3
+ prereleaseId?: string;
4
+ commit?: boolean;
5
+ tag?: boolean;
6
+ message?: string;
7
+ tagMessage?: string;
8
+ };
9
+ export type VersionResult = {
10
+ oldVersion: string;
11
+ newVersion: string;
12
+ dir: string;
13
+ committed?: string[];
14
+ tag?: string;
15
+ };
16
+ export declare const usage: CommandUsage;
17
+ export declare const views: {
18
+ readonly json: (result: VersionResult) => VersionResult;
19
+ readonly human: (result: VersionResult) => string;
20
+ };
21
+ export declare const command: CommandFn<VersionResult>;
22
+ //# sourceMappingURL=version.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.d.ts","sourceRoot":"","sources":["../../../src/commands/version.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,SAAS,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAM1D,MAAM,MAAM,cAAc,GAAG;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAA;IACrB,MAAM,CAAC,EAAE,OAAO,CAAA;IAChB,GAAG,CAAC,EAAE,OAAO,CAAA;IACb,OAAO,CAAC,EAAE,MAAM,CAAA;IAChB,UAAU,CAAC,EAAE,MAAM,CAAA;CACpB,CAAA;AAED,MAAM,MAAM,aAAa,GAAG;IAC1B,UAAU,EAAE,MAAM,CAAA;IAClB,UAAU,EAAE,MAAM,CAAA;IAClB,GAAG,EAAE,MAAM,CAAA;IACX,SAAS,CAAC,EAAE,MAAM,EAAE,CAAA;IACpB,GAAG,CAAC,EAAE,MAAM,CAAA;CACb,CAAA;AAoKD,eAAO,MAAM,KAAK,EAAE,YAanB,CAAA;AAED,eAAO,MAAM,KAAK;;;CAYuB,CAAA;AAEzC,eAAO,MAAM,OAAO,EAAE,SAAS,CAAC,aAAa,CAG5C,CAAA"}
@@ -0,0 +1,151 @@
1
+ import { inc, parse as parseVersion, versionIncrements, } from '@vltpkg/semver';
2
+ import { is as isGit, spawn as spawn_, isClean } from '@vltpkg/git';
3
+ import { error } from '@vltpkg/error-cause';
4
+ import { asError } from '@vltpkg/types';
5
+ import { commandUsage } from "../config/usage.js";
6
+ import { dirname } from 'node:path';
7
+ import assert from 'node:assert';
8
+ const isValidVersionIncrement = (value) => versionIncrements.includes(value);
9
+ const version = async (conf, increment, cwd, {
10
+ // Hardcode happy path options for now.
11
+ // TODO: make these config definitions
12
+ prereleaseId = 'pre', commit = true, tag = true, message = 'v%s', tagMessage = 'v%s', } = {}) => {
13
+ assert(increment, error('Version increment argument is required', {
14
+ code: 'EUSAGE',
15
+ validOptions: versionIncrements,
16
+ }));
17
+ const manifestPath = conf.options.packageJson.find(cwd);
18
+ assert(manifestPath, error('No package.json found', {
19
+ code: 'ENOENT',
20
+ path: cwd,
21
+ }));
22
+ const spawn = (args, opts) => spawn_(args, { cwd: manifestDir, ...opts });
23
+ const manifestDir = dirname(manifestPath);
24
+ const manifest = conf.options.packageJson.read(manifestDir);
25
+ assert(manifest.version, error('No version field found in package.json', {
26
+ path: manifestPath,
27
+ }));
28
+ const oldVersion = manifest.version;
29
+ let newVersion;
30
+ // Check if increment is a valid semver version string
31
+ const parsedIncrement = parseVersion(increment);
32
+ if (parsedIncrement) {
33
+ newVersion = parsedIncrement.toString();
34
+ }
35
+ else if (isValidVersionIncrement(increment)) {
36
+ // Use semver increment
37
+ const incrementType = increment;
38
+ try {
39
+ const result = inc(oldVersion, incrementType, prereleaseId);
40
+ newVersion = result.toString();
41
+ }
42
+ catch (err) {
43
+ throw error(`Failed to increment version from ${oldVersion} with ${increment}`, { version: oldVersion, wanted: increment, cause: err });
44
+ }
45
+ }
46
+ else {
47
+ throw error(`Invalid version increment: ${increment}. Must be a valid semver version or one of: major, minor, patch, premajor, preminor, prepatch, prerelease`, {
48
+ found: increment,
49
+ validOptions: versionIncrements,
50
+ });
51
+ }
52
+ // Update the manifest
53
+ manifest.version = newVersion;
54
+ conf.options.packageJson.write(manifestDir, manifest);
55
+ const result = {
56
+ oldVersion,
57
+ newVersion,
58
+ dir: manifestDir,
59
+ };
60
+ // Handle git operations if we're in a git repository
61
+ if (
62
+ /* c8 ignore next -- commit and tag are always true for now */
63
+ (commit || tag) &&
64
+ (await isGit({ cwd: conf.options.projectRoot }))) {
65
+ // Check for uncommitted changes (excluding package.json since we just modified it)
66
+ if (!(await isClean({ cwd: conf.options.projectRoot }))) {
67
+ try {
68
+ // Check if there are changes other than package.json
69
+ const gitResult = await spawn(['diff', '--name-only', 'HEAD']);
70
+ const changedFiles = gitResult.stdout
71
+ .trim()
72
+ .split('\n')
73
+ .filter(Boolean);
74
+ const nonPackageJsonChanges = changedFiles.filter(file => file !== 'package.json');
75
+ assert(nonPackageJsonChanges.length === 0, error('Git working directory not clean. Please commit or stash your changes first.', { found: nonPackageJsonChanges }));
76
+ }
77
+ catch (err) {
78
+ throw error('Git working directory not clean. Please commit or stash your changes first.', asError(err));
79
+ }
80
+ }
81
+ if (commit) {
82
+ try {
83
+ // Stage package.json
84
+ const files = ['package.json'];
85
+ await spawn(['add', ...files]);
86
+ await spawn([
87
+ 'commit',
88
+ '-m',
89
+ message.replace('%s', newVersion),
90
+ ]);
91
+ result.committed = files;
92
+ }
93
+ catch (err) {
94
+ throw error('Failed to commit version changes', {
95
+ version: newVersion,
96
+ cause: err,
97
+ });
98
+ }
99
+ }
100
+ if (tag) {
101
+ try {
102
+ const tagName = `v${newVersion}`;
103
+ await spawn([
104
+ 'tag',
105
+ tagName,
106
+ '-m',
107
+ tagMessage.replace('%s', newVersion),
108
+ ]);
109
+ result.tag = tagName;
110
+ }
111
+ catch (err) {
112
+ throw error('Failed to create git tag', {
113
+ version: newVersion,
114
+ cause: err,
115
+ });
116
+ }
117
+ }
118
+ }
119
+ return result;
120
+ };
121
+ export const usage = () => {
122
+ return commandUsage({
123
+ command: 'version',
124
+ usage: '[<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease]',
125
+ description: `Bump a package's version.
126
+
127
+ Run in a package directory to bump the version and write the new data back to package.json.
128
+
129
+ The \`<newversion>\` argument should be a valid semver string or a valid increment type (one of patch, minor, major, prepatch, preminor, premajor, prerelease).
130
+
131
+ If run in a git repository, it will also create a version commit and tag.`,
132
+ });
133
+ };
134
+ export const views = {
135
+ json: result => result,
136
+ human: result => {
137
+ let output = `v${result.newVersion}`;
138
+ if (result.committed) {
139
+ output += ` +commit`;
140
+ }
141
+ if (result.tag) {
142
+ output += ` +tag`;
143
+ }
144
+ return output;
145
+ },
146
+ };
147
+ export const command = async (conf) => {
148
+ const { positionals } = conf;
149
+ return version(conf, positionals[0], process.cwd());
150
+ };
151
+ //# sourceMappingURL=version.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"version.js","sourceRoot":"","sources":["../../../src/commands/version.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,GAAG,EACH,KAAK,IAAI,YAAY,EACrB,iBAAiB,GAClB,MAAM,gBAAgB,CAAA;AAEvB,OAAO,EAAE,EAAE,IAAI,KAAK,EAAE,KAAK,IAAI,MAAM,EAAE,OAAO,EAAE,MAAM,aAAa,CAAA;AAEnE,OAAO,EAAE,KAAK,EAAE,MAAM,qBAAqB,CAAA;AAC3C,OAAO,EAAE,OAAO,EAAE,MAAM,eAAe,CAAA;AACvC,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAA;AAIjD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAA;AACnC,OAAO,MAAM,MAAM,aAAa,CAAA;AAkBhC,MAAM,uBAAuB,GAAG,CAC9B,KAAa,EACW,EAAE,CAC1B,iBAAiB,CAAC,QAAQ,CAAC,KAAsB,CAAC,CAAA;AAEpD,MAAM,OAAO,GAAG,KAAK,EACnB,IAAkB,EAClB,SAA6B,EAC7B,GAAW,EACX;AACE,uCAAuC;AACvC,sCAAsC;AACtC,YAAY,GAAG,KAAK,EACpB,MAAM,GAAG,IAAI,EACb,GAAG,GAAG,IAAI,EACV,OAAO,GAAG,KAAK,EACf,UAAU,GAAG,KAAK,MACA,EAAE,EACE,EAAE;IAC1B,MAAM,CACJ,SAAS,EACT,KAAK,CAAC,wCAAwC,EAAE;QAC9C,IAAI,EAAE,QAAQ;QACd,YAAY,EAAE,iBAAiB;KAChC,CAAC,CACH,CAAA;IAED,MAAM,YAAY,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,GAAG,CAAC,CAAA;IACvD,MAAM,CACJ,YAAY,EACZ,KAAK,CAAC,uBAAuB,EAAE;QAC7B,IAAI,EAAE,QAAQ;QACd,IAAI,EAAE,GAAG;KACV,CAAC,CACH,CAAA;IAED,MAAM,KAAK,GAAG,CAAC,IAAc,EAAE,IAAiB,EAAE,EAAE,CAClD,MAAM,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,WAAW,EAAE,GAAG,IAAI,EAAE,CAAC,CAAA;IAE7C,MAAM,WAAW,GAAG,OAAO,CAAC,YAAY,CAAC,CAAA;IACzC,MAAM,QAAQ,GAAG,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,IAAI,CAAC,WAAW,CAAC,CAAA;IAE3D,MAAM,CACJ,QAAQ,CAAC,OAAO,EAChB,KAAK,CAAC,wCAAwC,EAAE;QAC9C,IAAI,EAAE,YAAY;KACnB,CAAC,CACH,CAAA;IAED,MAAM,UAAU,GAAG,QAAQ,CAAC,OAAO,CAAA;IACnC,IAAI,UAAkB,CAAA;IAEtB,sDAAsD;IACtD,MAAM,eAAe,GAAG,YAAY,CAAC,SAAS,CAAC,CAAA;IAC/C,IAAI,eAAe,EAAE,CAAC;QACpB,UAAU,GAAG,eAAe,CAAC,QAAQ,EAAE,CAAA;IACzC,CAAC;SAAM,IAAI,uBAAuB,CAAC,SAAS,CAAC,EAAE,CAAC;QAC9C,uBAAuB;QACvB,MAAM,aAAa,GAAG,SAAS,CAAA;QAC/B,IAAI,CAAC;YACH,MAAM,MAAM,GAAG,GAAG,CAAC,UAAU,EAAE,aAAa,EAAE,YAAY,CAAC,CAAA;YAC3D,UAAU,GAAG,MAAM,CAAC,QAAQ,EAAE,CAAA;QAChC,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACb,MAAM,KAAK,CACT,oCAAoC,UAAU,SAAS,SAAS,EAAE,EAClE,EAAE,OAAO,EAAE,UAAU,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,GAAG,EAAE,CACvD,CAAA;QACH,CAAC;IACH,CAAC;SAAM,CAAC;QACN,MAAM,KAAK,CACT,8BAA8B,SAAS,2GAA2G,EAClJ;YACE,KAAK,EAAE,SAAS;YAChB,YAAY,EAAE,iBAAiB;SAChC,CACF,CAAA;IACH,CAAC;IAED,sBAAsB;IACtB,QAAQ,CAAC,OAAO,GAAG,UAAU,CAAA;IAC7B,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAA;IAErD,MAAM,MAAM,GAAkB;QAC5B,UAAU;QACV,UAAU;QACV,GAAG,EAAE,WAAW;KACjB,CAAA;IAED,qDAAqD;IACrD;IACE,8DAA8D;IAC9D,CAAC,MAAM,IAAI,GAAG,CAAC;QACf,CAAC,MAAM,KAAK,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAChD,CAAC;QACD,mFAAmF;QACnF,IAAI,CAAC,CAAC,MAAM,OAAO,CAAC,EAAE,GAAG,EAAE,IAAI,CAAC,OAAO,CAAC,WAAW,EAAE,CAAC,CAAC,EAAE,CAAC;YACxD,IAAI,CAAC;gBACH,qDAAqD;gBACrD,MAAM,SAAS,GAAG,MAAM,KAAK,CAAC,CAAC,MAAM,EAAE,aAAa,EAAE,MAAM,CAAC,CAAC,CAAA;gBAC9D,MAAM,YAAY,GAAG,SAAS,CAAC,MAAM;qBAClC,IAAI,EAAE;qBACN,KAAK,CAAC,IAAI,CAAC;qBACX,MAAM,CAAC,OAAO,CAAC,CAAA;gBAClB,MAAM,qBAAqB,GAAG,YAAY,CAAC,MAAM,CAC/C,IAAI,CAAC,EAAE,CAAC,IAAI,KAAK,cAAc,CAChC,CAAA;gBACD,MAAM,CACJ,qBAAqB,CAAC,MAAM,KAAK,CAAC,EAClC,KAAK,CACH,6EAA6E,EAC7E,EAAE,KAAK,EAAE,qBAAqB,EAAE,CACjC,CACF,CAAA;YACH,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,KAAK,CACT,6EAA6E,EAC7E,OAAO,CAAC,GAAG,CAAC,CACb,CAAA;YACH,CAAC;QACH,CAAC;QAED,IAAI,MAAM,EAAE,CAAC;YACX,IAAI,CAAC;gBACH,qBAAqB;gBACrB,MAAM,KAAK,GAAG,CAAC,cAAc,CAAC,CAAA;gBAC9B,MAAM,KAAK,CAAC,CAAC,KAAK,EAAE,GAAG,KAAK,CAAC,CAAC,CAAA;gBAC9B,MAAM,KAAK,CAAC;oBACV,QAAQ;oBACR,IAAI;oBACJ,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC;iBAClC,CAAC,CAAA;gBACF,MAAM,CAAC,SAAS,GAAG,KAAK,CAAA;YAC1B,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,KAAK,CAAC,kCAAkC,EAAE;oBAC9C,OAAO,EAAE,UAAU;oBACnB,KAAK,EAAE,GAAG;iBACX,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;QAED,IAAI,GAAG,EAAE,CAAC;YACR,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,IAAI,UAAU,EAAE,CAAA;gBAChC,MAAM,KAAK,CAAC;oBACV,KAAK;oBACL,OAAO;oBACP,IAAI;oBACJ,UAAU,CAAC,OAAO,CAAC,IAAI,EAAE,UAAU,CAAC;iBACrC,CAAC,CAAA;gBACF,MAAM,CAAC,GAAG,GAAG,OAAO,CAAA;YACtB,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,MAAM,KAAK,CAAC,0BAA0B,EAAE;oBACtC,OAAO,EAAE,UAAU;oBACnB,KAAK,EAAE,GAAG;iBACX,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAA;AACf,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAiB,GAAG,EAAE;IACtC,OAAO,YAAY,CAAC;QAClB,OAAO,EAAE,SAAS;QAClB,KAAK,EACH,sFAAsF;QACxF,WAAW,EAAE;;;;;;8EAM6D;KAC3E,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,KAAK,GAAG;IACnB,IAAI,EAAE,MAAM,CAAC,EAAE,CAAC,MAAM;IACtB,KAAK,EAAE,MAAM,CAAC,EAAE;QACd,IAAI,MAAM,GAAG,IAAI,MAAM,CAAC,UAAU,EAAE,CAAA;QACpC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACrB,MAAM,IAAI,UAAU,CAAA;QACtB,CAAC;QACD,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC;YACf,MAAM,IAAI,OAAO,CAAA;QACnB,CAAC;QACD,OAAO,MAAM,CAAA;IACf,CAAC;CACsC,CAAA;AAEzC,MAAM,CAAC,MAAM,OAAO,GAA6B,KAAK,EAAC,IAAI,EAAC,EAAE;IAC5D,MAAM,EAAE,WAAW,EAAE,GAAG,IAAI,CAAA;IAC5B,OAAO,OAAO,CAAC,IAAI,EAAE,WAAW,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC,CAAA;AACrD,CAAC,CAAA","sourcesContent":["import {\n inc,\n parse as parseVersion,\n versionIncrements,\n} from '@vltpkg/semver'\nimport type { IncrementType } from '@vltpkg/semver'\nimport { is as isGit, spawn as spawn_, isClean } from '@vltpkg/git'\nimport type { GitOptions } from '@vltpkg/git'\nimport { error } from '@vltpkg/error-cause'\nimport { asError } from '@vltpkg/types'\nimport { commandUsage } from '../config/usage.ts'\nimport type { CommandFn, CommandUsage } from '../index.ts'\nimport type { Views } from '../view.ts'\nimport type { ParsedConfig } from '../config/index.ts'\nimport { dirname } from 'node:path'\nimport assert from 'node:assert'\n\nexport type VersionOptions = {\n prereleaseId?: string\n commit?: boolean\n tag?: boolean\n message?: string\n tagMessage?: string\n}\n\nexport type VersionResult = {\n oldVersion: string\n newVersion: string\n dir: string\n committed?: string[]\n tag?: string\n}\n\nconst isValidVersionIncrement = (\n value: string,\n): value is IncrementType =>\n versionIncrements.includes(value as IncrementType)\n\nconst version = async (\n conf: ParsedConfig,\n increment: string | undefined,\n cwd: string,\n {\n // Hardcode happy path options for now.\n // TODO: make these config definitions\n prereleaseId = 'pre',\n commit = true,\n tag = true,\n message = 'v%s',\n tagMessage = 'v%s',\n }: VersionOptions = {},\n): Promise<VersionResult> => {\n assert(\n increment,\n error('Version increment argument is required', {\n code: 'EUSAGE',\n validOptions: versionIncrements,\n }),\n )\n\n const manifestPath = conf.options.packageJson.find(cwd)\n assert(\n manifestPath,\n error('No package.json found', {\n code: 'ENOENT',\n path: cwd,\n }),\n )\n\n const spawn = (args: string[], opts?: GitOptions) =>\n spawn_(args, { cwd: manifestDir, ...opts })\n\n const manifestDir = dirname(manifestPath)\n const manifest = conf.options.packageJson.read(manifestDir)\n\n assert(\n manifest.version,\n error('No version field found in package.json', {\n path: manifestPath,\n }),\n )\n\n const oldVersion = manifest.version\n let newVersion: string\n\n // Check if increment is a valid semver version string\n const parsedIncrement = parseVersion(increment)\n if (parsedIncrement) {\n newVersion = parsedIncrement.toString()\n } else if (isValidVersionIncrement(increment)) {\n // Use semver increment\n const incrementType = increment\n try {\n const result = inc(oldVersion, incrementType, prereleaseId)\n newVersion = result.toString()\n } catch (err) {\n throw error(\n `Failed to increment version from ${oldVersion} with ${increment}`,\n { version: oldVersion, wanted: increment, cause: err },\n )\n }\n } else {\n throw error(\n `Invalid version increment: ${increment}. Must be a valid semver version or one of: major, minor, patch, premajor, preminor, prepatch, prerelease`,\n {\n found: increment,\n validOptions: versionIncrements,\n },\n )\n }\n\n // Update the manifest\n manifest.version = newVersion\n conf.options.packageJson.write(manifestDir, manifest)\n\n const result: VersionResult = {\n oldVersion,\n newVersion,\n dir: manifestDir,\n }\n\n // Handle git operations if we're in a git repository\n if (\n /* c8 ignore next -- commit and tag are always true for now */\n (commit || tag) &&\n (await isGit({ cwd: conf.options.projectRoot }))\n ) {\n // Check for uncommitted changes (excluding package.json since we just modified it)\n if (!(await isClean({ cwd: conf.options.projectRoot }))) {\n try {\n // Check if there are changes other than package.json\n const gitResult = await spawn(['diff', '--name-only', 'HEAD'])\n const changedFiles = gitResult.stdout\n .trim()\n .split('\\n')\n .filter(Boolean)\n const nonPackageJsonChanges = changedFiles.filter(\n file => file !== 'package.json',\n )\n assert(\n nonPackageJsonChanges.length === 0,\n error(\n 'Git working directory not clean. Please commit or stash your changes first.',\n { found: nonPackageJsonChanges },\n ),\n )\n } catch (err) {\n throw error(\n 'Git working directory not clean. Please commit or stash your changes first.',\n asError(err),\n )\n }\n }\n\n if (commit) {\n try {\n // Stage package.json\n const files = ['package.json']\n await spawn(['add', ...files])\n await spawn([\n 'commit',\n '-m',\n message.replace('%s', newVersion),\n ])\n result.committed = files\n } catch (err) {\n throw error('Failed to commit version changes', {\n version: newVersion,\n cause: err,\n })\n }\n }\n\n if (tag) {\n try {\n const tagName = `v${newVersion}`\n await spawn([\n 'tag',\n tagName,\n '-m',\n tagMessage.replace('%s', newVersion),\n ])\n result.tag = tagName\n } catch (err) {\n throw error('Failed to create git tag', {\n version: newVersion,\n cause: err,\n })\n }\n }\n }\n\n return result\n}\n\nexport const usage: CommandUsage = () => {\n return commandUsage({\n command: 'version',\n usage:\n '[<newversion> | major | minor | patch | premajor | preminor | prepatch | prerelease]',\n description: `Bump a package's version.\n\n Run in a package directory to bump the version and write the new data back to package.json.\n\n The \\`<newversion>\\` argument should be a valid semver string or a valid increment type (one of patch, minor, major, prepatch, preminor, premajor, prerelease).\n\n If run in a git repository, it will also create a version commit and tag.`,\n })\n}\n\nexport const views = {\n json: result => result,\n human: result => {\n let output = `v${result.newVersion}`\n if (result.committed) {\n output += ` +commit`\n }\n if (result.tag) {\n output += ` +tag`\n }\n return output\n },\n} as const satisfies Views<VersionResult>\n\nexport const command: CommandFn<VersionResult> = async conf => {\n const { positionals } = conf\n return version(conf, positionals[0], process.cwd())\n}\n"]}