Files
cloudbeaver/webapp/packages/core-cli/bin/validate-dependencies.js
T
eaa26dfe52 CB-4619 user scope settings (#2471)
* CB-4619 feat: update gql schema

* CB-4808 bulk update user parameters

* CB-4808 param type fix

* CB-4619 feat: updateUserPreferences API


* CB-4619 refactor: settings api

* CB-4619 refactor: move file

* CB-4619 refactor: settings api

* CB-4619 fix: pr review

* CB-4619 refactor: remove web-based product settings

* CB-4619 fix: after pr review

* CB-4619 refactor: move product conf to cloudbeaver conf

* CB-4619 fix: hide settings bar and log exception with changing session language

* CB-4619 fix: revert after merge

* CB-4808 new settings api

* CB-4808 update product.conf format

* CB-4808 update product.conf format

* CB-4619 feat: support server provided settings

* CB-4619 feat: prettify settings

* CB-4619 chore: map sql editor settings group

* CB-4808 add use short/long object name settings to CloudBeaver

* CB-4808 update default product.conf

* CB-4808 mode short/long settings to SQLModelPreferences

* CB-4808 review fix

* CB-4619 refactor: unit tests

* CB-4619 fix: prevent websocket opening spam

* CB-4619 fix: dependencies

* CB-4619 fix: remove extra theme loading

* CB-4619 fix: rename settings alias resolver file

* CB-4619 fix: after review

* CB-4619 fix conflicts

* CB-4619 rename server property

* CB-4619 remove shortname property

* CB-4619 fix legacy product conf reading

* CB-4619 merge root and runtime configurations

* CB-4619 chore: remove log viewer setting

* CB-4619 integer fields with env variables fix

* CB-4619 fix: property naming

* CB-4619 fix: parseJSONFlat null values

* CB-4619 fix: settings loading

* CB-4619 fix: save only actual settings

---------

Co-authored-by: Aleksandr Skoblikov <aleksandr.skoblikov@dbeaver.com>
Co-authored-by: kseniaguzeeva <112612526+kseniaguzeeva@users.noreply.github.com>
Co-authored-by: Evgenia Bezborodova <139753579+EvgeniaBzzz@users.noreply.github.com>
2024-03-28 10:30:52 +00:00

194 lines
5.5 KiB
JavaScript
Executable File

#!/usr/bin/env node
/* eslint-disable @typescript-eslint/no-var-requires */
'use strict';
process.title = 'core-filter-deps';
const glob = require('glob');
const fs = require('fs');
const path = require('path');
// Resolve current root
const currentPackageRoot = path.resolve('.');
// Replace with the correct path to the `package.json` file
const currentPackagePath = path.join(currentPackageRoot, 'package.json');
// Replace with the correct path to the `src` directory
const currentPackageSrcPath = path.join(currentPackageRoot, 'src');
// Read the contents of the `package.json` file
const currentPackage = JSON.parse(fs.readFileSync(currentPackagePath, 'utf8'));
// Keep track of the dependencies that were found in the source files
const dependencies = new Set();
const devDependencies = new Set();
let isSuccess = true;
const sourceFilesIterator = glob.globIterateSync('**/*.{ts,tsx,scss,css}', { cwd: currentPackageSrcPath });
const importRegex = /(import|export) ((type |)([\w,\s*]*?)(\{[\w\s\n,]*?\}|) from |)['"]((@[\w-]*\/[\w-]*)|([^\\.].*?))(\/.*)*['"]/g;
const testFileRegex = /((__custom_mocks__|__tests__).*|\.test)\.tsx?$/i;
const tsFileRegex = /\.ts$/i;
const tsxFileRegex = /\.tsx$/i;
const styleFileRegex = /\.s?css$/i;
const cssModuleFileRegex = /\.(m|module)\.s?css$/i;
for (const file of sourceFilesIterator) {
const isCSSModuleFileRegex = cssModuleFileRegex.test(file);
const isTSFileRegex = tsFileRegex.test(file);
const isStyleFileRegex = styleFileRegex.test(file);
const isTSXFileRegex = tsxFileRegex.test(file);
const isTestFile = testFileRegex.test(file);
if (isTSFileRegex) {
devDependencies.add('typescript');
}
if (isCSSModuleFileRegex) {
devDependencies.add('typescript-plugin-css-modules');
}
if (isTestFile) {
devDependencies.add('@types/jest');
}
if (isTSXFileRegex) {
if (isTestFile) {
devDependencies.add('react');
} else {
dependencies.add('react');
}
devDependencies.add('@types/react');
}
const fileContent = fs.readFileSync(path.join(currentPackageSrcPath, file), 'utf8');
const matches = fileContent.matchAll(importRegex);
for (const match of matches) {
const dep = match[6];
if (isStyleFileRegex || isTestFile) {
devDependencies.add(dep);
continue;
}
dependencies.add(dep);
}
}
currentPackage.sideEffects = currentPackage.sideEffects || [];
const sideEffects = ['src/**/*.css', 'src/**/*.scss', 'public/**/*'];
for (const sideEffect of sideEffects) {
if (!currentPackage.sideEffects.includes(sideEffect)) {
currentPackage.sideEffects.push(sideEffect);
}
}
console.log('Analyzing dependencies...');
const newDependencies = [...dependencies].sort(sortDependencies);
const newAllDependencies = [...newDependencies, ...devDependencies].sort(sortDependencies);
logUnmetAndExtraDependencies('dependencies', newDependencies, currentPackage.dependencies, newAllDependencies);
currentPackage.dependencies = sortObjectKeys(
newDependencies.reduce(
(acc, dep) => ({
...acc,
[dep]: getVersion(dep, acc?.[dep]),
}),
currentPackage.dependencies,
),
);
const newDevDependencies = [...devDependencies].sort(sortDependencies);
logUnmetAndExtraDependencies('dev dependencies', newDevDependencies, currentPackage.devDependencies, newAllDependencies);
currentPackage.devDependencies = sortObjectKeys(
[...devDependencies].sort(sortDependencies).reduce(
(acc, dep) => ({
...acc,
[dep]: getVersion(dep, acc?.[dep]),
}),
currentPackage.devDependencies,
),
);
if (isSuccess) {
console.log('All dependencies are valid');
}
// Write the updated `package.json`
fs.writeFileSync(currentPackagePath, JSON.stringify(currentPackage, null, 2) + '\n', 'utf8');
function getVersion(dependency, current) {
if (dependency.startsWith('@cloudbeaver')) {
return '~0.1.0';
}
if (current) {
return current;
}
try {
if (fs.existsSync(path.join(require.resolve(dependency), 'package.json')) === false) {
console.error(`Dependency ${dependency} not found`);
return '*';
}
} catch {
try {
if (fs.existsSync(path.join('@types', require.resolve(dependency), 'package.json')) === false) {
console.error(`Dependency ${dependency} not found`);
return '*';
} else {
return '^' + require(path.join('@types', require.resolve(dependency), 'package.json')).version;
}
} catch {
console.error(`Dependency ${dependency} not found`);
return '*';
}
}
return '^' + require(path.join(dependency, 'package.json')).version;
}
function sortDependencies(a, b) {
return a.localeCompare(b);
}
function logUnmetAndExtraDependencies(key, newDependencies, current, allDependencies = []) {
const unmetDependencies = newDependencies.filter(dep => !current?.[dep]);
const extraDependencies = Object.keys(current || {}).filter(dep => {
if (newDependencies.includes(dep)) {
return false;
}
if (dep.startsWith('@types/') && allDependencies.includes(dep.replace('@types/', ''))) {
return false;
}
return true;
});
if (unmetDependencies.length > 0) {
console.warn('\x1b[90m%s\x1b[0m', `Unmet ${key} found:`, unmetDependencies);
isSuccess = false;
}
if (extraDependencies.length > 0) {
console.warn('\x1b[31m%s\x1b[0m', `Extra ${key} found:`, extraDependencies);
isSuccess = false;
}
}
function sortObjectKeys(object) {
return Object.keys(object)
.sort()
.reduce((obj, key) => {
obj[key] = object[key];
return obj;
}, {});
}