@servicetitan/startup 35.1.0 → 35.2.0-far-1776.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/mfe-generate-metadata.d.ts.map +1 -1
- package/dist/cli/commands/mfe-generate-metadata.js +6 -1
- package/dist/cli/commands/mfe-generate-metadata.js.map +1 -1
- package/dist/cli/commands/review/rules/require-compatible-launch-darkly-sdk.d.ts.map +1 -1
- package/dist/cli/commands/review/rules/require-compatible-launch-darkly-sdk.js +6 -6
- package/dist/cli/commands/review/rules/require-compatible-launch-darkly-sdk.js.map +1 -1
- package/dist/cli/commands/review/types.d.ts +2 -5
- package/dist/cli/commands/review/types.d.ts.map +1 -1
- package/dist/cli/commands/review/types.js.map +1 -1
- package/dist/utils/find-package-lock.d.ts +2 -0
- package/dist/utils/find-package-lock.d.ts.map +1 -0
- package/dist/utils/find-package-lock.js +26 -0
- package/dist/utils/find-package-lock.js.map +1 -0
- package/dist/utils/find-up.js +4 -4
- package/dist/utils/find-up.js.map +1 -1
- package/dist/utils/get-package-data.d.ts.map +1 -1
- package/dist/utils/get-package-data.js +28 -1
- package/dist/utils/get-package-data.js.map +1 -1
- package/dist/utils/get-package-version.d.ts +2 -0
- package/dist/utils/get-package-version.d.ts.map +1 -0
- package/dist/utils/get-package-version.js +26 -0
- package/dist/utils/get-package-version.js.map +1 -0
- package/dist/utils/index.d.ts +3 -0
- package/dist/utils/index.d.ts.map +1 -1
- package/dist/utils/index.js +3 -0
- package/dist/utils/index.js.map +1 -1
- package/dist/utils/resolve-package-lock-entry.d.ts +11 -0
- package/dist/utils/resolve-package-lock-entry.d.ts.map +1 -0
- package/dist/utils/resolve-package-lock-entry.js +21 -0
- package/dist/utils/resolve-package-lock-entry.js.map +1 -0
- package/dist/webpack/configs/cache-config.d.ts.map +1 -1
- package/dist/webpack/configs/cache-config.js +1 -14
- package/dist/webpack/configs/cache-config.js.map +1 -1
- package/dist/webpack/configs/utils/get-launchdarkly-sdk-version.d.ts.map +1 -1
- package/dist/webpack/configs/utils/get-launchdarkly-sdk-version.js +1 -11
- package/dist/webpack/configs/utils/get-launchdarkly-sdk-version.js.map +1 -1
- package/dist/webpack/configs/utils/get-web-components-version.d.ts.map +1 -1
- package/dist/webpack/configs/utils/get-web-components-version.js +5 -7
- package/dist/webpack/configs/utils/get-web-components-version.js.map +1 -1
- package/package.json +2 -3
- package/src/cli/commands/__tests__/mfe-generate-metadata.test.ts +13 -0
- package/src/cli/commands/mfe-generate-metadata.ts +6 -1
- package/src/cli/commands/review/rules/require-compatible-launch-darkly-sdk.ts +2 -7
- package/src/cli/commands/review/types.ts +3 -8
- package/src/utils/__tests__/find-package-lock.test.ts +35 -0
- package/src/utils/__tests__/get-package-data.test.ts +97 -26
- package/src/utils/__tests__/get-package-version.test.ts +129 -0
- package/src/utils/__tests__/resolve-package-lock-entry.test.ts +99 -0
- package/src/utils/find-package-lock.ts +10 -0
- package/src/utils/find-up.ts +1 -1
- package/src/utils/get-package-data.ts +27 -2
- package/src/utils/get-package-version.ts +21 -0
- package/src/utils/index.ts +3 -0
- package/src/utils/resolve-package-lock-entry.ts +25 -0
- package/src/webpack/configs/cache-config.ts +1 -10
- package/src/webpack/configs/utils/__tests__/get-launchdarkly-sdk-version.test.ts +20 -8
- package/src/webpack/configs/utils/__tests__/get-web-components-version.test.ts +30 -10
- package/src/webpack/configs/utils/get-launchdarkly-sdk-version.ts +2 -12
- package/src/webpack/configs/utils/get-web-components-version.ts +8 -5
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../../../src/webpack/configs/utils/get-web-components-version.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["../../../../src/webpack/configs/utils/get-web-components-version.ts"],"sourcesContent":["import { getPackageVersion } from '../../../utils';\n\nexport function getWebComponentsVersion() {\n const version = getPackageVersion('@servicetitan/web-components');\n if (!version) {\n throw new Error(\n 'Unable to resolve @servicetitan/web-components version from package-lock.json'\n );\n }\n return version;\n}\n"],"names":["getWebComponentsVersion","version","getPackageVersion","Error"],"mappings":";;;;+BAEgBA;;;eAAAA;;;uBAFkB;AAE3B,SAASA;IACZ,MAAMC,UAAUC,IAAAA,wBAAiB,EAAC;IAClC,IAAI,CAACD,SAAS;QACV,MAAM,IAAIE,MACN;IAER;IACA,OAAOF;AACX"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@servicetitan/startup",
|
|
3
|
-
"version": "35.
|
|
3
|
+
"version": "35.2.0-far-1776.1",
|
|
4
4
|
"description": "CLI to create multi-package Lerna projects with TypeScript and React",
|
|
5
5
|
"homepage": "https://docs.st.dev/docs/frontend/uikit/startup",
|
|
6
6
|
"repository": {
|
|
@@ -145,6 +145,5 @@
|
|
|
145
145
|
},
|
|
146
146
|
"cli": {
|
|
147
147
|
"webpack": false
|
|
148
|
-
}
|
|
149
|
-
"gitHead": "f1d49b43f27789cf5cd4bea3e065cd9e33bf5876"
|
|
148
|
+
}
|
|
150
149
|
}
|
|
@@ -35,6 +35,7 @@ describe(`[startup] ${MfeGenerateMetadata.name}`, () => {
|
|
|
35
35
|
|
|
36
36
|
const mockParentPackageJson = {
|
|
37
37
|
name: 'parent-package',
|
|
38
|
+
workspaces: ['packages/*'],
|
|
38
39
|
dependencies: { 'some-dep': '^1.0.0' },
|
|
39
40
|
};
|
|
40
41
|
|
|
@@ -116,6 +117,18 @@ describe(`[startup] ${MfeGenerateMetadata.name}`, () => {
|
|
|
116
117
|
});
|
|
117
118
|
});
|
|
118
119
|
|
|
120
|
+
describe('when tsconfig.json does not exist', () => {
|
|
121
|
+
beforeEach(() => {
|
|
122
|
+
fs.rmSync('tsconfig.json');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('outputs metadata with empty entrypoints', async () => {
|
|
126
|
+
await subject();
|
|
127
|
+
|
|
128
|
+
expect(getMetadataFromStdout().entrypoints).toEqual({});
|
|
129
|
+
});
|
|
130
|
+
});
|
|
131
|
+
|
|
119
132
|
describe('with --output option', () => {
|
|
120
133
|
const outputDir = '/tmp/existing-dir';
|
|
121
134
|
const outputPath = `${outputDir}/metadata.json`;
|
|
@@ -32,7 +32,12 @@ export class MfeGenerateMetadata extends Command<typeof options> {
|
|
|
32
32
|
|
|
33
33
|
const { output } = this.args;
|
|
34
34
|
|
|
35
|
-
|
|
35
|
+
let destination: string;
|
|
36
|
+
try {
|
|
37
|
+
({ destination } = getFolders());
|
|
38
|
+
} catch {
|
|
39
|
+
destination = 'dist';
|
|
40
|
+
}
|
|
36
41
|
const name = getPackageName();
|
|
37
42
|
const packageData = getPackageData();
|
|
38
43
|
const sharedDependencies = loadSharedDependencies(
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import chalk from 'chalk';
|
|
2
2
|
import { execSync } from 'child_process';
|
|
3
3
|
import { satisfies } from 'semver';
|
|
4
|
+
import { resolvePackageLockEntry } from '../../../../utils';
|
|
4
5
|
import { FixCategory, Package, PackageError, PackageRule, Project } from '../types';
|
|
5
6
|
import { applyFilter, checkPackages, setVersion } from '../utils';
|
|
6
7
|
|
|
@@ -121,13 +122,7 @@ export class RequireCompatibleLaunchDarklySdk implements PackageRule {
|
|
|
121
122
|
dependency: string;
|
|
122
123
|
}) {
|
|
123
124
|
const { packages } = this.#project.packageLock;
|
|
124
|
-
return (
|
|
125
|
-
(packageName
|
|
126
|
-
? packages[`node_modules/${packageName}/node_modules/${dependency}`]
|
|
127
|
-
: undefined) ??
|
|
128
|
-
packages[`node_modules/${dependency}`] ??
|
|
129
|
-
{}
|
|
130
|
-
);
|
|
125
|
+
return resolvePackageLockEntry(packages, dependency, packageName);
|
|
131
126
|
}
|
|
132
127
|
|
|
133
128
|
private getTargetJsClientSdkVersion(packageName?: string) {
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import { PackageLockPackages } from '../../../utils';
|
|
2
|
+
|
|
1
3
|
export abstract class PackageRule {
|
|
2
4
|
abstract get id(): string;
|
|
3
5
|
abstract run(project: Project): PackageError | PackageError[] | undefined;
|
|
@@ -9,14 +11,7 @@ export interface Project {
|
|
|
9
11
|
dependencies: Dependencies;
|
|
10
12
|
// Only using this subset of package-lock.json
|
|
11
13
|
packageLock: {
|
|
12
|
-
packages:
|
|
13
|
-
string,
|
|
14
|
-
{
|
|
15
|
-
version: string;
|
|
16
|
-
dependencies?: Record<string, string>;
|
|
17
|
-
peerDependencies?: Record<string, string>;
|
|
18
|
-
}
|
|
19
|
-
>;
|
|
14
|
+
packages: PackageLockPackages;
|
|
20
15
|
location: string;
|
|
21
16
|
};
|
|
22
17
|
packages: Package[];
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
import { fs, vol } from 'memfs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { findPackageLock } from '../find-package-lock';
|
|
4
|
+
|
|
5
|
+
jest.mock('fs', () => fs);
|
|
6
|
+
|
|
7
|
+
describe(`[startup] ${findPackageLock.name}`, () => {
|
|
8
|
+
afterEach(() => vol.reset());
|
|
9
|
+
|
|
10
|
+
const subject = () => findPackageLock();
|
|
11
|
+
|
|
12
|
+
describe('when package-lock.json exists in cwd', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vol.fromJSON({ './package-lock.json': '{}' });
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
test('returns path', () => {
|
|
18
|
+
expect(subject()).toBe(path.resolve('./package-lock.json'));
|
|
19
|
+
});
|
|
20
|
+
});
|
|
21
|
+
|
|
22
|
+
describe('when package-lock.json exists in parent directory', () => {
|
|
23
|
+
beforeEach(() => {
|
|
24
|
+
vol.fromJSON({ '../package-lock.json': '{}' });
|
|
25
|
+
});
|
|
26
|
+
|
|
27
|
+
test('returns path', () => {
|
|
28
|
+
expect(subject()).toBe(path.resolve('../package-lock.json'));
|
|
29
|
+
});
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
test('returns undefined when no package-lock.json exists', () => {
|
|
33
|
+
expect(subject()).toBeUndefined();
|
|
34
|
+
});
|
|
35
|
+
});
|
|
@@ -1,47 +1,118 @@
|
|
|
1
|
+
import { fs, vol } from 'memfs';
|
|
1
2
|
import { getPackageData, getPackageDependencyVersion } from '../get-package-data';
|
|
2
|
-
import { readJson } from '../read-json';
|
|
3
3
|
|
|
4
|
-
jest.mock('
|
|
4
|
+
jest.mock('fs', () => fs);
|
|
5
5
|
|
|
6
6
|
describe(`[startup] Utils`, () => {
|
|
7
7
|
describe(`${getPackageData.name}`, () => {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
8
|
+
afterEach(() => vol.reset());
|
|
9
|
+
|
|
10
|
+
const subject = () => getPackageData();
|
|
11
|
+
|
|
12
|
+
describe('when root package.json with workspaces exists', () => {
|
|
13
|
+
beforeEach(() => {
|
|
14
|
+
vol.fromJSON({
|
|
15
|
+
'./package.json': JSON.stringify({
|
|
16
|
+
name: 'packageName',
|
|
17
|
+
dependencies: { foo: '1.1.0', baz: '3.0.0' },
|
|
18
|
+
}),
|
|
19
|
+
'../package.json': JSON.stringify({
|
|
20
|
+
workspaces: ['packages/*'],
|
|
21
|
+
dependencies: { foo: '1.0.0', bar: '2.0.0' },
|
|
22
|
+
}),
|
|
23
|
+
});
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
test('returns merged dependencies (local overrides root)', () => {
|
|
27
|
+
expect(subject()).toEqual({
|
|
16
28
|
name: 'packageName',
|
|
17
|
-
dependencies: { foo: '1.1.0', baz: '3.0.0' },
|
|
18
|
-
}
|
|
19
|
-
};
|
|
20
|
-
jest.mocked(readJson).mockImplementation(path => packages[path] ?? {});
|
|
29
|
+
dependencies: { foo: '1.1.0', bar: '2.0.0', baz: '3.0.0' },
|
|
30
|
+
});
|
|
31
|
+
});
|
|
21
32
|
});
|
|
22
33
|
|
|
23
|
-
|
|
34
|
+
describe('when no root package.json found', () => {
|
|
35
|
+
beforeEach(() => {
|
|
36
|
+
vol.fromJSON({
|
|
37
|
+
'./package.json': JSON.stringify({
|
|
38
|
+
name: 'rootPackage',
|
|
39
|
+
workspaces: ['packages/*'],
|
|
40
|
+
dependencies: { foo: '1.0.0' },
|
|
41
|
+
}),
|
|
42
|
+
});
|
|
43
|
+
});
|
|
44
|
+
|
|
45
|
+
test('returns only local dependencies', () => {
|
|
46
|
+
expect(subject()).toEqual({
|
|
47
|
+
name: 'rootPackage',
|
|
48
|
+
dependencies: { foo: '1.0.0' },
|
|
49
|
+
});
|
|
50
|
+
});
|
|
51
|
+
});
|
|
52
|
+
|
|
53
|
+
describe('when root has lerna.json with packages instead of workspaces', () => {
|
|
54
|
+
beforeEach(() => {
|
|
55
|
+
vol.fromJSON({
|
|
56
|
+
'./package.json': JSON.stringify({
|
|
57
|
+
name: 'packageName',
|
|
58
|
+
version: '2.0.0',
|
|
59
|
+
dependencies: { foo: '1.0.0' },
|
|
60
|
+
}),
|
|
61
|
+
'../package.json': JSON.stringify({
|
|
62
|
+
dependencies: { bar: '2.0.0' },
|
|
63
|
+
}),
|
|
64
|
+
'../lerna.json': JSON.stringify({
|
|
65
|
+
packages: ['packages/*'],
|
|
66
|
+
}),
|
|
67
|
+
});
|
|
68
|
+
});
|
|
69
|
+
|
|
70
|
+
test('returns dependencies from root discovered via lerna.json', () => {
|
|
71
|
+
expect(subject()).toEqual({
|
|
72
|
+
name: 'packageName',
|
|
73
|
+
version: '2.0.0',
|
|
74
|
+
dependencies: { bar: '2.0.0', foo: '1.0.0' },
|
|
75
|
+
});
|
|
76
|
+
});
|
|
77
|
+
});
|
|
78
|
+
|
|
79
|
+
describe('when root has lerna.json but no package.json at root level', () => {
|
|
80
|
+
beforeEach(() => {
|
|
81
|
+
vol.fromJSON({
|
|
82
|
+
'./package.json': JSON.stringify({
|
|
83
|
+
name: 'packageName',
|
|
84
|
+
version: '3.0.0',
|
|
85
|
+
dependencies: { foo: '1.0.0' },
|
|
86
|
+
}),
|
|
87
|
+
'../lerna.json': JSON.stringify({
|
|
88
|
+
packages: ['packages/*'],
|
|
89
|
+
}),
|
|
90
|
+
});
|
|
91
|
+
});
|
|
24
92
|
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
},
|
|
93
|
+
test('returns only local dependencies', () => {
|
|
94
|
+
expect(subject()).toEqual({
|
|
95
|
+
name: 'packageName',
|
|
96
|
+
version: '3.0.0',
|
|
97
|
+
dependencies: { foo: '1.0.0' },
|
|
98
|
+
});
|
|
32
99
|
});
|
|
33
100
|
});
|
|
34
101
|
|
|
35
|
-
describe(
|
|
102
|
+
describe('when package.json contains sharedDependencies', () => {
|
|
36
103
|
const sharedDependencies = { react: 'SharedDependencies.React' };
|
|
37
104
|
|
|
38
105
|
beforeEach(() => {
|
|
39
|
-
|
|
40
|
-
|
|
106
|
+
vol.fromJSON({
|
|
107
|
+
'./package.json': JSON.stringify({
|
|
108
|
+
name: 'packageName',
|
|
109
|
+
dependencies: { foo: '1.0.0' },
|
|
110
|
+
cli: { webpack: { 'shared-dependencies': sharedDependencies } },
|
|
111
|
+
}),
|
|
41
112
|
});
|
|
42
113
|
});
|
|
43
114
|
|
|
44
|
-
test('
|
|
115
|
+
test('result contains sharedDependencies', () => {
|
|
45
116
|
expect(subject()).toEqual(expect.objectContaining({ sharedDependencies }));
|
|
46
117
|
});
|
|
47
118
|
});
|
|
@@ -0,0 +1,129 @@
|
|
|
1
|
+
import { fs, vol } from 'memfs';
|
|
2
|
+
import { getPackageVersion } from '../get-package-version';
|
|
3
|
+
|
|
4
|
+
jest.mock('fs', () => fs);
|
|
5
|
+
|
|
6
|
+
describe(`[startup] ${getPackageVersion.name}`, () => {
|
|
7
|
+
afterEach(() => vol.reset());
|
|
8
|
+
|
|
9
|
+
const subject = (packageName: string) => getPackageVersion(packageName);
|
|
10
|
+
|
|
11
|
+
beforeEach(() => {
|
|
12
|
+
vol.fromJSON({
|
|
13
|
+
'./package-lock.json': JSON.stringify({
|
|
14
|
+
packages: {
|
|
15
|
+
'node_modules/@servicetitan/web-components': { version: '1.2.3' },
|
|
16
|
+
},
|
|
17
|
+
}),
|
|
18
|
+
});
|
|
19
|
+
});
|
|
20
|
+
|
|
21
|
+
test('returns version for a found package', () => {
|
|
22
|
+
expect(subject('@servicetitan/web-components')).toBe('1.2.3');
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('when package is not in lock file', () => {
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
vol.fromJSON({
|
|
28
|
+
'./package-lock.json': JSON.stringify({
|
|
29
|
+
packages: {},
|
|
30
|
+
}),
|
|
31
|
+
});
|
|
32
|
+
});
|
|
33
|
+
|
|
34
|
+
test('returns undefined', () => {
|
|
35
|
+
expect(subject('nonexistent-package')).toBeUndefined();
|
|
36
|
+
});
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
describe('when package is a linked workspace package', () => {
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
vol.fromJSON({
|
|
42
|
+
'./package-lock.json': JSON.stringify({
|
|
43
|
+
packages: {
|
|
44
|
+
'node_modules/@servicetitan/web-components': {
|
|
45
|
+
resolved: 'packages/web-components',
|
|
46
|
+
link: true,
|
|
47
|
+
},
|
|
48
|
+
'packages/web-components': {
|
|
49
|
+
version: '35.1.0',
|
|
50
|
+
},
|
|
51
|
+
},
|
|
52
|
+
}),
|
|
53
|
+
});
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('follows link to resolve version from source path', () => {
|
|
57
|
+
expect(subject('@servicetitan/web-components')).toBe('35.1.0');
|
|
58
|
+
});
|
|
59
|
+
});
|
|
60
|
+
|
|
61
|
+
describe('when entry has link but no resolved path', () => {
|
|
62
|
+
beforeEach(() => {
|
|
63
|
+
vol.fromJSON({
|
|
64
|
+
'./package-lock.json': JSON.stringify({
|
|
65
|
+
packages: {
|
|
66
|
+
'node_modules/some-package': { link: true, version: '1.0.0' },
|
|
67
|
+
},
|
|
68
|
+
}),
|
|
69
|
+
});
|
|
70
|
+
});
|
|
71
|
+
|
|
72
|
+
test('returns entry version', () => {
|
|
73
|
+
expect(subject('some-package')).toBe('1.0.0');
|
|
74
|
+
});
|
|
75
|
+
});
|
|
76
|
+
|
|
77
|
+
describe('when linked package resolved path does not exist in packages', () => {
|
|
78
|
+
beforeEach(() => {
|
|
79
|
+
vol.fromJSON({
|
|
80
|
+
'./package-lock.json': JSON.stringify({
|
|
81
|
+
packages: {
|
|
82
|
+
'node_modules/some-package': {
|
|
83
|
+
resolved: 'packages/some-package',
|
|
84
|
+
link: true,
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
}),
|
|
88
|
+
});
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
test('returns undefined', () => {
|
|
92
|
+
expect(subject('some-package')).toBeUndefined();
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
describe('when lock file contains invalid JSON', () => {
|
|
97
|
+
beforeEach(() => {
|
|
98
|
+
vol.fromJSON({
|
|
99
|
+
'./package-lock.json': 'not valid json',
|
|
100
|
+
});
|
|
101
|
+
});
|
|
102
|
+
|
|
103
|
+
test('returns undefined', () => {
|
|
104
|
+
expect(subject('some-package')).toBeUndefined();
|
|
105
|
+
});
|
|
106
|
+
});
|
|
107
|
+
|
|
108
|
+
describe('when lock file has no packages property', () => {
|
|
109
|
+
beforeEach(() => {
|
|
110
|
+
vol.fromJSON({
|
|
111
|
+
'./package-lock.json': JSON.stringify({}),
|
|
112
|
+
});
|
|
113
|
+
});
|
|
114
|
+
|
|
115
|
+
test('returns undefined', () => {
|
|
116
|
+
expect(subject('some-package')).toBeUndefined();
|
|
117
|
+
});
|
|
118
|
+
});
|
|
119
|
+
|
|
120
|
+
describe('when package-lock.json does not exist', () => {
|
|
121
|
+
beforeEach(() => {
|
|
122
|
+
fs.rmSync('package-lock.json');
|
|
123
|
+
});
|
|
124
|
+
|
|
125
|
+
test('returns undefined', () => {
|
|
126
|
+
expect(subject('@servicetitan/web-components')).toBeUndefined();
|
|
127
|
+
});
|
|
128
|
+
});
|
|
129
|
+
});
|
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
import { PackageLockPackages, resolvePackageLockEntry } from '../resolve-package-lock-entry';
|
|
2
|
+
|
|
3
|
+
describe(`[startup] ${resolvePackageLockEntry.name}`, () => {
|
|
4
|
+
let packages: PackageLockPackages;
|
|
5
|
+
let packageName: string;
|
|
6
|
+
let scope: string | undefined;
|
|
7
|
+
|
|
8
|
+
beforeEach(() => {
|
|
9
|
+
packages = {};
|
|
10
|
+
packageName = 'foo';
|
|
11
|
+
});
|
|
12
|
+
|
|
13
|
+
const subject = () => resolvePackageLockEntry(packages, packageName, scope);
|
|
14
|
+
|
|
15
|
+
describe('when package exists at top level', () => {
|
|
16
|
+
beforeEach(() => {
|
|
17
|
+
packages['node_modules/foo'] = { version: '1.0.0' };
|
|
18
|
+
});
|
|
19
|
+
|
|
20
|
+
test('resolves the entry', () => {
|
|
21
|
+
expect(subject()).toEqual({ version: '1.0.0' });
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('when package exists both at top level and under a scope', () => {
|
|
26
|
+
beforeEach(() => {
|
|
27
|
+
packages['node_modules/foo'] = { version: '1.0.0' };
|
|
28
|
+
packages['node_modules/parent/node_modules/foo'] = { version: '2.0.0' };
|
|
29
|
+
scope = undefined;
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
describe('when scope is provided', () => {
|
|
33
|
+
beforeEach(() => {
|
|
34
|
+
scope = 'parent';
|
|
35
|
+
});
|
|
36
|
+
|
|
37
|
+
test('resolves scoped entry', () => {
|
|
38
|
+
expect(subject()).toEqual({ version: '2.0.0' });
|
|
39
|
+
});
|
|
40
|
+
});
|
|
41
|
+
|
|
42
|
+
test('resolves top-level entry', () => {
|
|
43
|
+
expect(subject()).toEqual({ version: '1.0.0' });
|
|
44
|
+
});
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
describe('when package has dependencies and peerDependencies', () => {
|
|
48
|
+
beforeEach(() => {
|
|
49
|
+
packages['node_modules/foo'] = {
|
|
50
|
+
version: '1.0.0',
|
|
51
|
+
dependencies: { bar: '^1.0.0' },
|
|
52
|
+
peerDependencies: { baz: '>=2.0.0' },
|
|
53
|
+
};
|
|
54
|
+
});
|
|
55
|
+
|
|
56
|
+
test('returns the full entry', () => {
|
|
57
|
+
expect(subject()).toEqual({
|
|
58
|
+
version: '1.0.0',
|
|
59
|
+
dependencies: { bar: '^1.0.0' },
|
|
60
|
+
peerDependencies: { baz: '>=2.0.0' },
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
describe('when package is a linked workspace package', () => {
|
|
66
|
+
beforeEach(() => {
|
|
67
|
+
packages['node_modules/foo'] = { link: true, resolved: 'packages/foo' };
|
|
68
|
+
packages['packages/foo'] = { version: '3.0.0' };
|
|
69
|
+
});
|
|
70
|
+
|
|
71
|
+
test('follows link to resolved path', () => {
|
|
72
|
+
expect(subject()).toEqual({ version: '3.0.0' });
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
describe('when resolved entry does not exist', () => {
|
|
76
|
+
beforeEach(() => {
|
|
77
|
+
delete packages['packages/foo'];
|
|
78
|
+
});
|
|
79
|
+
|
|
80
|
+
test('returns empty object', () => {
|
|
81
|
+
expect(subject()).toEqual({});
|
|
82
|
+
});
|
|
83
|
+
});
|
|
84
|
+
|
|
85
|
+
describe('when resolved property is missing', () => {
|
|
86
|
+
beforeEach(() => {
|
|
87
|
+
delete packages['node_modules/foo'].resolved;
|
|
88
|
+
});
|
|
89
|
+
|
|
90
|
+
test('returns the entry as-is', () => {
|
|
91
|
+
expect(subject()).toEqual({ link: true });
|
|
92
|
+
});
|
|
93
|
+
});
|
|
94
|
+
});
|
|
95
|
+
|
|
96
|
+
test('returns empty object', () => {
|
|
97
|
+
expect(subject()).toEqual({});
|
|
98
|
+
});
|
|
99
|
+
});
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import fs from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { findUp } from './find-up';
|
|
4
|
+
|
|
5
|
+
export function findPackageLock() {
|
|
6
|
+
return findUp(directory => {
|
|
7
|
+
const lockFile = path.resolve(directory, 'package-lock.json');
|
|
8
|
+
return fs.existsSync(lockFile) ? lockFile : undefined;
|
|
9
|
+
});
|
|
10
|
+
}
|
package/src/utils/find-up.ts
CHANGED
|
@@ -1,4 +1,6 @@
|
|
|
1
|
-
import
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { findUp } from './find-up';
|
|
3
|
+
import { readJson, readJsonSafe } from './read-json';
|
|
2
4
|
|
|
3
5
|
interface PackageData {
|
|
4
6
|
name: string;
|
|
@@ -14,13 +16,36 @@ export function getPackageData(): PackageData {
|
|
|
14
16
|
name: packageJson.name,
|
|
15
17
|
version: packageJson.version,
|
|
16
18
|
dependencies: {
|
|
17
|
-
...
|
|
19
|
+
...findRootDependencies(),
|
|
18
20
|
...packageJson.dependencies,
|
|
19
21
|
},
|
|
20
22
|
sharedDependencies: packageJson.cli?.webpack?.['shared-dependencies'],
|
|
21
23
|
};
|
|
22
24
|
}
|
|
23
25
|
|
|
26
|
+
function findRootDependencies() {
|
|
27
|
+
const cwd = path.resolve('./');
|
|
28
|
+
const root = findUp(directory => {
|
|
29
|
+
if (directory === cwd) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
const pkgPath = path.join(directory, 'package.json');
|
|
33
|
+
const pkg = readJsonSafe<{ workspaces?: string[]; dependencies?: Record<string, string> }>(
|
|
34
|
+
pkgPath
|
|
35
|
+
);
|
|
36
|
+
if (pkg?.workspaces) {
|
|
37
|
+
return pkg;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
const lernaPath = path.join(directory, 'lerna.json');
|
|
41
|
+
if (readJsonSafe<{ packages?: string[] }>(lernaPath)?.packages) {
|
|
42
|
+
return pkg ?? {};
|
|
43
|
+
}
|
|
44
|
+
});
|
|
45
|
+
|
|
46
|
+
return root?.dependencies ?? {};
|
|
47
|
+
}
|
|
48
|
+
|
|
24
49
|
export function getPackageDependencyVersion(dependency: string, defaultVersion?: string) {
|
|
25
50
|
try {
|
|
26
51
|
const { version } = require(`${dependency}/package.json`);
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { findPackageLock } from './find-package-lock';
|
|
2
|
+
import { readJsonSafe } from './read-json';
|
|
3
|
+
import { PackageLockPackages, resolvePackageLockEntry } from './resolve-package-lock-entry';
|
|
4
|
+
|
|
5
|
+
interface PackageLock {
|
|
6
|
+
packages: PackageLockPackages;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export function getPackageVersion(packageName: string) {
|
|
10
|
+
const lockFilePath = findPackageLock();
|
|
11
|
+
if (!lockFilePath) {
|
|
12
|
+
return undefined;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const lockFile = readJsonSafe<PackageLock>(lockFilePath);
|
|
16
|
+
if (!lockFile) {
|
|
17
|
+
return undefined;
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
return resolvePackageLockEntry(lockFile.packages, packageName).version;
|
|
21
|
+
}
|
package/src/utils/index.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
export * from './find-package-lock';
|
|
1
2
|
export * from './find-packages';
|
|
2
3
|
export * from './find-up';
|
|
3
4
|
export * from './format-duration';
|
|
@@ -10,6 +11,7 @@ export * from './get-folders';
|
|
|
10
11
|
export * from './get-jest-config';
|
|
11
12
|
export * from './get-package-data';
|
|
12
13
|
export * from './get-package-name';
|
|
14
|
+
export * from './get-package-version';
|
|
13
15
|
export * from './get-packages';
|
|
14
16
|
export * from './get-startup-version';
|
|
15
17
|
export * from './get-tsconfig';
|
|
@@ -21,4 +23,5 @@ export * from './omit';
|
|
|
21
23
|
export * from './pick';
|
|
22
24
|
export * from './prettify';
|
|
23
25
|
export * from './read-json';
|
|
26
|
+
export * from './resolve-package-lock-entry';
|
|
24
27
|
export * from './to-array';
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
interface PackageLockEntry {
|
|
2
|
+
version?: string;
|
|
3
|
+
resolved?: string;
|
|
4
|
+
link?: boolean;
|
|
5
|
+
dependencies?: Record<string, string>;
|
|
6
|
+
peerDependencies?: Record<string, string>;
|
|
7
|
+
}
|
|
8
|
+
|
|
9
|
+
export type PackageLockPackages = Record<string, PackageLockEntry>;
|
|
10
|
+
|
|
11
|
+
export function resolvePackageLockEntry(
|
|
12
|
+
packages: PackageLockPackages | undefined,
|
|
13
|
+
packageName: string,
|
|
14
|
+
scope?: string
|
|
15
|
+
) {
|
|
16
|
+
const entry =
|
|
17
|
+
(scope ? packages?.[`node_modules/${scope}/node_modules/${packageName}`] : undefined) ??
|
|
18
|
+
packages?.[`node_modules/${packageName}`];
|
|
19
|
+
|
|
20
|
+
if (entry?.link && entry.resolved) {
|
|
21
|
+
return packages?.[entry.resolved] ?? {};
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
return entry ?? {};
|
|
25
|
+
}
|
|
@@ -1,7 +1,5 @@
|
|
|
1
|
-
import fs from 'fs';
|
|
2
|
-
import path from 'path';
|
|
3
1
|
import { Configuration } from 'webpack';
|
|
4
|
-
import {
|
|
2
|
+
import { findPackageLock } from '../../utils';
|
|
5
3
|
import { Context, Overrides } from './types';
|
|
6
4
|
|
|
7
5
|
type Config = Configuration['cache'];
|
|
@@ -28,10 +26,3 @@ export function cacheConfig(context: Context, _overrides: Overrides): Result {
|
|
|
28
26
|
infrastructureLogging: { level: 'error' },
|
|
29
27
|
};
|
|
30
28
|
}
|
|
31
|
-
|
|
32
|
-
function findPackageLock() {
|
|
33
|
-
return findUp(directory => {
|
|
34
|
-
const lockFile = path.resolve(path.join(directory), 'package-lock.json');
|
|
35
|
-
return fs.existsSync(lockFile) ? lockFile : undefined;
|
|
36
|
-
});
|
|
37
|
-
}
|