@cloud-ru/ft-deps-validator 1.1.1 → 1.1.2-preview-8996d18.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.
Files changed (115) hide show
  1. package/README.md +34 -15
  2. package/dist/cjs/Checker/MonorepoChecker.d.ts +10 -0
  3. package/dist/cjs/Checker/MonorepoChecker.js +57 -0
  4. package/dist/cjs/Checker/RepoChecker.d.ts +8 -0
  5. package/dist/cjs/Checker/RepoChecker.js +36 -0
  6. package/dist/cjs/Checker/__tests__/MonorepoChecker.spec.js +305 -0
  7. package/dist/cjs/Checker/__tests__/RepoChecker.spec.js +116 -0
  8. package/dist/cjs/Checker/index.d.ts +2 -0
  9. package/dist/cjs/Checker/index.js +7 -0
  10. package/dist/cjs/Config/MonorepoConfig.d.ts +12 -0
  11. package/dist/cjs/Config/MonorepoConfig.js +42 -0
  12. package/dist/cjs/Config/RepoConfig.d.ts +10 -0
  13. package/dist/cjs/Config/RepoConfig.js +27 -0
  14. package/dist/cjs/Config/__tests__/MonorepoConfig.spec.js +291 -0
  15. package/dist/cjs/Config/__tests__/RepoConfig.spec.d.ts +1 -0
  16. package/dist/cjs/Config/__tests__/RepoConfig.spec.js +99 -0
  17. package/dist/cjs/Config/index.d.ts +2 -0
  18. package/dist/cjs/Config/index.js +7 -0
  19. package/dist/cjs/Report/__tests__/Report.spec.d.ts +1 -0
  20. package/dist/cjs/Report/__tests__/Report.spec.js +176 -0
  21. package/dist/cjs/Report/index.d.ts +11 -0
  22. package/dist/cjs/Report/index.js +55 -0
  23. package/dist/cjs/index.d.ts +0 -1
  24. package/dist/cjs/index.js +13 -57
  25. package/dist/{esm/types/config.d.ts → cjs/types.d.ts} +14 -3
  26. package/dist/cjs/utils/__tests__/getCliArguments.spec.d.ts +1 -0
  27. package/dist/cjs/utils/__tests__/getCliArguments.spec.js +70 -0
  28. package/dist/cjs/utils/getCliArguments.d.ts +6 -6
  29. package/dist/cjs/utils/getCliArguments.js +1 -27
  30. package/dist/cjs/utils/getConfigFile.d.ts +4 -3
  31. package/dist/cjs/utils/getConfigFile.js +3 -9
  32. package/dist/cjs/utils/getEnvironment.d.ts +3 -0
  33. package/dist/cjs/utils/getEnvironment.js +50 -0
  34. package/dist/cjs/utils/readPackageJsonFile.d.ts +9 -0
  35. package/dist/cjs/utils/readPackageJsonFile.js +28 -0
  36. package/dist/esm/Checker/MonorepoChecker.d.ts +10 -0
  37. package/dist/esm/Checker/MonorepoChecker.js +53 -0
  38. package/dist/esm/Checker/RepoChecker.d.ts +8 -0
  39. package/dist/esm/Checker/RepoChecker.js +29 -0
  40. package/dist/esm/Checker/__tests__/MonorepoChecker.spec.d.ts +1 -0
  41. package/dist/esm/Checker/__tests__/MonorepoChecker.spec.js +300 -0
  42. package/dist/esm/Checker/__tests__/RepoChecker.spec.d.ts +1 -0
  43. package/dist/esm/Checker/__tests__/RepoChecker.spec.js +111 -0
  44. package/dist/esm/Checker/index.d.ts +2 -0
  45. package/dist/esm/Checker/index.js +2 -0
  46. package/dist/esm/Config/MonorepoConfig.d.ts +12 -0
  47. package/dist/esm/Config/MonorepoConfig.js +35 -0
  48. package/dist/esm/Config/RepoConfig.d.ts +10 -0
  49. package/dist/esm/Config/RepoConfig.js +20 -0
  50. package/dist/esm/Config/__tests__/MonorepoConfig.spec.d.ts +1 -0
  51. package/dist/esm/Config/__tests__/MonorepoConfig.spec.js +289 -0
  52. package/dist/esm/Config/__tests__/RepoConfig.spec.d.ts +1 -0
  53. package/dist/esm/Config/__tests__/RepoConfig.spec.js +94 -0
  54. package/dist/esm/Config/index.d.ts +2 -0
  55. package/dist/esm/Config/index.js +2 -0
  56. package/dist/esm/Report/__tests__/Report.spec.d.ts +1 -0
  57. package/dist/esm/Report/__tests__/Report.spec.js +174 -0
  58. package/dist/esm/Report/index.d.ts +11 -0
  59. package/dist/esm/Report/index.js +51 -0
  60. package/dist/esm/index.d.ts +0 -1
  61. package/dist/esm/index.js +14 -55
  62. package/dist/{cjs/types/config.d.ts → esm/types.d.ts} +14 -3
  63. package/dist/esm/types.js +1 -0
  64. package/dist/esm/utils/__tests__/getCliArguments.spec.d.ts +1 -0
  65. package/dist/esm/utils/__tests__/getCliArguments.spec.js +68 -0
  66. package/dist/esm/utils/getCliArguments.d.ts +6 -6
  67. package/dist/esm/utils/getCliArguments.js +1 -27
  68. package/dist/esm/utils/getConfigFile.d.ts +4 -3
  69. package/dist/esm/utils/getConfigFile.js +3 -9
  70. package/dist/esm/utils/getEnvironment.d.ts +3 -0
  71. package/dist/esm/utils/getEnvironment.js +42 -0
  72. package/dist/esm/utils/readPackageJsonFile.d.ts +9 -0
  73. package/dist/esm/utils/readPackageJsonFile.js +20 -0
  74. package/package.json +2 -2
  75. package/src/Checker/MonorepoChecker.ts +45 -0
  76. package/src/Checker/RepoChecker.ts +23 -0
  77. package/src/Checker/__tests__/MonorepoChecker.spec.ts +330 -0
  78. package/src/Checker/__tests__/RepoChecker.spec.ts +132 -0
  79. package/src/Checker/index.ts +2 -0
  80. package/src/Config/MonorepoConfig.ts +51 -0
  81. package/src/Config/RepoConfig.ts +30 -0
  82. package/src/Config/__tests__/MonorepoConfig.spec.ts +346 -0
  83. package/src/Config/__tests__/RepoConfig.spec.ts +131 -0
  84. package/src/Config/index.ts +2 -0
  85. package/src/Report/__tests__/Report.spec.ts +221 -0
  86. package/src/Report/index.ts +75 -0
  87. package/src/index.ts +14 -67
  88. package/src/{types/config.ts → types.ts} +15 -3
  89. package/src/utils/__tests__/getCliArguments.spec.ts +89 -0
  90. package/src/utils/getCliArguments.ts +1 -35
  91. package/src/utils/getConfigFile.ts +7 -11
  92. package/src/utils/getEnvironment.ts +53 -0
  93. package/src/utils/readPackageJsonFile.ts +20 -0
  94. package/dist/cjs/types/cliArguments.d.ts +0 -4
  95. package/dist/cjs/types/config.js +0 -2
  96. package/dist/cjs/types/state.d.ts +0 -6
  97. package/dist/cjs/types/state.js +0 -2
  98. package/dist/cjs/utils/getMonorepoPrefix.d.ts +0 -6
  99. package/dist/cjs/utils/getMonorepoPrefix.js +0 -33
  100. package/dist/cjs/utils/initializeState.d.ts +0 -8
  101. package/dist/cjs/utils/initializeState.js +0 -40
  102. package/dist/esm/types/cliArguments.d.ts +0 -4
  103. package/dist/esm/types/state.d.ts +0 -6
  104. package/dist/esm/utils/getMonorepoPrefix.d.ts +0 -6
  105. package/dist/esm/utils/getMonorepoPrefix.js +0 -27
  106. package/dist/esm/utils/initializeState.d.ts +0 -8
  107. package/dist/esm/utils/initializeState.js +0 -34
  108. package/src/types/cliArguments.ts +0 -5
  109. package/src/types/state.ts +0 -6
  110. package/src/utils/getMonorepoPrefix.ts +0 -32
  111. package/src/utils/initializeState.ts +0 -51
  112. /package/dist/{esm/types/cliArguments.js → cjs/Checker/__tests__/MonorepoChecker.spec.d.ts} +0 -0
  113. /package/dist/{esm/types/config.js → cjs/Checker/__tests__/RepoChecker.spec.d.ts} +0 -0
  114. /package/dist/{esm/types/state.js → cjs/Config/__tests__/MonorepoConfig.spec.d.ts} +0 -0
  115. /package/dist/cjs/{types/cliArguments.js → types.js} +0 -0
