@servicetitan/startup 24.0.4 → 24.1.0
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 +9 -0
- 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/get-packages.d.ts.map +1 -1
- package/dist/utils/get-packages.js +27 -12
- package/dist/utils/get-packages.js.map +1 -1
- package/package.json +11 -11
- 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/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 +12 -0
- 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-packages.test.ts +47 -10
- package/src/utils/get-packages.ts +32 -17
|
@@ -45,6 +45,10 @@ interface Args extends ArgsPackagePublish, ArgsPackageClean {
|
|
|
45
45
|
export class MFEPublish implements Command {
|
|
46
46
|
constructor(private args: Args) {}
|
|
47
47
|
|
|
48
|
+
description() {
|
|
49
|
+
return 'publish or unpublish MFE packages';
|
|
50
|
+
}
|
|
51
|
+
|
|
48
52
|
@logErrors
|
|
49
53
|
async execute() {
|
|
50
54
|
let packages = splitPackagesByType(getPackages())[PackageType.Webpack] ?? [];
|
|
@@ -93,6 +97,10 @@ export class MFEPublish implements Command {
|
|
|
93
97
|
export class MFEPackagePublish implements Command {
|
|
94
98
|
constructor(private args: ArgsPackagePublish) {}
|
|
95
99
|
|
|
100
|
+
description() {
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
|
|
96
104
|
@logErrors
|
|
97
105
|
async execute() {
|
|
98
106
|
if (!isWebComponent()) {
|
|
@@ -197,6 +205,10 @@ export class MFEPackagePublish implements Command {
|
|
|
197
205
|
export class MFEPackageClean implements Command {
|
|
198
206
|
constructor(private args: ArgsPackageClean) {}
|
|
199
207
|
|
|
208
|
+
description() {
|
|
209
|
+
return undefined;
|
|
210
|
+
}
|
|
211
|
+
|
|
200
212
|
@logErrors
|
|
201
213
|
async execute() {
|
|
202
214
|
if (!isWebComponent()) {
|
|
@@ -121,6 +121,10 @@ function checkStylesWebComponent(files: FileInfo[]) {
|
|
|
121
121
|
}
|
|
122
122
|
|
|
123
123
|
export class StylesCheck implements Command {
|
|
124
|
+
description() {
|
|
125
|
+
return undefined;
|
|
126
|
+
}
|
|
127
|
+
|
|
124
128
|
// eslint-disable-next-line @typescript-eslint/require-await
|
|
125
129
|
async execute() {
|
|
126
130
|
if (isLegacy()) {
|
package/src/cli/index.ts
CHANGED
|
@@ -1,69 +1,23 @@
|
|
|
1
1
|
import execa from 'execa';
|
|
2
2
|
import { argv, Arguments } from 'yargs';
|
|
3
|
-
|
|
4
|
-
import {
|
|
5
|
-
import {
|
|
6
|
-
Build,
|
|
7
|
-
BundlePackage,
|
|
8
|
-
Command,
|
|
9
|
-
ESLintCommand,
|
|
10
|
-
Init,
|
|
11
|
-
Install,
|
|
12
|
-
KendoUILicense,
|
|
13
|
-
Lint,
|
|
14
|
-
MFEPackageClean,
|
|
15
|
-
MFEPackagePublish,
|
|
16
|
-
MFEPublish,
|
|
17
|
-
PreparePackage,
|
|
18
|
-
Start,
|
|
19
|
-
StylesCheck,
|
|
20
|
-
Tests,
|
|
21
|
-
} from './commands';
|
|
3
|
+
import { CommandName, getStartupVersion, log } from '../utils';
|
|
4
|
+
import { getCommand, getUserCommands } from './commands';
|
|
22
5
|
import { setNodeOptions } from './utils';
|
|
23
6
|
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
case CommandName.build:
|
|
31
|
-
return Build;
|
|
32
|
-
case CommandName['bundle-package']:
|
|
33
|
-
return BundlePackage;
|
|
34
|
-
case CommandName.eslint:
|
|
35
|
-
return ESLintCommand;
|
|
36
|
-
case CommandName.init:
|
|
37
|
-
return Init;
|
|
38
|
-
case CommandName.install:
|
|
39
|
-
return Install;
|
|
40
|
-
case CommandName['kendo-ui-license']:
|
|
41
|
-
return KendoUILicense;
|
|
42
|
-
case CommandName.lint:
|
|
43
|
-
return Lint;
|
|
44
|
-
case CommandName['mfe-package-clean']:
|
|
45
|
-
return MFEPackageClean;
|
|
46
|
-
case CommandName['mfe-package-publish']:
|
|
47
|
-
return MFEPackagePublish;
|
|
48
|
-
case CommandName['mfe-publish']:
|
|
49
|
-
return MFEPublish;
|
|
50
|
-
case CommandName['prepare-package']:
|
|
51
|
-
return PreparePackage;
|
|
52
|
-
case CommandName.start:
|
|
53
|
-
return Start;
|
|
54
|
-
case CommandName['styles-check']:
|
|
55
|
-
return StylesCheck;
|
|
56
|
-
case CommandName.test:
|
|
57
|
-
return Tests;
|
|
58
|
-
default:
|
|
59
|
-
log.error(`${name}: command not found!`);
|
|
60
|
-
process.exit(127);
|
|
61
|
-
}
|
|
7
|
+
const argvSync = argv as Arguments;
|
|
8
|
+
const name = argvSync._[0]?.toString() as CommandName;
|
|
9
|
+
if (!name) {
|
|
10
|
+
log.info(`startup cli v${getStartupVersion()}`);
|
|
11
|
+
usage();
|
|
12
|
+
process.exit(0);
|
|
62
13
|
}
|
|
63
14
|
|
|
64
|
-
const argvSync = argv as Arguments;
|
|
65
|
-
const name = argvSync._[0].toString() as CommandName;
|
|
66
15
|
const Command = getCommand(name);
|
|
16
|
+
if (!Command) {
|
|
17
|
+
log.error(`Unknown command: "${name}"`);
|
|
18
|
+
usage();
|
|
19
|
+
process.exit(127);
|
|
20
|
+
}
|
|
67
21
|
|
|
68
22
|
if (setNodeOptions(name)) {
|
|
69
23
|
// Run command in child process with amended NODE_OPTIONS
|
|
@@ -77,3 +31,17 @@ if (setNodeOptions(name)) {
|
|
|
77
31
|
process.exit(1);
|
|
78
32
|
});
|
|
79
33
|
}
|
|
34
|
+
|
|
35
|
+
function usage() {
|
|
36
|
+
write('\nUsage:\n');
|
|
37
|
+
|
|
38
|
+
const commands = getUserCommands().filter(({ name }) => !!name);
|
|
39
|
+
const maxNameLength = commands.reduce((result, { name }) => Math.max(result, name.length), 0);
|
|
40
|
+
commands.forEach(({ name, description }) => {
|
|
41
|
+
write(`startup ${name.padEnd(maxNameLength, ' ')} ${description}`);
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function write(text: string) {
|
|
46
|
+
return console.info(text); // eslint-disable-line no-console
|
|
47
|
+
}
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import execa from 'execa';
|
|
2
2
|
import { isBundle, isLegacy } from '../get-configuration';
|
|
3
|
+
import { log } from '../log';
|
|
3
4
|
import { maybeCreateGitFolder } from '../maybe-create-git-folder';
|
|
4
5
|
|
|
5
6
|
import {
|
|
@@ -21,6 +22,15 @@ describe('[startup] Utils', () => {
|
|
|
21
22
|
{ name: 'baz', location: 'packages/baz', type: PackageType.Webpack },
|
|
22
23
|
];
|
|
23
24
|
|
|
25
|
+
beforeEach(() => jest.clearAllMocks());
|
|
26
|
+
|
|
27
|
+
function expectExecaToBeCalledWith(command: string, options?: execa.SyncOptions) {
|
|
28
|
+
const [file, ...args] = command.split(' ');
|
|
29
|
+
const { calls } = jest.mocked(execa.sync).mock;
|
|
30
|
+
const expected: any[] = [file, args, ...(options ? [options] : [])];
|
|
31
|
+
expect(calls).toContainEqual(expect.arrayContaining(expected));
|
|
32
|
+
}
|
|
33
|
+
|
|
24
34
|
describe(`${getPackages.name}`, () => {
|
|
25
35
|
let options: Parameters<typeof getPackages>[0] | undefined;
|
|
26
36
|
let dependencies: Record<string, string[]> | undefined;
|
|
@@ -72,7 +82,7 @@ describe('[startup] Utils', () => {
|
|
|
72
82
|
|
|
73
83
|
test('returns lerna packages with type metadata', () => {
|
|
74
84
|
expect(subject()).toEqual(packages);
|
|
75
|
-
|
|
85
|
+
expectExecaToBeCalledWith('npx lerna la --json');
|
|
76
86
|
});
|
|
77
87
|
|
|
78
88
|
test('conditionally creates .git folder', () => {
|
|
@@ -81,16 +91,34 @@ describe('[startup] Utils', () => {
|
|
|
81
91
|
expect(maybeCreateGitFolder).toHaveBeenCalled();
|
|
82
92
|
});
|
|
83
93
|
|
|
94
|
+
describe('when running on Windows', () => {
|
|
95
|
+
const originalPlatform = process.platform;
|
|
96
|
+
beforeEach(() => {
|
|
97
|
+
Object.defineProperty(process, 'platform', { value: 'win32' });
|
|
98
|
+
});
|
|
99
|
+
|
|
100
|
+
afterEach(() => {
|
|
101
|
+
Object.defineProperty(process, 'platform', { value: originalPlatform });
|
|
102
|
+
});
|
|
103
|
+
|
|
104
|
+
test('sets NX_CACHE_PROJECT_GRAPH=false', () => {
|
|
105
|
+
subject();
|
|
106
|
+
|
|
107
|
+
expectExecaToBeCalledWith('npx lerna la --json', {
|
|
108
|
+
extendEnv: true,
|
|
109
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
110
|
+
env: { NX_CACHE_PROJECT_GRAPH: 'false' },
|
|
111
|
+
});
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
84
115
|
describe.each(['scope', 'ignore'])('with "%s"', option => {
|
|
85
116
|
beforeEach(() => (options = { [option]: 'foo' }));
|
|
86
117
|
|
|
87
118
|
test(`passes "${option}" option to lerna`, () => {
|
|
88
119
|
subject();
|
|
89
120
|
|
|
90
|
-
|
|
91
|
-
'npx',
|
|
92
|
-
`lerna la --${option} foo --json`.split(' ')
|
|
93
|
-
);
|
|
121
|
+
expectExecaToBeCalledWith(`npx lerna la --${option} foo --json`);
|
|
94
122
|
});
|
|
95
123
|
});
|
|
96
124
|
|
|
@@ -111,6 +139,18 @@ describe('[startup] Utils', () => {
|
|
|
111
139
|
});
|
|
112
140
|
});
|
|
113
141
|
});
|
|
142
|
+
|
|
143
|
+
describe('when execa returns unexpected output', () => {
|
|
144
|
+
beforeEach(() =>
|
|
145
|
+
jest.mocked(execa.sync).mockReturnValue({ stdout: Buffer.from('foo') } as any)
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
test('throws an error and logs the output', () => {
|
|
149
|
+
const logSpy = jest.spyOn(log, 'error');
|
|
150
|
+
expect(() => subject()).toThrow();
|
|
151
|
+
expect(logSpy).toHaveBeenCalledWith(expect.stringContaining('\nfoo'));
|
|
152
|
+
});
|
|
153
|
+
});
|
|
114
154
|
});
|
|
115
155
|
|
|
116
156
|
describe(`${getPackagesGraph.name}`, () => {
|
|
@@ -128,7 +168,7 @@ describe('[startup] Utils', () => {
|
|
|
128
168
|
|
|
129
169
|
test('returns lerna package graph', () => {
|
|
130
170
|
expect(subject()).toEqual(packageGraph);
|
|
131
|
-
|
|
171
|
+
expectExecaToBeCalledWith('npx lerna la --graph');
|
|
132
172
|
});
|
|
133
173
|
|
|
134
174
|
describe.each(['scope', 'ignore'])('with "%s"', option => {
|
|
@@ -137,10 +177,7 @@ describe('[startup] Utils', () => {
|
|
|
137
177
|
test(`passes "${option}" option to lerna`, () => {
|
|
138
178
|
subject();
|
|
139
179
|
|
|
140
|
-
|
|
141
|
-
'npx',
|
|
142
|
-
`lerna la --${option} foo --graph`.split(' ')
|
|
143
|
-
);
|
|
180
|
+
expectExecaToBeCalledWith(`npx lerna la --${option} foo --graph`);
|
|
144
181
|
});
|
|
145
182
|
});
|
|
146
183
|
});
|
|
@@ -2,6 +2,7 @@ import execa from 'execa';
|
|
|
2
2
|
import { isBundle, isLegacy } from './get-configuration';
|
|
3
3
|
import { maybeCreateGitFolder } from './maybe-create-git-folder';
|
|
4
4
|
import { toArray } from './to-array';
|
|
5
|
+
import { log } from './log';
|
|
5
6
|
|
|
6
7
|
export enum PackageType {
|
|
7
8
|
TSC,
|
|
@@ -29,23 +30,13 @@ export function getPackages(options: GetPackagesOptions = {}) {
|
|
|
29
30
|
const ignore = toArray(options.ignore);
|
|
30
31
|
|
|
31
32
|
maybeCreateGitFolder();
|
|
32
|
-
const allPackages: RawPackage[] =
|
|
33
|
-
execa.sync('npx', ['lerna', 'la', '--json']).stdout
|
|
34
|
-
);
|
|
33
|
+
const allPackages: RawPackage[] = listPackages();
|
|
35
34
|
|
|
36
35
|
if (!scope.length && !ignore.length) {
|
|
37
36
|
return withMetadata(allPackages);
|
|
38
37
|
}
|
|
39
38
|
|
|
40
|
-
const filteredPackages: RawPackage[] =
|
|
41
|
-
execa.sync('npx', [
|
|
42
|
-
'lerna',
|
|
43
|
-
'la',
|
|
44
|
-
...scope.map(v => ['--scope', v]).flat(),
|
|
45
|
-
...ignore.map(v => ['--ignore', v]).flat(),
|
|
46
|
-
'--json',
|
|
47
|
-
]).stdout
|
|
48
|
-
);
|
|
39
|
+
const filteredPackages: RawPackage[] = listPackages(options);
|
|
49
40
|
|
|
50
41
|
const graph: Record<string, string[]> = getPackagesGraph();
|
|
51
42
|
|
|
@@ -86,18 +77,42 @@ interface GetPackagesGraphOptions {
|
|
|
86
77
|
* Returns packages and their direct dependencies
|
|
87
78
|
*/
|
|
88
79
|
export function getPackagesGraph(options: GetPackagesGraphOptions = {}): Record<string, string[]> {
|
|
80
|
+
return listPackages({ ...options, graph: true });
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
function listPackages(options: GetPackagesOptions & { graph?: boolean } = {}) {
|
|
89
84
|
const scope = toArray(options.scope);
|
|
90
85
|
const ignore = toArray(options.ignore);
|
|
91
86
|
|
|
92
|
-
|
|
93
|
-
|
|
87
|
+
let execaOptions: execa.SyncOptions | undefined;
|
|
88
|
+
if (process.platform === 'win32') {
|
|
89
|
+
/*
|
|
90
|
+
* Disabled the project graph cache to workaround issue when nx fails with
|
|
91
|
+
* "Error: EPERM: operation not permitted, rename ..." error when multiple
|
|
92
|
+
* processes simultaneously generate the project graph.
|
|
93
|
+
*/
|
|
94
|
+
// eslint-disable-next-line @typescript-eslint/naming-convention
|
|
95
|
+
execaOptions = { extendEnv: true, env: { NX_CACHE_PROJECT_GRAPH: 'false' } };
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
const output = execa.sync(
|
|
99
|
+
'npx',
|
|
100
|
+
[
|
|
94
101
|
'lerna',
|
|
95
102
|
'la',
|
|
96
103
|
...scope.map(v => ['--scope', v]).flat(),
|
|
97
104
|
...ignore.map(v => ['--ignore', v]).flat(),
|
|
98
|
-
'--graph',
|
|
99
|
-
]
|
|
100
|
-
|
|
105
|
+
options.graph ? '--graph' : '--json',
|
|
106
|
+
],
|
|
107
|
+
execaOptions
|
|
108
|
+
).stdout;
|
|
109
|
+
|
|
110
|
+
try {
|
|
111
|
+
return JSON.parse(output);
|
|
112
|
+
} catch (error) {
|
|
113
|
+
log.error(`error: could not parse lerna output:\n${output}`);
|
|
114
|
+
throw error;
|
|
115
|
+
}
|
|
101
116
|
}
|
|
102
117
|
|
|
103
118
|
function withMetadata(packages: RawPackage[]): Package[] {
|