yeoman-environment 4.0.0-alpha.4 → 4.0.0-alpha.6

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 (86) hide show
  1. package/bin/bin.cjs +4 -0
  2. package/dist/cli/index.d.ts +0 -1
  3. package/dist/cli/index.js +18 -15
  4. package/dist/cli/utils.js +6 -7
  5. package/dist/commands.d.ts +23 -0
  6. package/dist/commands.js +45 -0
  7. package/dist/commit.d.ts +17 -0
  8. package/dist/commit.js +22 -0
  9. package/dist/composed-store.d.ts +26 -0
  10. package/dist/composed-store.js +68 -0
  11. package/dist/constants.d.ts +3 -0
  12. package/dist/constants.js +17 -0
  13. package/dist/environment-base.d.ts +259 -0
  14. package/dist/environment-base.js +638 -0
  15. package/dist/environment-full.d.ts +115 -0
  16. package/dist/environment-full.js +321 -0
  17. package/dist/generator-lookup.d.ts +56 -0
  18. package/dist/generator-lookup.js +97 -0
  19. package/dist/index.d.ts +10 -4
  20. package/dist/index.js +9 -5
  21. package/dist/module-lookup.d.ts +59 -0
  22. package/dist/module-lookup.js +227 -0
  23. package/dist/package-manager.d.ts +17 -31
  24. package/dist/package-manager.js +52 -69
  25. package/dist/store.d.ts +19 -19
  26. package/dist/store.js +76 -47
  27. package/dist/util/command.d.ts +17 -14
  28. package/dist/util/command.js +32 -17
  29. package/dist/util/namespace.d.ts +19 -73
  30. package/dist/util/namespace.js +56 -190
  31. package/dist/util/resolve.d.ts +6 -0
  32. package/dist/util/resolve.js +40 -0
  33. package/dist/util/util.d.ts +5 -12
  34. package/dist/util/util.js +24 -23
  35. package/package.json +20 -33
  36. package/readme.md +2 -3
  37. package/dist/adapter.d.ts +0 -54
  38. package/dist/adapter.js +0 -97
  39. package/dist/adapter.js.map +0 -1
  40. package/dist/cli/index.js.map +0 -1
  41. package/dist/cli/utils.js.map +0 -1
  42. package/dist/command.d.ts +0 -24
  43. package/dist/command.js +0 -74
  44. package/dist/command.js.map +0 -1
  45. package/dist/composability.d.ts +0 -25
  46. package/dist/composability.js +0 -78
  47. package/dist/composability.js.map +0 -1
  48. package/dist/environment.d.ts +0 -409
  49. package/dist/environment.js +0 -1221
  50. package/dist/environment.js.map +0 -1
  51. package/dist/generator-features.d.ts +0 -39
  52. package/dist/generator-features.js +0 -69
  53. package/dist/generator-features.js.map +0 -1
  54. package/dist/index.js.map +0 -1
  55. package/dist/namespace-composability.d.ts +0 -36
  56. package/dist/namespace-composability.js +0 -340
  57. package/dist/namespace-composability.js.map +0 -1
  58. package/dist/package-manager.js.map +0 -1
  59. package/dist/resolver.d.ts +0 -146
  60. package/dist/resolver.js +0 -421
  61. package/dist/resolver.js.map +0 -1
  62. package/dist/spawn-command.d.ts +0 -21
  63. package/dist/spawn-command.js +0 -30
  64. package/dist/spawn-command.js.map +0 -1
  65. package/dist/store.js.map +0 -1
  66. package/dist/util/binary-diff.d.ts +0 -2
  67. package/dist/util/binary-diff.js +0 -36
  68. package/dist/util/binary-diff.js.map +0 -1
  69. package/dist/util/command.js.map +0 -1
  70. package/dist/util/conflicter.d.ts +0 -76
  71. package/dist/util/conflicter.js +0 -346
  72. package/dist/util/conflicter.js.map +0 -1
  73. package/dist/util/esm.d.ts +0 -1
  74. package/dist/util/esm.js +0 -22
  75. package/dist/util/esm.js.map +0 -1
  76. package/dist/util/log.d.ts +0 -12
  77. package/dist/util/log.js +0 -165
  78. package/dist/util/log.js.map +0 -1
  79. package/dist/util/namespace.js.map +0 -1
  80. package/dist/util/repository.d.ts +0 -116
  81. package/dist/util/repository.js +0 -223
  82. package/dist/util/repository.js.map +0 -1
  83. package/dist/util/transform.d.ts +0 -55
  84. package/dist/util/transform.js +0 -149
  85. package/dist/util/transform.js.map +0 -1
  86. package/dist/util/util.js.map +0 -1