@@ -0,0 +1,75 @@
1
+ import { Results } from 'depcheck';
2
+
3
+ import { logError, logInfo } from '../utils/console';
4
+
5
+ type Messages = ['info' | 'error', number, string][];
6
+
7
+ export type CheckState = Partial<
8
+ Pick<Results, 'dependencies' | 'missing'> & {
9
+ wrongVersions: string[];
10
+ internalAsDev: string[];
11
+ }
12
+ >;
13
+
14
+ export class Report {
15
+ private storage: Record<string, CheckState> = {};
16
+
17
+ public add(folder: string, state: CheckState) {
18
+ if (this.storage[folder]) {
19
+ throw new Error(`There is check state in storage already for: ${folder}`);
20
+ }
21
+
22
+ this.storage[folder] = state;
23
+ }
24
+
25
+ public printResultAndGetExitCode(): 1 | 0 {
26
+ let exitCode: 1 | 0 = 0;
27
+
28
+ for (const [
29
+ packageName,
30
+ { dependencies = [], internalAsDev = [], wrongVersions = [], missing = {} },
31
+ ] of Object.entries(this.storage)) {
32
+ const messages: Messages = [['info', 0, packageName]];
33
+
34
+ if (wrongVersions.length) {
35
+ messages.push(['error', 1, 'wrong version of internal packages:']);
36
+ wrongVersions.forEach(dep => messages.push(['error', 2, dep]));
37
+ }
38
+
39
+ if (internalAsDev.length) {
40
+ messages.push(['error', 1, 'incorrect usage as dev dep of internal packages:']);
41
+ internalAsDev.forEach(dep => messages.push(['error', 2, dep]));
42
+ }
43
+
44
+ if (dependencies.length) {
45
+ messages.push(['error', 1, 'unused dependencies:']);
46
+ dependencies.forEach(dep => messages.push(['error', 2, dep]));
47
+ }
48
+
49
+ const missingEntities = Object.entries(missing);
50
+ if (missingEntities.length) {
51
+ messages.push(['error', 1, 'missing dependencies:']);
52
+ for (const [packageName, files] of missingEntities) {
53
+ messages.push(['error', 2, packageName]);
54
+ for (const file of files) {
55
+ messages.push(['error', 2, file]);
56
+ }
57
+ }
58
+ }
59
+
60
+ if (messages.length > 1) {
61
+ exitCode = 1;
62
+ this.printMessages(messages);
63
+ }
64
+ }
65
+
66
+ return exitCode;
67
+ }
68
+
69
+ private printMessages(messages: Messages) {
70
+ for (const [level, tabs, message] of messages) {
71
+ const log = level === 'info' ? logInfo : logError;
72
+ log(`${'\t'.repeat(tabs)}${message}`);
73
+ }
74
+ }
75
+ }
package/src/index.ts CHANGED
@@ -1,77 +1,24 @@
1
- #!/usr/bin/env node
2
-
3
- import depCheck from 'depcheck';
4
- import { globSync } from 'glob';
5
-
6
- import { logDebug, logError, logInfo } from './utils/console';
7
- import { getCliArguments } from './utils/getCliArguments';
8
- import { getConfigFile } from './utils/getConfigFile';
9
- import { initializeState } from './utils/initializeState';
1
+ import { MonorepoChecker, RepoChecker } from './Checker';
2
+ import { MonorepoConfig } from './Config';
3
+ import { RepoConfig } from './Config/RepoConfig';
4
+ import { logError } from './utils/console';
5
+ import { getEnvironment, isMonorepoEnv } from './utils/getEnvironment';
10
6
 
