@servicetitan/startup 24.0.4 → 24.1.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.
- package/dist/cli/commands/build.d.ts +1 -0
- package/dist/cli/commands/build.d.ts.map +1 -1
- package/dist/cli/commands/build.js +3 -0
- package/dist/cli/commands/build.js.map +1 -1
- package/dist/cli/commands/bundle-package.d.ts +1 -0
- package/dist/cli/commands/bundle-package.d.ts.map +1 -1
- package/dist/cli/commands/bundle-package.js +3 -0
- package/dist/cli/commands/bundle-package.js.map +1 -1
- package/dist/cli/commands/eslint.d.ts +1 -0
- package/dist/cli/commands/eslint.d.ts.map +1 -1
- package/dist/cli/commands/eslint.js +3 -0
- package/dist/cli/commands/eslint.js.map +1 -1
- package/dist/cli/commands/get-command.d.ts +6 -0
- package/dist/cli/commands/get-command.d.ts.map +1 -0
- package/dist/cli/commands/get-command.js +50 -0
- package/dist/cli/commands/get-command.js.map +1 -0
- package/dist/cli/commands/get-user-commands.d.ts +7 -0
- package/dist/cli/commands/get-user-commands.d.ts.map +1 -0
- package/dist/cli/commands/get-user-commands.js +17 -0
- package/dist/cli/commands/get-user-commands.js.map +1 -0
- package/dist/cli/commands/index.d.ts +3 -3
- package/dist/cli/commands/index.d.ts.map +1 -1
- package/dist/cli/commands/index.js +3 -0
- package/dist/cli/commands/index.js.map +1 -1
- package/dist/cli/commands/init.d.ts +2 -1
- package/dist/cli/commands/init.d.ts.map +1 -1
- package/dist/cli/commands/init.js +5 -2
- package/dist/cli/commands/init.js.map +1 -1
- package/dist/cli/commands/install.d.ts +1 -0
- package/dist/cli/commands/install.d.ts.map +1 -1
- package/dist/cli/commands/install.js +3 -0
- package/dist/cli/commands/install.js.map +1 -1
- package/dist/cli/commands/kendo-ui-license.d.ts +1 -0
- package/dist/cli/commands/kendo-ui-license.d.ts.map +1 -1
- package/dist/cli/commands/kendo-ui-license.js +3 -0
- package/dist/cli/commands/kendo-ui-license.js.map +1 -1
- package/dist/cli/commands/lint.d.ts +1 -0
- package/dist/cli/commands/lint.d.ts.map +1 -1
- package/dist/cli/commands/lint.js +3 -0
- package/dist/cli/commands/lint.js.map +1 -1
- package/dist/cli/commands/mfe-publish.d.ts +3 -0
- package/dist/cli/commands/mfe-publish.d.ts.map +1 -1
- package/dist/cli/commands/mfe-publish.js +14 -1
- package/dist/cli/commands/mfe-publish.js.map +1 -1
- package/dist/cli/commands/prepare-package.d.ts +1 -0
- package/dist/cli/commands/prepare-package.d.ts.map +1 -1
- package/dist/cli/commands/prepare-package.js +3 -0
- package/dist/cli/commands/prepare-package.js.map +1 -1
- package/dist/cli/commands/start.d.ts +1 -0
- package/dist/cli/commands/start.d.ts.map +1 -1
- package/dist/cli/commands/start.js +3 -0
- package/dist/cli/commands/start.js.map +1 -1
- package/dist/cli/commands/styles-check.d.ts +1 -0
- package/dist/cli/commands/styles-check.d.ts.map +1 -1
- package/dist/cli/commands/styles-check.js +3 -0
- package/dist/cli/commands/styles-check.js.map +1 -1
- package/dist/cli/commands/tests.d.ts +1 -0
- package/dist/cli/commands/tests.d.ts.map +1 -1
- package/dist/cli/commands/tests.js +3 -0
- package/dist/cli/commands/tests.js.map +1 -1
- package/dist/cli/commands/types.d.ts +5 -0
- package/dist/cli/commands/types.d.ts.map +1 -0
- package/dist/cli/commands/types.js +3 -0
- package/dist/cli/commands/types.js.map +1 -0
- package/dist/cli/index.js +24 -37
- package/dist/cli/index.js.map +1 -1
- package/dist/utils/find-packages.d.ts +6 -0
- package/dist/utils/find-packages.d.ts.map +1 -0
- package/dist/utils/find-packages.js +52 -0
- package/dist/utils/find-packages.js.map +1 -0
- package/dist/utils/get-configuration.d.ts +5 -4
- package/dist/utils/get-configuration.d.ts.map +1 -1
- package/dist/utils/get-configuration.js +15 -9
- package/dist/utils/get-configuration.js.map +1 -1
- package/dist/utils/get-packages.d.ts +1 -5
- package/dist/utils/get-packages.d.ts.map +1 -1
- package/dist/utils/get-packages.js +44 -26
- package/dist/utils/get-packages.js.map +1 -1
- package/package.json +14 -13
- package/src/cli/commands/__tests__/get-command.test.ts +17 -0
- package/src/cli/commands/__tests__/get-user-commands.test.ts +24 -0
- package/src/cli/commands/__tests__/init.test.ts +4 -4
- package/src/cli/commands/__tests__/mfe-package-publish.test.ts +8 -0
- package/src/cli/commands/build.ts +4 -0
- package/src/cli/commands/bundle-package.ts +4 -0
- package/src/cli/commands/eslint.ts +4 -0
- package/src/cli/commands/get-command.ts +50 -0
- package/src/cli/commands/get-user-commands.ts +19 -0
- package/src/cli/commands/index.ts +3 -4
- package/src/cli/commands/init.ts +7 -3
- package/src/cli/commands/install.ts +4 -0
- package/src/cli/commands/kendo-ui-license.ts +4 -0
- package/src/cli/commands/lint.ts +4 -0
- package/src/cli/commands/mfe-publish.ts +20 -1
- package/src/cli/commands/prepare-package.ts +4 -0
- package/src/cli/commands/start.ts +4 -0
- package/src/cli/commands/styles-check.ts +4 -0
- package/src/cli/commands/tests.ts +4 -0
- package/src/cli/commands/types.ts +4 -0
- package/src/cli/index.ts +27 -59
- package/src/utils/__tests__/get-configuration.test.ts +30 -8
- package/src/utils/__tests__/get-packages.test.ts +171 -93
- package/src/utils/find-packages.ts +61 -0
- package/src/utils/get-configuration.ts +18 -8
- package/src/utils/get-packages.ts +59 -42
- package/dist/utils/maybe-create-git-folder.d.ts +0 -10
- package/dist/utils/maybe-create-git-folder.d.ts.map +0 -1
- package/dist/utils/maybe-create-git-folder.js +0 -25
- package/dist/utils/maybe-create-git-folder.js.map +0 -1
- package/src/utils/__tests__/maybe-create-git-folder.test.ts +0 -41
- package/src/utils/maybe-create-git-folder.ts +0 -18
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
3
|
-
import { maybeCreateGitFolder } from '../maybe-create-git-folder';
|
|
4
|
-
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { fs, vol } from 'memfs';
|
|
5
3
|
import {
|
|
6
4
|
Package,
|
|
7
5
|
PackageType,
|
|
@@ -10,142 +8,222 @@ import {
|
|
|
10
8
|
splitPackagesByType,
|
|
11
9
|
} from '../get-packages';
|
|
12
10
|
|
|
13
|
-
jest.mock('
|
|
14
|
-
jest.mock('../get-configuration');
|
|
15
|
-
jest.mock('../maybe-create-git-folder');
|
|
11
|
+
jest.mock('fs', () => fs);
|
|
16
12
|
|
|
17
13
|
describe('[startup] Utils', () => {
|
|
18
|
-
|
|
19
|
-
{ name: 'foo', location: 'packages/foo', type: PackageType.Legacy },
|
|
20
|
-
{ name: 'bar', location: 'packages/bar', type: PackageType.TSC },
|
|
21
|
-
{ name: 'baz', location: 'packages/baz', type: PackageType.Webpack },
|
|
22
|
-
];
|
|
14
|
+
beforeEach(() => jest.clearAllMocks());
|
|
23
15
|
|
|
24
16
|
describe(`${getPackages.name}`, () => {
|
|
25
17
|
let options: Parameters<typeof getPackages>[0] | undefined;
|
|
26
|
-
let dependencies: Record<string, string[]> | undefined;
|
|
27
|
-
|
|
28
|
-
function findPackageByLocation(location?: string) {
|
|
29
|
-
return packages.find(p => p.location === location);
|
|
30
|
-
}
|
|
31
|
-
|
|
32
|
-
function packageGraph() {
|
|
33
|
-
return dependencies ?? Object.fromEntries(packages.map(({ name }) => [name, []]));
|
|
34
|
-
}
|
|
35
|
-
|
|
36
|
-
function scopedPackages() {
|
|
37
|
-
let result = packages;
|
|
38
|
-
if (options?.scope) {
|
|
39
|
-
const arrayScope = Array.isArray(options.scope) ? options.scope : [options.scope];
|
|
40
|
-
result = result.filter(({ name }) => arrayScope.includes(name));
|
|
41
|
-
}
|
|
42
|
-
return result;
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
function resolvePackages(args: string[]) {
|
|
46
|
-
if (args.includes('--graph')) {
|
|
47
|
-
return packageGraph();
|
|
48
|
-
}
|
|
49
|
-
if (args.includes('--scope')) {
|
|
50
|
-
return scopedPackages().map(({ type, ...pkg }) => pkg);
|
|
51
|
-
}
|
|
52
|
-
return packages.map(({ type, ...pkg }) => pkg);
|
|
53
|
-
}
|
|
54
18
|
|
|
55
19
|
beforeEach(() => {
|
|
56
20
|
options = undefined;
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
21
|
+
vol.fromNestedJSON({
|
|
22
|
+
'package.json': JSON.stringify({
|
|
23
|
+
workspaces: ['packages/*', 'examples/*', 'legacy/bar'],
|
|
24
|
+
}),
|
|
25
|
+
'packages': {
|
|
26
|
+
foo: {
|
|
27
|
+
'package.json': JSON.stringify({
|
|
28
|
+
name: 'foo',
|
|
29
|
+
version: '1.0.0',
|
|
30
|
+
private: true,
|
|
31
|
+
}),
|
|
32
|
+
},
|
|
33
|
+
},
|
|
34
|
+
'legacy': {
|
|
35
|
+
bar: {
|
|
36
|
+
'package.json': JSON.stringify({
|
|
37
|
+
name: 'bar',
|
|
38
|
+
version: '2.0.0',
|
|
39
|
+
cli: { legacy: true },
|
|
40
|
+
}),
|
|
41
|
+
},
|
|
42
|
+
},
|
|
43
|
+
'examples': {
|
|
44
|
+
baz: {
|
|
45
|
+
'package.json': JSON.stringify({
|
|
46
|
+
name: 'baz',
|
|
47
|
+
version: '3.0.0',
|
|
48
|
+
cli: { webpack: false },
|
|
49
|
+
}),
|
|
50
|
+
},
|
|
51
|
+
},
|
|
68
52
|
});
|
|
69
53
|
});
|
|
70
54
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
55
|
+
afterEach(() => vol.reset());
|
|
56
|
+
|
|
57
|
+
const subject = () =>
|
|
58
|
+
getPackages(options).sort((a, b) => a.version.localeCompare(b.version));
|
|
59
|
+
|
|
60
|
+
test('returns workspace packages', () => {
|
|
61
|
+
expect(subject()).toEqual([
|
|
62
|
+
{
|
|
63
|
+
name: 'foo',
|
|
64
|
+
version: '1.0.0',
|
|
65
|
+
private: true,
|
|
66
|
+
location: path.resolve('./packages/foo'),
|
|
67
|
+
type: PackageType.Webpack,
|
|
68
|
+
},
|
|
69
|
+
{
|
|
70
|
+
name: 'bar',
|
|
71
|
+
version: '2.0.0',
|
|
72
|
+
private: false,
|
|
73
|
+
location: path.resolve('./legacy/bar'),
|
|
74
|
+
type: PackageType.Legacy,
|
|
75
|
+
},
|
|
76
|
+
{
|
|
77
|
+
name: 'baz',
|
|
78
|
+
version: '3.0.0',
|
|
79
|
+
private: false,
|
|
80
|
+
location: path.resolve('./examples/baz'),
|
|
81
|
+
type: PackageType.TSC,
|
|
82
|
+
},
|
|
83
|
+
]);
|
|
76
84
|
});
|
|
77
85
|
|
|
78
|
-
|
|
79
|
-
|
|
86
|
+
describe('with "scope"', () => {
|
|
87
|
+
beforeEach(() => (options = { scope: 'foo' }));
|
|
80
88
|
|
|
81
|
-
|
|
82
|
-
|
|
89
|
+
test('returns only the specified packages', () => {
|
|
90
|
+
expect(subject()).toEqual([expect.objectContaining({ name: 'foo' })]);
|
|
91
|
+
});
|
|
83
92
|
|
|
84
|
-
|
|
85
|
-
|
|
93
|
+
describe('when filtered package has dependencies', () => {
|
|
94
|
+
beforeEach(() => {
|
|
95
|
+
const fooPath = path.resolve('./packages/foo/package.json');
|
|
96
|
+
const fooJson = JSON.parse(fs.readFileSync(fooPath, 'utf8').toString());
|
|
97
|
+
fs.writeFileSync(
|
|
98
|
+
fooPath,
|
|
99
|
+
JSON.stringify({ ...fooJson, dependencies: { bar: '>=2.0' } })
|
|
100
|
+
);
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('also returns internal dependencies', () => {
|
|
104
|
+
expect(subject()).toEqual([
|
|
105
|
+
expect.objectContaining({ name: 'foo' }),
|
|
106
|
+
expect.objectContaining({ name: 'bar' }),
|
|
107
|
+
]);
|
|
108
|
+
});
|
|
109
|
+
});
|
|
86
110
|
|
|
87
|
-
|
|
88
|
-
|
|
111
|
+
describe('when "scope" is a glob expression', () => {
|
|
112
|
+
beforeEach(() => (options = { scope: 'ba*' }));
|
|
89
113
|
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
114
|
+
test('returns only the specified packages', () => {
|
|
115
|
+
expect(subject()).toEqual([
|
|
116
|
+
expect.objectContaining({ name: 'bar' }),
|
|
117
|
+
expect.objectContaining({ name: 'baz' }),
|
|
118
|
+
]);
|
|
119
|
+
});
|
|
94
120
|
});
|
|
95
121
|
});
|
|
96
122
|
|
|
97
|
-
describe('with "
|
|
98
|
-
beforeEach(() => (options = {
|
|
123
|
+
describe('with "ignore"', () => {
|
|
124
|
+
beforeEach(() => (options = { ignore: ['foo'] }));
|
|
99
125
|
|
|
100
|
-
test('
|
|
101
|
-
expect(subject()).
|
|
126
|
+
test('omits the specified packages', () => {
|
|
127
|
+
expect(subject()).not.toContainEqual(expect.objectContaining({ name: 'foo' }));
|
|
102
128
|
});
|
|
103
129
|
|
|
104
|
-
describe('when
|
|
105
|
-
beforeEach(() => (
|
|
130
|
+
describe('when "ignore" is a glob expression', () => {
|
|
131
|
+
beforeEach(() => (options = { ignore: ['ba*'] }));
|
|
106
132
|
|
|
107
|
-
test('
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
);
|
|
133
|
+
test('returns only the specified packages', () => {
|
|
134
|
+
const result = subject();
|
|
135
|
+
expect(result).not.toContainEqual(expect.objectContaining({ name: 'bar' }));
|
|
136
|
+
expect(result).not.toContainEqual(expect.objectContaining({ name: 'baz' }));
|
|
111
137
|
});
|
|
112
138
|
});
|
|
113
139
|
});
|
|
140
|
+
|
|
141
|
+
function itReturnsEmptyArray() {
|
|
142
|
+
test('returns empty array', () => {
|
|
143
|
+
expect(subject()).toEqual([]);
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
describe('with no packages', () => {
|
|
148
|
+
beforeEach(() => vol.fromJSON({ 'package.json': JSON.stringify({}) }));
|
|
149
|
+
|
|
150
|
+
itReturnsEmptyArray();
|
|
151
|
+
});
|
|
152
|
+
|
|
153
|
+
describe('with no package.json', () => {
|
|
154
|
+
beforeEach(() => vol.reset());
|
|
155
|
+
|
|
156
|
+
itReturnsEmptyArray();
|
|
157
|
+
});
|
|
114
158
|
});
|
|
115
159
|
|
|
116
160
|
describe(`${getPackagesGraph.name}`, () => {
|
|
117
|
-
const packageGraph = Object.fromEntries(packages.map(({ name }) => [name, []]));
|
|
118
161
|
let options: Parameters<typeof getPackagesGraph>[0] | undefined;
|
|
119
162
|
|
|
120
163
|
beforeEach(() => {
|
|
121
164
|
options = undefined;
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
165
|
+
vol.fromNestedJSON({
|
|
166
|
+
'package.json': JSON.stringify({ workspaces: ['packages/*'] }),
|
|
167
|
+
'packages': {
|
|
168
|
+
foo: {
|
|
169
|
+
'package.json': JSON.stringify({
|
|
170
|
+
name: 'foo',
|
|
171
|
+
dependencies: { bar: '^1.0.0', react: '>=18' },
|
|
172
|
+
devDependencies: {
|
|
173
|
+
'@testing-library/react': '>=16',
|
|
174
|
+
'@testing-library/dom': '>=10',
|
|
175
|
+
},
|
|
176
|
+
}),
|
|
177
|
+
},
|
|
178
|
+
bar: {
|
|
179
|
+
'package.json': JSON.stringify({
|
|
180
|
+
name: 'bar',
|
|
181
|
+
dependencies: { foo: '*' },
|
|
182
|
+
}),
|
|
183
|
+
},
|
|
184
|
+
baz: {
|
|
185
|
+
'package.json': JSON.stringify({
|
|
186
|
+
name: 'baz',
|
|
187
|
+
}),
|
|
188
|
+
},
|
|
189
|
+
},
|
|
190
|
+
});
|
|
125
191
|
});
|
|
126
192
|
|
|
127
193
|
const subject = () => getPackagesGraph(options);
|
|
128
194
|
|
|
129
|
-
test('returns
|
|
130
|
-
expect(subject()).toEqual(
|
|
131
|
-
|
|
195
|
+
test('returns package graph', () => {
|
|
196
|
+
expect(subject()).toEqual({
|
|
197
|
+
foo: ['bar', 'react', '@testing-library/react', '@testing-library/dom'].sort(),
|
|
198
|
+
bar: ['foo'],
|
|
199
|
+
baz: [],
|
|
200
|
+
});
|
|
132
201
|
});
|
|
133
202
|
|
|
134
|
-
describe
|
|
135
|
-
beforeEach(() => (options = {
|
|
203
|
+
describe('with "scope"', () => {
|
|
204
|
+
beforeEach(() => (options = { scope: 'foo' }));
|
|
205
|
+
|
|
206
|
+
test('includes only the specified packages', () => {
|
|
207
|
+
expect(Object.keys(subject())).toEqual(['foo']);
|
|
208
|
+
});
|
|
209
|
+
});
|
|
136
210
|
|
|
137
|
-
|
|
138
|
-
|
|
211
|
+
describe('with "ignore"', () => {
|
|
212
|
+
beforeEach(() => (options = { ignore: ['foo', 'bar'] }));
|
|
139
213
|
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
`lerna la --${option} foo --graph`.split(' ')
|
|
143
|
-
);
|
|
214
|
+
test('omits the specified packages', () => {
|
|
215
|
+
expect(Object.keys(subject())).toEqual(['baz']);
|
|
144
216
|
});
|
|
145
217
|
});
|
|
146
218
|
});
|
|
147
219
|
|
|
148
220
|
describe(`${splitPackagesByType.name}`, () => {
|
|
221
|
+
const packages: Pick<Package, 'name' | 'location' | 'type'>[] = [
|
|
222
|
+
{ name: 'foo', location: 'packages/foo', type: PackageType.Legacy },
|
|
223
|
+
{ name: 'bar', location: 'packages/bar', type: PackageType.TSC },
|
|
224
|
+
{ name: 'baz', location: 'packages/baz', type: PackageType.Webpack },
|
|
225
|
+
];
|
|
226
|
+
|
|
149
227
|
const subject = (packages: Package[]) => splitPackagesByType(packages);
|
|
150
228
|
|
|
151
229
|
test('groups packages by type', () => {
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import { globSync } from 'glob';
|
|
2
|
+
import path from 'path';
|
|
3
|
+
import { readJsonSafe } from './read-json';
|
|
4
|
+
import { log } from './log';
|
|
5
|
+
|
|
6
|
+
export interface ProjectPackage extends Record<string, any> {
|
|
7
|
+
name: string;
|
|
8
|
+
location: string;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
export function findPackages(): ProjectPackage[] {
|
|
12
|
+
const workspaces = findWorkspaces();
|
|
13
|
+
if (!workspaces) {
|
|
14
|
+
return [];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
const result = workspaces
|
|
18
|
+
.flatMap(pattern => globSync(pattern))
|
|
19
|
+
.map(location => {
|
|
20
|
+
const dir = path.resolve(location);
|
|
21
|
+
const file = path.join(dir, 'package.json');
|
|
22
|
+
return { ...readJsonSafe<ProjectPackage>(file), location: dir };
|
|
23
|
+
})
|
|
24
|
+
.filter(({ name }) => name !== undefined) as ProjectPackage[];
|
|
25
|
+
|
|
26
|
+
/* istanbul ignore next: debug only */
|
|
27
|
+
log.debug(
|
|
28
|
+
`find-packages`,
|
|
29
|
+
() => `found packages: ${JSON.stringify(result.map(({ name }) => name))}`
|
|
30
|
+
);
|
|
31
|
+
|
|
32
|
+
return result;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
function findWorkspaces() {
|
|
36
|
+
let directory = path.resolve('./');
|
|
37
|
+
do {
|
|
38
|
+
const packageJson = path.resolve(path.join(directory, 'package.json'));
|
|
39
|
+
|
|
40
|
+
log.debug('find-packages', `reading: ${packageJson}`);
|
|
41
|
+
let workspaces = readJsonSafe<{ workspaces: string[] }>(packageJson)?.workspaces;
|
|
42
|
+
|
|
43
|
+
if (!workspaces) {
|
|
44
|
+
const lernaJson = path.resolve(path.join(directory, 'lerna.json'));
|
|
45
|
+
log.debug('find-packages', `reading: ${lernaJson}`);
|
|
46
|
+
workspaces = readJsonSafe<{ packages: string[] }>(lernaJson)?.packages;
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
if (workspaces) {
|
|
50
|
+
workspaces = workspaces.map(
|
|
51
|
+
// Note, glob requires "/" as path separator, even on Windows
|
|
52
|
+
workspace => path.join(directory, workspace).replace(/\\/g, '/')
|
|
53
|
+
);
|
|
54
|
+
/* istanbul ignore next: debug only */
|
|
55
|
+
log.debug('find-packages', () => `found workspaces: ${JSON.stringify(workspaces)}`);
|
|
56
|
+
return workspaces;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
directory = path.resolve(path.join(directory, '../'));
|
|
60
|
+
} while (path.parse(directory).name);
|
|
61
|
+
}
|
|
@@ -71,12 +71,22 @@ type Configuration = {
|
|
|
71
71
|
[key in CommandName]: NodeConfiguration;
|
|
72
72
|
} & NodeConfiguration;
|
|
73
73
|
|
|
74
|
-
|
|
75
|
-
|
|
74
|
+
type LocationOrJson = string | Record<string, any>;
|
|
75
|
+
|
|
76
|
+
export function getConfiguration(locationOrJson: LocationOrJson = './'): Configuration {
|
|
77
|
+
const json =
|
|
78
|
+
typeof locationOrJson === 'string'
|
|
79
|
+
? readJson(path.join(locationOrJson, 'package.json'))
|
|
80
|
+
: locationOrJson;
|
|
81
|
+
return json?.cli ?? {};
|
|
76
82
|
}
|
|
77
83
|
|
|
78
|
-
export function getConfigurationSafe(
|
|
79
|
-
|
|
84
|
+
export function getConfigurationSafe(locationOrJson: LocationOrJson = './'): Configuration {
|
|
85
|
+
const json =
|
|
86
|
+
typeof locationOrJson === 'string'
|
|
87
|
+
? readJsonSafe(path.join(locationOrJson, 'package.json'))
|
|
88
|
+
: locationOrJson;
|
|
89
|
+
return json?.cli ?? {};
|
|
80
90
|
}
|
|
81
91
|
|
|
82
92
|
export function getDevServerConfiguration() {
|
|
@@ -114,8 +124,8 @@ export function getStylelintConfiguration() {
|
|
|
114
124
|
return getConfiguration().lint?.stylelint ?? {};
|
|
115
125
|
}
|
|
116
126
|
|
|
117
|
-
export function isBundle(
|
|
118
|
-
return getConfiguration(
|
|
127
|
+
export function isBundle(locationOrJson?: LocationOrJson) {
|
|
128
|
+
return getConfiguration(locationOrJson).webpack !== false;
|
|
119
129
|
}
|
|
120
130
|
|
|
121
131
|
export function isCustomStyleRules() {
|
|
@@ -138,8 +148,8 @@ export function isExposeSharedDependencies() {
|
|
|
138
148
|
return configuration.webpack['expose-shared-dependencies'] === true;
|
|
139
149
|
}
|
|
140
150
|
|
|
141
|
-
export function isLegacy(
|
|
142
|
-
return getConfiguration(
|
|
151
|
+
export function isLegacy(locationOrJson?: LocationOrJson) {
|
|
152
|
+
return getConfiguration(locationOrJson).legacy === true;
|
|
143
153
|
}
|
|
144
154
|
|
|
145
155
|
export function isLegacyRoot() {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import multimatch from 'multimatch';
|
|
2
|
+
import { findPackages, ProjectPackage } from './find-packages';
|
|
2
3
|
import { isBundle, isLegacy } from './get-configuration';
|
|
3
|
-
import { maybeCreateGitFolder } from './maybe-create-git-folder';
|
|
4
4
|
import { toArray } from './to-array';
|
|
5
5
|
|
|
6
6
|
export enum PackageType {
|
|
@@ -17,8 +17,6 @@ export interface Package {
|
|
|
17
17
|
location: string;
|
|
18
18
|
}
|
|
19
19
|
|
|
20
|
-
type RawPackage = Omit<Package, 'type'>;
|
|
21
|
-
|
|
22
20
|
interface GetPackagesOptions {
|
|
23
21
|
scope?: string | string[];
|
|
24
22
|
ignore?: string | string[];
|
|
@@ -28,26 +26,13 @@ export function getPackages(options: GetPackagesOptions = {}) {
|
|
|
28
26
|
const scope = toArray(options.scope);
|
|
29
27
|
const ignore = toArray(options.ignore);
|
|
30
28
|
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
execa.sync('npx', ['lerna', 'la', '--json']).stdout
|
|
34
|
-
);
|
|
35
|
-
|
|
36
|
-
if (!scope.length && !ignore.length) {
|
|
29
|
+
const allPackages = findPackages();
|
|
30
|
+
if (scope.length === 0 && ignore.length === 0) {
|
|
37
31
|
return withMetadata(allPackages);
|
|
38
32
|
}
|
|
39
33
|
|
|
40
|
-
const filteredPackages
|
|
41
|
-
|
|
42
|
-
'lerna',
|
|
43
|
-
'la',
|
|
44
|
-
...scope.map(v => ['--scope', v]).flat(),
|
|
45
|
-
...ignore.map(v => ['--ignore', v]).flat(),
|
|
46
|
-
'--json',
|
|
47
|
-
]).stdout
|
|
48
|
-
);
|
|
49
|
-
|
|
50
|
-
const graph: Record<string, string[]> = getPackagesGraph();
|
|
34
|
+
const filteredPackages = filterPackages(allPackages, options);
|
|
35
|
+
const graph = buildPackageGraph(allPackages);
|
|
51
36
|
|
|
52
37
|
// We don't need external dependencies
|
|
53
38
|
for (const [vertex, dependencies] of Object.entries(graph)) {
|
|
@@ -77,39 +62,67 @@ export function getPackages(options: GetPackagesOptions = {}) {
|
|
|
77
62
|
return withMetadata(allPackages.filter(({ name }) => used[name]));
|
|
78
63
|
}
|
|
79
64
|
|
|
80
|
-
interface GetPackagesGraphOptions {
|
|
81
|
-
scope?: string | string[];
|
|
82
|
-
ignore?: string | string[];
|
|
83
|
-
}
|
|
84
|
-
|
|
85
65
|
/**
|
|
86
66
|
* Returns packages and their direct dependencies
|
|
87
67
|
*/
|
|
88
|
-
export function getPackagesGraph(options:
|
|
89
|
-
|
|
90
|
-
|
|
68
|
+
export function getPackagesGraph(options: GetPackagesOptions = {}) {
|
|
69
|
+
return buildPackageGraph(filterPackages(findPackages(), options));
|
|
70
|
+
}
|
|
91
71
|
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
72
|
+
function buildPackageGraph(packages: ProjectPackage[]) {
|
|
73
|
+
return packages.reduce<Record<string, string[]>>(
|
|
74
|
+
(result, { name, dependencies = {}, devDependencies = {} }) => {
|
|
75
|
+
result[name] = [...Object.keys(dependencies), ...Object.keys(devDependencies)].sort(
|
|
76
|
+
(a, b) => a.localeCompare(b)
|
|
77
|
+
);
|
|
78
|
+
return result;
|
|
79
|
+
},
|
|
80
|
+
{}
|
|
100
81
|
);
|
|
101
82
|
}
|
|
102
83
|
|
|
103
|
-
function
|
|
104
|
-
|
|
84
|
+
function filterPackages(packages: ProjectPackage[], options: GetPackagesOptions) {
|
|
85
|
+
if (options.ignore === undefined && options.scope === undefined) {
|
|
86
|
+
return packages;
|
|
87
|
+
}
|
|
88
|
+
|
|
89
|
+
const patterns = [...toArray(options.scope), ...negate(toArray(options.ignore))];
|
|
90
|
+
|
|
91
|
+
if (patterns.length) {
|
|
92
|
+
if (!options.scope?.length) {
|
|
93
|
+
patterns.unshift('**');
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
const chosen = new Set(
|
|
98
|
+
multimatch(
|
|
99
|
+
packages.map(item => item.name),
|
|
100
|
+
patterns
|
|
101
|
+
)
|
|
102
|
+
);
|
|
103
|
+
|
|
104
|
+
return packages.filter(({ name }) => chosen.has(name));
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
function withMetadata(packages: ProjectPackage[]): Package[] {
|
|
108
|
+
return packages.map(pkg => {
|
|
109
|
+
const { name, version, location } = pkg;
|
|
110
|
+
return {
|
|
111
|
+
name,
|
|
112
|
+
version,
|
|
113
|
+
private: pkg.private ?? false,
|
|
114
|
+
location,
|
|
115
|
+
type: getPackageType(pkg),
|
|
116
|
+
};
|
|
117
|
+
});
|
|
105
118
|
}
|
|
106
119
|
|
|
107
|
-
function getPackageType(
|
|
108
|
-
if (isLegacy(
|
|
120
|
+
function getPackageType(packageJson: ProjectPackage) {
|
|
121
|
+
if (isLegacy(packageJson)) {
|
|
109
122
|
return PackageType.Legacy;
|
|
110
123
|
}
|
|
111
124
|
|
|
112
|
-
if (isBundle(
|
|
125
|
+
if (isBundle(packageJson)) {
|
|
113
126
|
return PackageType.Webpack;
|
|
114
127
|
}
|
|
115
128
|
|
|
@@ -129,3 +142,7 @@ export function splitPackagesByType(packages: Package[]) {
|
|
|
129
142
|
|
|
130
143
|
return result;
|
|
131
144
|
}
|
|
145
|
+
|
|
146
|
+
function negate(patterns: string[]) {
|
|
147
|
+
return patterns.map(pattern => `!${pattern}`);
|
|
148
|
+
}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Create empty .git folder to workaround issue where Lerna does not
|
|
3
|
-
* detect workspace packages on Windows systems. The empty .git folder
|
|
4
|
-
* causes nx to use the git-hasher when building the project graph.
|
|
5
|
-
* Note this gets fixed (e.g., https://github.com/nrwl/nx/issues/8601) but
|
|
6
|
-
* keeps reappearing (e.g., https://github.com/nrwl/nx/issues/9584 and
|
|
7
|
-
* https://github.com/nrwl/nx/issues/18094)
|
|
8
|
-
*/
|
|
9
|
-
export declare function maybeCreateGitFolder(): void;
|
|
10
|
-
//# sourceMappingURL=maybe-create-git-folder.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"maybe-create-git-folder.d.ts","sourceRoot":"","sources":["../../src/utils/maybe-create-git-folder.ts"],"names":[],"mappings":"AAEA;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,SAOnC"}
|
|
@@ -1,25 +0,0 @@
|
|
|
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
|
-
exports.maybeCreateGitFolder = void 0;
|
|
7
|
-
const fs_1 = __importDefault(require("fs"));
|
|
8
|
-
/**
|
|
9
|
-
* Create empty .git folder to workaround issue where Lerna does not
|
|
10
|
-
* detect workspace packages on Windows systems. The empty .git folder
|
|
11
|
-
* causes nx to use the git-hasher when building the project graph.
|
|
12
|
-
* Note this gets fixed (e.g., https://github.com/nrwl/nx/issues/8601) but
|
|
13
|
-
* keeps reappearing (e.g., https://github.com/nrwl/nx/issues/9584 and
|
|
14
|
-
* https://github.com/nrwl/nx/issues/18094)
|
|
15
|
-
*/
|
|
16
|
-
function maybeCreateGitFolder() {
|
|
17
|
-
if (process.platform !== 'win32') {
|
|
18
|
-
return;
|
|
19
|
-
}
|
|
20
|
-
if (!fs_1.default.existsSync('.git')) {
|
|
21
|
-
fs_1.default.mkdirSync('.git');
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
exports.maybeCreateGitFolder = maybeCreateGitFolder;
|
|
25
|
-
//# sourceMappingURL=maybe-create-git-folder.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"maybe-create-git-folder.js","sourceRoot":"","sources":["../../src/utils/maybe-create-git-folder.ts"],"names":[],"mappings":";;;;;;AAAA,4CAAoB;AAEpB;;;;;;;GAOG;AACH,SAAgB,oBAAoB;IAChC,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO,EAAE,CAAC;QAC/B,OAAO;IACX,CAAC;IACD,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;QACzB,YAAE,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC;IACzB,CAAC;AACL,CAAC;AAPD,oDAOC"}
|
|
@@ -1,41 +0,0 @@
|
|
|
1
|
-
import { fs, vol } from 'memfs';
|
|
2
|
-
|
|
3
|
-
import { maybeCreateGitFolder } from '../maybe-create-git-folder';
|
|
4
|
-
|
|
5
|
-
jest.mock('fs', () => fs);
|
|
6
|
-
|
|
7
|
-
describe(`[startup] Utils`, () => {
|
|
8
|
-
describe(`${maybeCreateGitFolder.name}`, () => {
|
|
9
|
-
const mkdirSpy = jest.spyOn(fs, 'mkdirSync').mockImplementation(jest.fn());
|
|
10
|
-
|
|
11
|
-
beforeEach(() => vol.fromJSON({}));
|
|
12
|
-
|
|
13
|
-
afterEach(() => vol.reset);
|
|
14
|
-
|
|
15
|
-
const subject = () => maybeCreateGitFolder();
|
|
16
|
-
|
|
17
|
-
describe('when running on Windows', () => {
|
|
18
|
-
beforeEach(() => {
|
|
19
|
-
Object.defineProperty(process, 'platform', { value: 'win32' });
|
|
20
|
-
});
|
|
21
|
-
|
|
22
|
-
test('creates .git folder', () => {
|
|
23
|
-
subject();
|
|
24
|
-
|
|
25
|
-
expect(mkdirSpy).toHaveBeenCalledWith('.git');
|
|
26
|
-
});
|
|
27
|
-
});
|
|
28
|
-
|
|
29
|
-
describe('when not running on Windows', () => {
|
|
30
|
-
beforeEach(() => {
|
|
31
|
-
Object.defineProperty(process, 'platform', { value: 'linux' });
|
|
32
|
-
});
|
|
33
|
-
|
|
34
|
-
test('does not create .git folder', () => {
|
|
35
|
-
subject();
|
|
36
|
-
|
|
37
|
-
expect(mkdirSpy).not.toHaveBeenCalledWith();
|
|
38
|
-
});
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
});
|