@@ -1,31 +1,34 @@
1
- declare const YeomanCommand_base: import("commander").CommandConstructor;
2
- export default class YeomanCommand extends YeomanCommand_base {
3
- createCommand(name: any): YeomanCommand;
1
+ import { Command, Option } from 'commander';
2
+ import type BaseEnvironment from '../environment-base.js';
3
+ export default class YeomanCommand extends Command {
4
+ env?: BaseEnvironment;
5
+ createCommand(name?: string): YeomanCommand;
4
6
  /**
5
7
  * Override addOption to register a negative alternative for every option.
6
8
  * @param {Option} option
7
9
  * @return {YeomanCommand} this;
8
10
  */
9
- addOption(option: Option): YeomanCommand;
11
+ addOption(option: Option): this;
12
+ /**
13
+ * Load Generator options into a commander instance.
14
+ *
15
+ * @param {Generator} generator - Generator
16
+ * @return {Command} return command
17
+ */
18
+ registerGenerator(generator: any): this;
10
19
  /**
11
20
  * Register arguments using generator._arguments structure.
12
21
  * @param {object[]} generatorArgs
13
22
  * @return {YeomanCommand} this;
14
23
  */
15
- addGeneratorArguments(generatorArgs?: object[]): YeomanCommand;
24
+ addGeneratorArguments(generatorArgs?: any[]): this;
16
25
  /**
17
26
  * Register options using generator._options structure.
18
27
  * @param {object} options
19
28
  * @param {string} blueprintOptionDescription - description of the blueprint that adds the option
20
29
  * @return {YeomanCommand} this;
21
30
  */
22
- addGeneratorOptions(options: object): YeomanCommand;
23
- _addGeneratorOption(optionName: any, optionDefinition: any, additionalDescription?: string): any;
24
- /**
25
- * Override to reject errors instead of throwing and add command to error.
26
- * @return promise this
27
- */
28
- parseAsync(argv: any, parseOptions: any): Promise<YeomanCommand>;
31
+ addGeneratorOptions(options: Record<string, any>): this;
32
+ _addGeneratorOption(optionName: string, optionDefinition: any, additionalDescription?: string): any;
29
33
  }
30
- import { Option } from 'commander';
31
- export {};
34
+ export declare const addEnvironmentOptions: (command?: YeomanCommand) => YeomanCommand;
@@ -1,5 +1,6 @@
1
1
  import { Command, Option } from 'commander';
2
2
  export default class YeomanCommand extends Command {
3
+ env;
3
4
  createCommand(name) {
4
5
  return new YeomanCommand(name);
5
6
  }
@@ -24,13 +25,22 @@ export default class YeomanCommand extends Command {
24
25
  }
25
26
  return result;
26
27
  }
28
+ /**
29
+ * Load Generator options into a commander instance.
30
+ *
31
+ * @param {Generator} generator - Generator
32
+ * @return {Command} return command
33
+ */
34
+ registerGenerator(generator) {
35
+ return this.addGeneratorOptions(generator._options).addGeneratorArguments(generator._arguments);
36
+ }
27
37
  /**
28
38
  * Register arguments using generator._arguments structure.
29
39
  * @param {object[]} generatorArgs
30
40
  * @return {YeomanCommand} this;
31
41
  */
32
42
  addGeneratorArguments(generatorArgs = []) {
33
- if (!generatorArgs) {
43
+ if (!generatorArgs || generatorArgs.length === 0) {
34
44
  return this;
35
45
  }
36
46
  const args = generatorArgs
@@ -75,23 +85,28 @@ export default class YeomanCommand extends Command {
75
85
  else if (optionDefinition.type === Array) {
76
86
  cmdString = optionDefinition.required === false ? `${cmdString} [value...]` : `${cmdString} <value...>`;
77
87
  }
78
- return this.addOption(new Option(cmdString, optionDefinition.description + additionalDescription)
88
+ return this.addOption(new Option(cmdString, `${optionDefinition.description}${additionalDescription}`)
79
89
  .default(optionDefinition.default)
80
90
  .hideHelp(optionDefinition.hide));
81
91
  }
82
- /**
83
- * Override to reject errors instead of throwing and add command to error.
84
- * @return promise this
85
- */
86
- parseAsync(argv, parseOptions) {
87
- try {
88
- this.parse(argv, parseOptions);
89
- }
90
- catch (commanderError) {
91
- commanderError.command = this;
92
- return Promise.reject(commanderError);
93
- }
94
- return Promise.all(this._actionResults).then(() => this);
95
- }
96
92
  }
97
- //# sourceMappingURL=command.js.map
93
+ /* Add Environment options */
94
+ export const addEnvironmentOptions = (command = new YeomanCommand()) => command
95
+ .option('--cwd', 'Path to use as current dir')
96
+ /* Environment options */
97
+ .option('--skip-install', 'Do not automatically install dependencies', false)
98
+ /* Generator options */
99
+ .option('--skip-cache', 'Do not remember prompt answers', false)
100
+ .option('--local-config-only', 'Generate .yo-rc-global.json locally', false)
101
+ .option('--ask-answered', 'Show prompts for already configured options', false)
102
+ /* Conflicter options */
103
+ .option('--force', 'Override every file', false)
104
+ .option('--dry-run', 'Print conflicts', false)
105
+ .option('--whitespace', 'Whitespace changes will not trigger conflicts', false)
106
+ .option('--bail', 'Fail on first conflict', false)
107
+ .option('--skip-yo-resolve', 'Ignore .yo-resolve files', false)
108
+ /* Hidden options, used for api */
109
+ .addOption(new Option('--skip-local-cache', 'Skip local answers cache').default(true).hideHelp())
110
+ .addOption(new Option('--skip-parse-options', 'Skip legacy options parsing').default(false).hideHelp())
111
+ .addOption(new Option('--experimental', 'Experimental features').default(false).hideHelp())
112
+ .addOption(new Option('--log-cwd', 'Path for log purpose').hideHelp());
@@ -1,80 +1,26 @@
1
+ type AsNamespaceOptions = {
2
+ lookups?: string[];
3
+ };
4
+ export declare const defaultLookups: string[];
1
5
  /**
2
- * Parse a namespace
6
+ * Given a String `filepath`, tries to figure out the relative namespace.
3
7
  *
4
- * @private
5
- * @param {String} namespace
6
- * @return {Object} parsed
7
- * @return {String} parsed.complete - Complete namespace
8
- * @return {String} parsed.namespace - Namespace with format @scope/namespace:generator
9
- * @return {String} parsed.generatorHint - Package name
10
- * @return {String} parsed.id - Id of the instance.
11
- * @return {String} parsed.instanceId - Instance id with format @scope/namespace:generator#id
12
- * @return {String} parsed.method - Method id with format @scope/namespace:generator+foo+bar
13
- * @return {String} parsed.scope - Scope name
14
- * @return {String} parsed.packageNamespace - Package namespace with format @scope/namespace
15
- * @return {String} parsed.generator - Original namespace
16
- * @return {String} parsed.flags - Original namespace
17
- */
18
- export function parseNamespace(complete: any): Object;
19
- /**
20
- * Convert a namespace to a namespace object
8
+ * ### Examples:
21
9
  *
22
- * @private
23
- * @param {String | YeomanNamespace} namespace
24
- * @return {YeomanNamespace}
25
- */
26
- export function toNamespace(namespace: string | YeomanNamespace): YeomanNamespace;
27
- /**
28
- * Convert a package name to a namespace object
10
+ * this.namespace('backbone/all/index.js');
11
+ * // => backbone:all
29
12
  *
30
- * @private
31
- * @param {String} packageName
32
- * @return {YeomanNamespace}
33
- */
34
- export function namespaceFromPackageName(packageName: string): YeomanNamespace;
35
- /**
36
- * Convert a namespace to a namespace object
13
+ * this.namespace('generator-backbone/model');
14
+ * // => backbone:model
37
15
  *
38
- * @private
39
- * @param {String | YeomanNamespace} namespace
40
- * @return {YeomanNamespace}
41
- */
42
- export function requireNamespace(namespace: string | YeomanNamespace): YeomanNamespace;
43
- /**
44
- * Test if the object is an Namespace instance.
16
+ * this.namespace('backbone.js');
17
+ * // => backbone
18
+ *
19
+ * this.namespace('generator-mocha/backbone/model/index.js');
20
+ * // => mocha:backbone:model
45
21
  *
46
- * @private
47
- * @param {Object} namespace
48
- * @return {Boolean} True if namespace is a YeomanNamespace
22
+ * @param filepath
23
+ * @param lookups paths
49
24
  */
50
- export function isNamespace(namespace: Object): boolean;
51
- export class YeomanNamespace {
52
- static parse(complete: any): {
53
- complete: any;
54
- } | null;
55
- constructor(parsed: any);
56
- _original: any;
57
- scope: any;
58
- unscoped: any;
59
- generator: any;
60
- instanceId: any;
61
- semver: any;
62
- methods: any;
63
- flags: any;
64
- _update(parsed: any): void;
65
- command: any;
66
- get _scopeAddition(): string;
67
- get generatorName(): string;
68
- _semverAddition(post: any): any;
69
- get instanceName(): string;
70
- get complete(): string;
71
- get packageNamespace(): string;
72
- set namespace(arg: string);
73
- get namespace(): string;
74
- get unscopedNamespace(): string;
75
- get id(): string;
76
- get generatorHint(): string;
77
- get versionedHint(): string;
78
- with(newValues: any): YeomanNamespace;
79
- toString(): string;
80
- }
25
+ export declare const asNamespace: (filepath: string, { lookups }: AsNamespaceOptions) => string;
26
+ export {};
@@ -1,197 +1,63 @@
1
- import createdLogger from 'debug';
2
- const debug = createdLogger('yeoman:environment:namespace');
3
- // ===================== | == @ ======== scope ======== | ===== unscoped ===== | = : ========== generator ======== | = @ ===== semver ===== @ | = # ========= instanceId ======== | == + ======== method ======= |= flags = |
4
- const NAMESPACE_REGEX = /^(?:(@[a-z\d-~][a-z\d-._~]*)\/)?([a-z\d-~][a-z\d-._~]*)(?::((?:[a-z\d-~][a-z\d-._~]*:?)*))?(?:@([a-z\d-.~><+=^* ]*)@?)?(?:#((?:[a-z\d-~][a-z\d-._~]*|\*)))?(?:\+((?:[a-zA-Z\d]\w*\+?)*))?(\?)?$/;
5
- const groups = {
6
- complete: 0,
7
- scope: 1,
8
- unscoped: 2,
9
- generator: 3,
10
- semver: 4,
11
- instanceId: 5,
12
- method: 6,
13
- flags: 7,
14
- };
15
- const flags = { optional: '?' };
16
- export class YeomanNamespace {
17
- constructor(parsed) {
18
- this._original = parsed.complete;
19
- this.scope = parsed.scope;
20
- this.unscoped = parsed.unscoped;
21
- this.generator = parsed.generator;
22
- this.instanceId = parsed.instanceId;
23
- this.semver = parsed.semver;
24
- this.methods = parsed.method ? parsed.method.split('+') : parsed.methods;
25
- this.flags = parsed.flags;
26
- // Populate flags
27
- if (this.flags) {
28
- for (const [name, value] of Object.entries(flags)) {
29
- if (this.flags === value) {
30
- this[name] = true;
31
- }
32
- else {
33
- delete this[name];
34
- }
35
- }
36
- }
37
- debug('Parsed namespace %o', this);
38
- }
39
- static parse(complete) {
40
- const result = NAMESPACE_REGEX.exec(complete);
41
- if (!result) {
42
- debug('Namespace failed RegExp parse %s, using fallback', complete);
43
- return null;
44
- }
45
- const parsed = { complete };
46
- // Populate fields
47
- for (const [name, value] of Object.entries(groups)) {
48
- if (result[value]) {
49
- parsed[name] = result[value];
50
- }
51
- }
52
- return parsed;
53
- }
54
- _update(parsed) {
55
- this.scope = parsed.scope || this.scope;
56
- this.unscoped = parsed.unscoped || this.unscoped;
57
- this.generator = parsed.generator || this.generator;
58
- this.instanceId = parsed.instanceId || this.instanceId;
59
- this.command = parsed.command || this.command;
60
- this.flags = parsed.flags || this.flags;
61
- }
62
- get _scopeAddition() {
63
- return this.scope ? `${this.scope}/` : '';
64
- }
65
- get generatorName() {
66
- return this.generator ? `:${this.generator}` : '';
67
- }
68
- _semverAddition(post) {
69
- if (!this.semver) {
70
- return post ?? '';
71
- }
72
- if (post) {
73
- return `@${this.semver}@${post}`;
74
- }
75
- return `@${this.semver}`;
76
- }
77
- get instanceName() {
78
- return this.instanceId ? `#${this.instanceId}` : '';
79
- }
80
- get complete() {
81
- let methods = '';
82
- if (this.methods && this.methods.length > 0) {
83
- methods = '+' + this.methods.join('+');
84
- }
85
- const postSemver = `${this.instanceName}${methods}${this.flags || ''}`;
86
- return `${this.namespace}${this._semverAddition(postSemver)}`;
87
- }
88
- get packageNamespace() {
89
- return `${this._scopeAddition}${this.unscoped}`;
90
- }
91
- get namespace() {
92
- return `${this.packageNamespace}${this.generatorName}`;
93
- }
94
- set namespace(namespace) {
95
- const parsed = YeomanNamespace.parse(namespace);
96
- if (!parsed) {
97
- throw new Error(`Error parsing namespace ${namespace}`);
98
- }
99
- this._update(parsed);
100
- }
101
- get unscopedNamespace() {
102
- return `${this.unscoped}${this.generatorName}`;
103
- }
104
- get id() {
105
- return `${this.namespace}${this.instanceName}`;
106
- }
107
- get generatorHint() {
108
- return `${this._scopeAddition}generator-${this.unscoped}`;
109
- }
110
- get versionedHint() {
111
- return this.semver ? `${this.generatorHint}@"${this.semver}"` : this.generatorHint;
112
- }
113
- with(newValues) {
114
- const self = this;
115
- return new YeomanNamespace({
116
- ...self,
117
- ...newValues,
118
- });
119
- }
120
- toString() {
121
- return this.complete;
122
- }
123
- }
1
+ import { parse } from 'node:path';
2
+ import slash from 'slash';
3
+ import { findLast } from 'lodash-es';
4
+ import escapeStringRegexp from 'escape-string-regexp';
5
+ export const defaultLookups = ['.', 'generators', 'lib/generators', 'dist/generators'];
124
6
  /**
125
- * Parse a namespace
7
+ * Given a String `filepath`, tries to figure out the relative namespace.
126
8
  *
127
- * @private
128
- * @param {String} namespace
129
- * @return {Object} parsed
130
- * @return {String} parsed.complete - Complete namespace
131
- * @return {String} parsed.namespace - Namespace with format @scope/namespace:generator
132
- * @return {String} parsed.generatorHint - Package name
133
- * @return {String} parsed.id - Id of the instance.
134
- * @return {String} parsed.instanceId - Instance id with format @scope/namespace:generator#id
135
- * @return {String} parsed.method - Method id with format @scope/namespace:generator+foo+bar
136
- * @return {String} parsed.scope - Scope name
137
- * @return {String} parsed.packageNamespace - Package namespace with format @scope/namespace
138
- * @return {String} parsed.generator - Original namespace
139
- * @return {String} parsed.flags - Original namespace
140
- */
141
- export function parseNamespace(complete) {
142
- if (typeof complete !== 'string') {
143
- return null;
144
- }
145
- const parsed = YeomanNamespace.parse(complete);
146
- return parsed ? new YeomanNamespace(parsed) : null;
147
- }
148
- /**
149
- * Convert a namespace to a namespace object
9
+ * ### Examples:
150
10
  *
151
- * @private
152
- * @param {String | YeomanNamespace} namespace
153
- * @return {YeomanNamespace}
154
- */
155
- export function toNamespace(namespace) {
156
- return isNamespace(namespace) ? namespace : parseNamespace(namespace);
157
- }
158
- /**
159
- * Convert a package name to a namespace object
11
+ * this.namespace('backbone/all/index.js');
12
+ * // => backbone:all
160
13
  *
161
- * @private
162
- * @param {String} packageName
163
- * @return {YeomanNamespace}
164
- */
165
- export function namespaceFromPackageName(packageName) {
166
- const namespace = this.parseNamespace(packageName);
167
- if (!namespace.unscoped.startsWith('generator-')) {
168
- throw new Error(`${packageName} is not a valid generator package name`);
169
- }
170
- namespace.unscoped = namespace.unscoped.replace(/^generator-/, '');
171
- return namespace;
172
- }
173
- /**
174
- * Convert a namespace to a namespace object
14
+ * this.namespace('generator-backbone/model');
15
+ * // => backbone:model
175
16
  *
176
- * @private
177
- * @param {String | YeomanNamespace} namespace
178
- * @return {YeomanNamespace}
179
- */
180
- export function requireNamespace(namespace) {
181
- const parsed = toNamespace(namespace);
182
- if (!parsed) {
183
- throw new Error(`Error parsing namespace ${namespace}`);
184
- }
185
- return parsed;
186
- }
187
- /**
188
- * Test if the object is an Namespace instance.
17
+ * this.namespace('backbone.js');
18
+ * // => backbone
19
+ *
20
+ * this.namespace('generator-mocha/backbone/model/index.js');
21
+ * // => mocha:backbone:model
189
22
  *
190
- * @private
191
- * @param {Object} namespace
192
- * @return {Boolean} True if namespace is a YeomanNamespace
23
+ * @param filepath
24
+ * @param lookups paths
193
25
  */
194
- export function isNamespace(namespace) {
195
- return namespace && namespace.constructor && namespace.constructor.name === 'YeomanNamespace';
196
- }
197
- //# sourceMappingURL=namespace.js.map
26
+ export const asNamespace = (filepath, { lookups = defaultLookups }) => {
27
+ if (!filepath) {
28
+ throw new Error('Missing file path');
29
+ }
30
+ // Normalize path
31
+ let ns = slash(filepath);
32
+ // Ignore path before latest node_modules
33
+ const nodeModulesPath = '/node_modules/';
34
+ if (ns.includes(nodeModulesPath)) {
35
+ ns = ns.slice(ns.lastIndexOf(nodeModulesPath) + nodeModulesPath.length, ns.length);
36
+ }
37
+ // Cleanup extension and normalize path for differents OS
38
+ const parsed = parse(ns);
39
+ ns = parsed.dir ? `${parsed.dir}/${parsed.name}` : parsed.name;
40
+ // Sort lookups by length so biggest are removed first
41
+ const nsLookups = [...lookups, '..']
42
+ .map(found => slash(found))
43
+ .sort((a, b) => a.split('/').length - b.split('/').length)
44
+ .reverse();
45
+ // If `ns` contains a lookup dir in its path, remove it.
46
+ for (const lookup of nsLookups) {
47
+ // Only match full directory (begin with leading slash or start of input, end with trailing slash)
48
+ ns = ns.replace(new RegExp(`(?:/|^)${escapeStringRegexp(lookup)}(?=/)`, 'g'), '');
49
+ }
50
+ const folders = ns.split('/');
51
+ const scope = findLast(folders, folder => folder.startsWith('@'));
52
+ // Cleanup `ns` from unwanted parts and then normalize slashes to `:`
53
+ ns = ns
54
+ .replace(/\/\//g, '') // Remove double `/`
55
+ .replace(/(.*generator-)/, '') // Remove before `generator-`
56
+ .replace(/\/(index|main)$/, '') // Remove `/index` or `/main`
57
+ .replace(/^\//, '') // Remove leading `/`
58
+ .replace(/\/+/g, ':'); // Replace slashes by `:`
59
+ if (scope) {
60
+ ns = `${scope}/${ns}`;
61
+ }
62
+ return ns;
63
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Resolve a module path
3
+ * @param specifier - Filepath or module name
4
+ * @return - The resolved path leading to the module
5
+ */
6
+ export declare function resolveModulePath(specifier: string, resolvedOrigin?: string): Promise<string | undefined>;
@@ -0,0 +1,40 @@
1
+ import { dirname, extname, join, normalize, resolve, sep } from 'node:path';
2
+ import { realpath, stat } from 'node:fs/promises';
3
+ import untildify from 'untildify';
4
+ import { locatePath } from 'locate-path';
5
+ import { defaultExtensions } from '../generator-lookup.js';
6
+ /**
7
+ * Resolve a module path
8
+ * @param specifier - Filepath or module name
9
+ * @return - The resolved path leading to the module
10
+ */
11
+ export async function resolveModulePath(specifier, resolvedOrigin) {
12
+ let maybeResolved = specifier;
13
+ if (maybeResolved.startsWith('.')) {
14
+ if (resolvedOrigin) {
15
+ maybeResolved = resolve(dirname(resolvedOrigin), '..', maybeResolved);
16
+ }
17
+ else {
18
+ throw new Error(`Specifier ${maybeResolved} could not be calculated`);
19
+ }
20
+ }
21
+ maybeResolved = untildify(maybeResolved);
22
+ maybeResolved = normalize(maybeResolved);
23
+ if (extname(maybeResolved) === '') {
24
+ maybeResolved += sep;
25
+ }
26
+ try {
27
+ let specStat = await stat(maybeResolved);
28
+ if (specStat.isSymbolicLink()) {
29
+ specStat = await stat(await realpath(maybeResolved));
30
+ }
31
+ if (specStat.isFile()) {
32
+ return maybeResolved;
33
+ }
34
+ if (specStat.isDirectory()) {
35
+ return await locatePath(defaultExtensions.map(ext => `index${ext}`).map(file => join(maybeResolved, file)));
36
+ }
37
+ }
38
+ catch { }
39
+ throw new Error(`Error resolving ${specifier}`);
40
+ }
@@ -1,14 +1,7 @@
1
- export { default as log } from "./log.js";
1
+ import { type SyncOptions } from 'execa';
2
+ export declare const execaOutput: (cmg: string, args: string[], options: SyncOptions) => string | undefined;
2
3
  /**
3
- * Create a "sloppy" copy of an initial Environment object. The focus of this method is on
4
- * performance rather than correctly deep copying every property or recreating a correct
5
- * instance. Use carefully and don't rely on `hasOwnProperty` of the copied environment.
6
- *
7
- * Every property are shared except the runLoop which is regenerated.
8
- *
9
- * @param {Environment} initialEnv - an Environment instance
10
- * @return {Environment} sloppy copy of the initial Environment
4
+ * Two-step argument splitting function that first splits arguments in quotes,
5
+ * and then splits up the remaining arguments if they are not part of a quote.
11
6
  */
12
- export function duplicateEnv(initialEnv: Environment): Environment;
13
- export function execaOutput(cmg: any, args: any, options: any): string | undefined;
14
- import Environment from '../environment.js';
7
+ export declare function splitArgsFromString(argsString: string | string[]): string[];
package/dist/util/util.js CHANGED
@@ -1,24 +1,5 @@
1
- /** @module env/util */
2
1
  import { execaSync } from 'execa';
3
- import GroupedQueue from 'grouped-queue';
4
- import Environment from '../environment.js';
5
- /**
6
- * Create a "sloppy" copy of an initial Environment object. The focus of this method is on
7
- * performance rather than correctly deep copying every property or recreating a correct
8
- * instance. Use carefully and don't rely on `hasOwnProperty` of the copied environment.
9
- *
10
- * Every property are shared except the runLoop which is regenerated.
11
- *
12
- * @param {Environment} initialEnv - an Environment instance
13
- * @return {Environment} sloppy copy of the initial Environment
14
- */
15
- const duplicateEnv = initialEnv => {
16
- // Hack: Create a clone of the environment with a new instance of `runLoop`
17
- const env = Object.create(initialEnv);
18
- env.runLoop = new GroupedQueue(Environment.queues, false);
19
- return env;
20
- };
21
- const execaOutput = (cmg, args, options) => {
2
+ export const execaOutput = (cmg, args, options) => {
22
3
  try {
23
4
  const result = execaSync(cmg, args, options);
24
5
  if (!result.failed) {
@@ -28,6 +9,26 @@ const execaOutput = (cmg, args, options) => {
28
9
  catch { }
29
10
  return undefined;
30
11
  };
31
- export { duplicateEnv, execaOutput };
32
- export { default as log } from './log.js';
33
- //# sourceMappingURL=util.js.map
12
+ /**
13
+ * Two-step argument splitting function that first splits arguments in quotes,
14
+ * and then splits up the remaining arguments if they are not part of a quote.
15
+ */
16
+ export function splitArgsFromString(argsString) {
17
+ if (Array.isArray(argsString)) {
18
+ return argsString;
19
+ }
20
+ let result = [];
21
+ if (!argsString) {
22
+ return result;
23
+ }
24
+ const quoteSeparatedArgs = argsString.split(/("[^"]*")/).filter(Boolean);
25
+ for (const arg of quoteSeparatedArgs) {
26
+ if (arg.includes('"')) {
27
+ result.push(arg.replace(/"/g, ''));
28
+ }
29
+ else {
30
+ result = result.concat(arg.trim().split(' '));
31
+ }
32
+ }
33
+ return result;
34
+ }