11
7
  (async () => {
12
8
  try {
13
- const args = getCliArguments();
14
- const configFile = getConfigFile(args.cwd);
15
-
16
- const config = configFile ? Object.assign(args, configFile) : args;
17
-
18
- const options = {
19
- ignoreBinPackage: false,
20
- skipMissing: false,
21
- ignorePatterns: config.ignorePatterns.map(pattern => pattern.toString()),
22
- ignoreMatches: config.ignoreMatches.map(match => match.toString()),
23
- };
24
-
25
- const folders = globSync(config.rootPackagesFolderPattern, {
26
- ignore: config.ignoredPackagesFolderFiles.map(path => path.toString()),
27
- });
28
- const state = initializeState({
29
- cwd: args.cwd,
30
- folders,
31
- prefix: config.prefix,
32
- });
33
-
34
- for (const folder of folders) {
35
- const { dependencies, missing: missingDepsPerPackage } = await depCheck(folder, options);
9
+ const env = getEnvironment();
36
10
 
37
- state.unusedDeps.push(...dependencies.map(x => `${folder}: ${x}`));
11
+ const checker = isMonorepoEnv(env)
12
+ ? new MonorepoChecker(new MonorepoConfig(env))
13
+ : new RepoChecker(new RepoConfig(env));
38
14
 
39
- if (Object.keys(missingDepsPerPackage).length) {
40
- state.missing.push(missingDepsPerPackage);
41
- }
42
- }
15
+ const report = await checker.check();
43
16
 
44
- if (Object.values(state).every(result => result.length < 1)) {
45
- logInfo('Dependencies have been checked. Everything is ok.');
46
- process.exit(0);
47
- return;
48
- }
17
+ const exitCode = report.printResultAndGetExitCode();
49
18
 
50
- if (state.wrongVersions.length) {
51
- logError('You have to fix wrong version of internal packages:');
52
- state.wrongVersions.forEach(logDebug);
53
- }
54
-
55
- if (state.internalAsDev.length) {
56
- logError(
57
- 'You have to fix wrong usage of internal packages in dev dependencies (either delete them or move to dependencies):',
58
- );
59
- state.internalAsDev.forEach(logDebug);
60
- }
61
-
62
- if (state.unusedDeps.length) {
63
- logError('You have to fix following unused dependencies:');
64
- state.unusedDeps.forEach(logDebug);
65
- }
66
-
67
- if (state.missing.length) {
68
- logError('You have to fix following missed dependencies:');
69
- state.missing.forEach(x => logDebug(JSON.stringify(x, null, 2)));
70
- }
71
-
72
- process.exit(1);
73
- } catch (err) {
74
- console.error(err);
19
+ process.exit(exitCode);
20
+ } catch (e: unknown) {
21
+ logError(`${e}`);
75
22
  process.exit(1);
76
23
  }
77
24
  })();
@@ -1,12 +1,24 @@
1
- export type Config = {
1
+ type BaseEnvType = {
2
2
  /** Directories names that should be ignored */
3
3
  ignorePatterns?: string[];
4
4
  /** Names of packages that should be ignored */
5
5
  ignoreMatches?: string[];
6
- /** Monorepo prefix (if skipped will try to find automatically) */
7
- prefix?: string;
6
+ };
7
+
8
+ export type RawRepoEnvType = BaseEnvType & { packages?: Record<string, BaseEnvType> };
9
+
10
+ export type RawMonorepoEnvType = {
8
11
  /** One or more paths that should be ignored in packages folder */
9
12
  ignoredPackagesFolderFiles?: string[];
10
13
  /** Folder containing packages (glob pattern, e.g., "packages/*" or "apps/*") */
11
14
  rootPackagesFolderPattern?: string;
15
+ } & RawRepoEnvType;
16
+
17
+ export type RepoEnvType = RawRepoEnvType & {
18
+ cwd: string;
19
+ };
20
+
21
+ export type MonorepoEnvType = RawMonorepoEnvType & {
22
+ cwd: string;
23
+ rootPackagesFolderPattern: string;
12
24
  };
@@ -0,0 +1,89 @@
1
+ import { beforeEach, describe, expect, it, vi } from 'vitest';
2
+
3
+ import { getCliArguments } from '../getCliArguments';
4
+
5
+ describe('@cloud-ru/ft-deps-validator/getCliArguments', () => {
6
+ const originalArgv = process.argv;
7
+
8
+ beforeEach(() => {
9
+ process.argv = originalArgv;
10
+ vi.clearAllMocks();
11
+ });
12
+
13
+ it('should return empty object when no arguments provided', () => {
14
+ process.argv = ['node', 'script.js'];
15
+ const result = getCliArguments();
16
+
17
+ expect(result.cwd).toBeUndefined();
18
+ expect(result.rootPackagesFolderPattern).toBeUndefined();
19
+ expect(result.ignoredPackagesFolderFiles).toBeUndefined();
20
+ expect(result.ignorePatterns).toBeUndefined();
21
+ expect(result.ignoreMatches).toBeUndefined();
22
+ });
23
+
24
+ it('should parse cwd option', () => {
25
+ const testCwd = '/test/directory';
26
+ process.argv = ['node', 'script.js', '--cwd', testCwd];
27
+ const result = getCliArguments();
28
+
29
+ expect(result.cwd).toBe(testCwd);
30
+ });
31
+
32
+ it('should parse cwd option with alias -d', () => {
33
+ const testCwd = '/test/directory';
34
+ process.argv = ['node', 'script.js', '-d', testCwd];
35
+ const result = getCliArguments();
36
+
37
+ expect(result.cwd).toBe(testCwd);
38
+ });
39
+
40
+ it('should parse rootPackagesFolderPattern option', () => {
41
+ const pattern = 'apps/*';
42
+ process.argv = ['node', 'script.js', '--rootPackagesFolderPattern', pattern];
43
+ const result = getCliArguments();
44
+
45
+ expect(result.rootPackagesFolderPattern).toBe(pattern);
46
+ });
47
+
48
+ it('should parse rootPackagesFolderPattern option with alias -p', () => {
49
+ const pattern = 'apps/*';
50
+ process.argv = ['node', 'script.js', '-p', pattern];
51
+ const result = getCliArguments();
52
+
53
+ expect(result.rootPackagesFolderPattern).toBe(pattern);
54
+ });
55
+
56
+ it('should parse ignoredPackagesFolderFiles option', () => {
57
+ const files = ['file1.json', 'file2.json'];
58
+ process.argv = ['node', 'script.js', '--ignoredPackagesFolderFiles', ...files];
59
+ const result = getCliArguments();
60
+
61
+ expect(result.ignoredPackagesFolderFiles).toEqual(files);
62
+ });
63
+
64
+ it('should parse ignorePatterns option', () => {
65
+ const patterns = ['test', 'build'];
66
+ process.argv = ['node', 'script.js', '--ignorePatterns', ...patterns];
67
+ const result = getCliArguments();
68
+
69
+ expect(result.ignorePatterns).toEqual(patterns);
70
+ });
71
+
72
+ it('should parse ignoreMatches option', () => {
73
+ const matches = ['package1', 'package2'];
74
+ process.argv = ['node', 'script.js', '--ignoreMatches', ...matches];
75
+ const result = getCliArguments();
76
+
77
+ expect(result.ignoreMatches).toEqual(matches);
78
+ });
79
+
80
+ it('should parse multiple options together', () => {
81
+ const testCwd = '/test/directory';
82
+ const pattern = 'apps/*';
83
+ process.argv = ['node', 'script.js', '--cwd', testCwd, '--rootPackagesFolderPattern', pattern];
84
+ const result = getCliArguments();
85
+
86
+ expect(result.cwd).toBe(testCwd);
87
+ expect(result.rootPackagesFolderPattern).toBe(pattern);
88
+ });
89
+ });
@@ -1,48 +1,27 @@
1
- import path from 'path';
2
-
3
1
  import yargs from 'yargs';
4
2
 
5
3
  export function getCliArguments() {
6
- const parsed = yargs(process.argv.slice(2))
4
+ return yargs(process.argv.slice(2))
7
5
  .option('cwd', {
8
6
  alias: 'd',
9
7
  type: 'string',
10
- default: process.cwd(),
11
8
  description: 'working directory (default: current working directory, cwd)',
12
9
  })
13
- .option('prefix', {
14
- type: 'string',
15
- description: 'monorepo prefix (if skipped will try to find automatically)',
16
- })
17
10
  .option('rootPackagesFolderPattern', {
18
11
  alias: 'p',
19
12
  type: 'string',
20
- default: 'packages/*',
21
13
  description: 'folder containing packages (glob pattern, e.g., "packages/*" or "apps/*")',
22
14
  })
23
15
  .option('ignoredPackagesFolderFiles', {
24
16
  type: 'array',
25
- default: ['packages/tsconfig.cjs.json', 'packages/tsconfig.esm.json'],
26
17
  description: 'specify one or more paths that should be ignored in packages folder',
27
18
  })
28
19
  .option('ignorePatterns', {
29
20
  type: 'array',
30
- default: ['stories', 'dist', '__tests__', '__e2e__'],
31
21
  description: 'specify one or more directories names that should be ignored',
32
22
  })
33
23
  .option('ignoreMatches', {
34
24
  type: 'array',
35
- default: [
36
- 'react',
37
- 'react-dom',
38
- 'react-docgen-typescript',
39
- '@snack-uikit/figma-tokens',
40
- '@sbercloud/figma-tokens-cloud-platform',
41
- '@sbercloud/figma-tokens-mlspace',
42
- '@sbercloud/figma-tokens-admin',
43
- '@sbercloud/figma-tokens-web',
44
- '@sbercloud/figma-tokens-giga-id',
45
- ],
46
25
  description: 'specify one or more packages that should be ignored',
47
26
  })
48
27
  .locale('en')
@@ -50,17 +29,4 @@ export function getCliArguments() {
50
29
  .alias('h', 'help')
51
30
  .alias('v', 'version')
52
31
  .parseSync();
53
-
54
- const cwd = path.resolve(parsed.cwd);
55
-
56
- const rootPackagesFolderPattern = path.resolve(cwd, parsed.rootPackagesFolderPattern);
57
-
58
- const ignoredPackagesFolderFiles = parsed.ignoredPackagesFolderFiles.map(file => path.resolve(cwd, file.toString()));
59
-
60
- return {
61
- ...parsed,
62
- cwd,
63
- rootPackagesFolderPattern,
64
- ignoredPackagesFolderFiles,
65
- };
66
32
  }
@@ -1,23 +1,19 @@
1
1
  import fs from 'fs';
2
2
  import path from 'path';
3
3
 
4
- import { CliArguments } from '../types/cliArguments';
5
- import { Config } from '../types/config';
4
+ import { RawMonorepoEnvType, RawRepoEnvType } from '../types';
6
5
 
7
6
  const CONFIG_FILE_NAME = 'deps-validator.config.json';
8
7
 
9
- export function getConfigFile(cwd: CliArguments['cwd']): Config | null {
8
+ type PossibleConfig = RawMonorepoEnvType & RawRepoEnvType;
9
+
10
+ export function getConfigFile(cwd: string): PossibleConfig {
10
11
  const configPath = path.resolve(cwd, CONFIG_FILE_NAME);
11
12
 
12
13
  if (!fs.existsSync(configPath)) {
13
- return null;
14
+ return { packages: {} };
14
15
  }
15
16
 
16
- try {
17
- const configContent = fs.readFileSync(configPath, 'utf-8');
18
- const config = JSON.parse(configContent) as Config;
19
- return config;
20
- } catch {
21
- return null;
22
- }
17
+ const configContent = fs.readFileSync(configPath, 'utf-8');
18
+ return JSON.parse(configContent) as PossibleConfig;
23
19
  }
@@ -0,0 +1,53 @@
1
+ import fs from 'node:fs';
2
+ import path from 'node:path';
3
+
4
+ import { MonorepoEnvType, RepoEnvType } from '../types';
5
+ import { getCliArguments } from './getCliArguments';
6
+ import { getConfigFile } from './getConfigFile';
7
+
8
+ export function getEnvironment(): MonorepoEnvType | RepoEnvType {
9
+ const defaultConfig = {
10
+ cwd: process.cwd(),
11
+ ignoredPackagesFolderFiles: ['packages/tsconfig.cjs.json', 'packages/tsconfig.esm.json'],
12
+ ignorePatterns: ['stories', 'dist', '__tests__', '__e2e__'],
13
+ ignoreMatches: [
14
+ 'react',
15
+ 'react-dom',
16
+ 'react-docgen-typescript',
17
+ '@snack-uikit/figma-tokens',
18
+ '@sbercloud/figma-tokens-cloud-platform',
19
+ '@sbercloud/figma-tokens-mlspace',
20
+ '@sbercloud/figma-tokens-admin',
21
+ '@sbercloud/figma-tokens-web',
22
+ '@sbercloud/figma-tokens-giga-id',
23
+ ],
24
+ };
25
+
26
+ const configFile = getConfigFile(defaultConfig.cwd);
27
+ const configArguments = getCliArguments();
28
+ const rootIsNotPassed = !configFile.rootPackagesFolderPattern && !configArguments.ignoredPackagesFolderFiles;
29
+
30
+ const rawConfig = Object.assign(
31
+ defaultConfig,
32
+ /* конфиг файл имеет меньший приоритет перед cli-аргументами */
33
+ configFile,
34
+ configArguments,
35
+ );
36
+
37
+ if (rootIsNotPassed) {
38
+ /*
39
+ Если папку не передали в конфиге, то проверим на наличие папки сами,
40
+ если она есть, то считаем что это монорепа
41
+ */
42
+ if (fs.existsSync(path.resolve(defaultConfig.cwd, './packages'))) {
43
+ rawConfig.rootPackagesFolderPattern = 'packages/*';
44
+ } else {
45
+ delete rawConfig.rootPackagesFolderPattern;
46
+ }
47
+ }
48
+
49
+ return rawConfig;
50
+ }
51
+
52
+ export const isMonorepoEnv = (env: MonorepoEnvType | RepoEnvType): env is MonorepoEnvType =>
53
+ Boolean('rootPackagesFolderPattern' in env);
@@ -0,0 +1,20 @@
1
+ import fs from 'node:fs';
2
+ import fsp from 'node:fs/promises';
3
+ import path from 'node:path';
4
+
5
+ type PackageJson = {
6
+ name: string;
7
+ version: string;
8
+ dependencies: Record<string, string>;
9
+ devDependencies: Record<string, string>;
10
+ };
11
+
12
+ export const readPackageJsonFile = async (folder: string): Promise<PackageJson> => {
13
+ const file = await fsp.readFile(path.relative(folder, './package.json'), 'utf8');
14
+ return JSON.parse(file);
15
+ };
16
+
17
+ export const readPackageJsonFileSync = (folder: string): PackageJson => {
18
+ const file = fs.readFileSync(path.resolve(folder, './package.json'), 'utf8');
19
+ return JSON.parse(file);
20
+ };
@@ -1,4 +0,0 @@
1
- import { Config } from './config';
2
- export type CliArguments = Config & {
3
- cwd: string;
4
- };
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,6 +0,0 @@
1
- export type State = {
2
- wrongVersions: string[];
3
- internalAsDev: string[];
4
- unusedDeps: string[];
5
- missing: Array<Record<string, string[]>>;
6
- };
@@ -1,2 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", { value: true });
@@ -1,6 +0,0 @@
1
- type Options = {
2
- cwd: string;
3
- folders: string[];
4
- };
5
- export declare function getMonorepoPrefix({ cwd, folders }: Options): string | null;
6
- export {};
@@ -1,33 +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.getMonorepoPrefix = getMonorepoPrefix;
7
- const path_1 = __importDefault(require("path"));
8
- function getMonorepoPrefix({ cwd, folders }) {
9
- var _a;
10
- try {
11
- // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
12
- const rootPkg = require(path_1.default.resolve(cwd, 'package.json'));
13
- return rootPkg.name || null;
14
- }
15
- catch (_b) {
16
- if (folders.length < 1) {
17
- return null;
18
- }
19
- try {
20
- // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
21
- const firstPkg = require(path_1.default.resolve(folders[0], 'package.json'));
22
- // Extract monorepo scope from package name (e.g., "@cloud-ru" from "@cloud-ru/ft-deps-validator")
23
- const match = (_a = firstPkg.name) === null || _a === void 0 ? void 0 : _a.match(/^(@[^/]+)/);
24
- if (match) {
25
- return match[1];
26
- }
27
- return null;
28
- }
29
- catch (_c) {
30
- return null;
31
- }
32
- }
33
- }
@@ -1,8 +0,0 @@
1
- import { State } from '../types/state';
2
- type Options = {
3
- cwd: string;
4
- folders: string[];
5
- prefix?: string;
6
- };
7
- export declare function initializeState({ cwd, folders, prefix }: Options): State;
8
- export {};
@@ -1,40 +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.initializeState = initializeState;
7
- const path_1 = __importDefault(require("path"));
8
- const getMonorepoPrefix_1 = require("./getMonorepoPrefix");
9
- function initializeState({ cwd, folders, prefix }) {
10
- const internalPackages = {};
11
- const initialState = {
12
- wrongVersions: [],
13
- internalAsDev: [],
14
- unusedDeps: [],
15
- missing: [],
16
- };
17
- const monorepoName = prefix || (0, getMonorepoPrefix_1.getMonorepoPrefix)({ cwd, folders });
18
- if (!monorepoName) {
19
- throw new Error('[ERROR] Prefix was not specified and was not found');
20
- }
21
- const monorepoPackageRegexp = new RegExp(`${monorepoName}\\/`);
22
- for (const folder of folders) {
23
- // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
24
- const pkg = require(path_1.default.resolve(folder, 'package.json'));
25
- internalPackages[pkg.name] = pkg.version;
26
- }
27
- for (const folder of folders) {
28
- // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
29
- const pkg = require(path_1.default.resolve(folder, 'package.json'));
30
- const usedInternal = Object.keys(pkg.dependencies || {}).filter(x => monorepoPackageRegexp.test(x));
31
- usedInternal.forEach(dep => {
32
- if (pkg.dependencies[dep] !== internalPackages[dep]) {
33
- initialState.wrongVersions.push(`Error in ${pkg.name}: ${dep} has ${pkg.dependencies[dep]}, but correct version is ${internalPackages[dep]}`);
34
- }
35
- });
36
- const usedInternalDev = Object.keys(pkg.devDependencies || {}).filter(x => monorepoPackageRegexp.test(x));
37
- usedInternalDev.forEach(dep => initialState.internalAsDev.push(`Error in ${pkg.name}: ${dep}`));
38
- }
39
- return initialState;
40
- }
@@ -1,4 +0,0 @@
1
- import { Config } from './config';
2
- export type CliArguments = Config & {
3
- cwd: string;
4
- };
@@ -1,6 +0,0 @@
1
- export type State = {
2
- wrongVersions: string[];
3
- internalAsDev: string[];
4
- unusedDeps: string[];
5
- missing: Array<Record<string, string[]>>;
6
- };
@@ -1,6 +0,0 @@
1
- type Options = {
2
- cwd: string;
3
- folders: string[];
4
- };
5
- export declare function getMonorepoPrefix({ cwd, folders }: Options): string | null;
6
- export {};
@@ -1,27 +0,0 @@
1
- import path from 'path';
2
- export function getMonorepoPrefix({ cwd, folders }) {
3
- var _a;
4
- try {
5
- // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
6
- const rootPkg = require(path.resolve(cwd, 'package.json'));
7
- return rootPkg.name || null;
8
- }
9
- catch (_b) {
10
- if (folders.length < 1) {
11
- return null;
12
- }
13
- try {
14
- // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
15
- const firstPkg = require(path.resolve(folders[0], 'package.json'));
16
- // Extract monorepo scope from package name (e.g., "@cloud-ru" from "@cloud-ru/ft-deps-validator")
17
- const match = (_a = firstPkg.name) === null || _a === void 0 ? void 0 : _a.match(/^(@[^/]+)/);
18
- if (match) {
19
- return match[1];
20
- }
21
- return null;
22
- }
23
- catch (_c) {
24
- return null;
25
- }
26
- }
27
- }
@@ -1,8 +0,0 @@
1
- import { State } from '../types/state';
2
- type Options = {
3
- cwd: string;
4
- folders: string[];
5
- prefix?: string;
6
- };
7
- export declare function initializeState({ cwd, folders, prefix }: Options): State;
8
- export {};
@@ -1,34 +0,0 @@
1
- import path from 'path';
2
- import { getMonorepoPrefix } from './getMonorepoPrefix';
3
- export function initializeState({ cwd, folders, prefix }) {
4
- const internalPackages = {};
5
- const initialState = {
6
- wrongVersions: [],
7
- internalAsDev: [],
8
- unusedDeps: [],
9
- missing: [],
10
- };
11
- const monorepoName = prefix || getMonorepoPrefix({ cwd, folders });
12
- if (!monorepoName) {
13
- throw new Error('[ERROR] Prefix was not specified and was not found');
14
- }
15
- const monorepoPackageRegexp = new RegExp(`${monorepoName}\\/`);
16
- for (const folder of folders) {
17
- // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
18
- const pkg = require(path.resolve(folder, 'package.json'));
19
- internalPackages[pkg.name] = pkg.version;
20
- }
21
- for (const folder of folders) {
22
- // eslint-disable-next-line import/no-dynamic-require, @typescript-eslint/no-var-requires
23
- const pkg = require(path.resolve(folder, 'package.json'));
24
- const usedInternal = Object.keys(pkg.dependencies || {}).filter(x => monorepoPackageRegexp.test(x));
25
- usedInternal.forEach(dep => {
26
- if (pkg.dependencies[dep] !== internalPackages[dep]) {
27
- initialState.wrongVersions.push(`Error in ${pkg.name}: ${dep} has ${pkg.dependencies[dep]}, but correct version is ${internalPackages[dep]}`);
28
- }
29
- });
30
- const usedInternalDev = Object.keys(pkg.devDependencies || {}).filter(x => monorepoPackageRegexp.test(x));
31
- usedInternalDev.forEach(dep => initialState.internalAsDev.push(`Error in ${pkg.name}: ${dep}`));
32
- }
33
- return initialState;
34
- }