@revolut/web-cli
Advanced tools
Comparing version
{ | ||
"name": "@revolut/web-cli", | ||
"version": "1.4.2", | ||
"version": "1.5.0", | ||
"license": "Apache-2.0", | ||
@@ -5,0 +5,0 @@ "description": "Interactive CLI tool for web projects to provide automation for various tasks", |
export declare type TemplateName = 'app' | 'backoffice-library' | 'backoffice-microfrontend' | 'backoffice-app' | 'library'; | ||
export declare const TEMPLATES: TemplateName[]; | ||
export declare const TEMPLATE_FILES_MAPPING: Record<TemplateName, string[]>; | ||
export declare enum TemplateKind { | ||
WebApp = "WebApp", | ||
Infrastructure = "Infrastructure" | ||
} | ||
export declare const TEMPLATE_DIR: Record<TemplateKind, string>; |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
exports.TEMPLATE_FILES_MAPPING = exports.TEMPLATES = void 0; | ||
exports.TEMPLATE_DIR = exports.TemplateKind = exports.TEMPLATE_FILES_MAPPING = exports.TEMPLATES = void 0; | ||
exports.TEMPLATES = [ | ||
@@ -25,2 +25,11 @@ 'app', | ||
}; | ||
var TemplateKind; | ||
(function (TemplateKind) { | ||
TemplateKind["WebApp"] = "WebApp"; | ||
TemplateKind["Infrastructure"] = "Infrastructure"; | ||
})(TemplateKind = exports.TemplateKind || (exports.TemplateKind = {})); | ||
exports.TEMPLATE_DIR = { | ||
[TemplateKind.WebApp]: 'web-app', | ||
[TemplateKind.Infrastructure]: 'infrastructure', | ||
}; | ||
//# sourceMappingURL=constants.js.map |
export * from './constants'; | ||
export * from './RushConfigDataMiner'; | ||
export * from './utils/RushConfigDataMiner'; |
@@ -18,3 +18,3 @@ "use strict"; | ||
__exportStar(require("./constants"), exports); | ||
__exportStar(require("./RushConfigDataMiner"), exports); | ||
__exportStar(require("./utils/RushConfigDataMiner"), exports); | ||
//# sourceMappingURL=exports-for-tests.js.map |
#!/usr/bin/env node | ||
"use strict"; | ||
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
var desc = Object.getOwnPropertyDescriptor(m, k); | ||
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { | ||
desc = { enumerable: true, get: function() { return m[k]; } }; | ||
} | ||
Object.defineProperty(o, k2, desc); | ||
}) : (function(o, m, k, k2) { | ||
if (k2 === undefined) k2 = k; | ||
o[k2] = m[k]; | ||
})); | ||
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { | ||
Object.defineProperty(o, "default", { enumerable: true, value: v }); | ||
}) : function(o, v) { | ||
o["default"] = v; | ||
}); | ||
var __importStar = (this && this.__importStar) || function (mod) { | ||
if (mod && mod.__esModule) return mod; | ||
var result = {}; | ||
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); | ||
__setModuleDefault(result, mod); | ||
return result; | ||
}; | ||
var __importDefault = (this && this.__importDefault) || function (mod) { | ||
@@ -32,30 +9,10 @@ return (mod && mod.__esModule) ? mod : { "default": mod }; | ||
const update_notifier_1 = __importDefault(require("update-notifier")); | ||
const enquirer_1 = require("enquirer"); | ||
const chalk_1 = require("chalk"); | ||
const ora_1 = __importDefault(require("ora")); | ||
const fs_jetpack_1 = __importDefault(require("fs-jetpack")); | ||
const package_json_1 = __importDefault(require("../package.json")); | ||
const actions_1 = require("./actions"); | ||
const constants_1 = require("./constants"); | ||
const RushConfigDataMiner_1 = require("./RushConfigDataMiner"); | ||
const RushConfigEditor_1 = require("./RushConfigEditor"); | ||
const utils_1 = require("./utils"); | ||
(0, update_notifier_1.default)({ pkg: package_json_1.default }).notify(); | ||
const program = new commander_1.Command(); | ||
program.version(package_json_1.default.version); | ||
const callerDirCwd = fs_jetpack_1.default.cwd(); | ||
const webCliCwd = fs_jetpack_1.default.cwd(__dirname, '..'); | ||
function getUnscopedPackageName(packageName) { | ||
return packageName.includes('@') ? packageName.split('/')[1] : packageName; | ||
} | ||
function getDefaultAppFolder(template, packageName) { | ||
const unscopedPackageName = getUnscopedPackageName(packageName); | ||
switch (template) { | ||
case 'backoffice-app': | ||
return `backoffice-ui-apps/${unscopedPackageName}`; | ||
case 'backoffice-library': | ||
return `packages/${unscopedPackageName}`; | ||
default: | ||
return `${unscopedPackageName}`; | ||
} | ||
} | ||
// Scaffold web app | ||
program | ||
@@ -77,119 +34,13 @@ .command('scaffold') | ||
}) | ||
.action(async (options) => { | ||
var _a, _b; | ||
// Read inputs and ask to provide if not provided | ||
const { template } = await (0, enquirer_1.prompt)({ | ||
name: 'template', | ||
message: 'Select template.', | ||
type: 'select', | ||
choices: constants_1.TEMPLATES, | ||
initial: options.template, | ||
skip: Boolean(options.template), | ||
}); | ||
const { packageName } = await (0, enquirer_1.prompt)({ | ||
name: 'packageName', | ||
message: 'Name of the package', | ||
type: 'input', | ||
initial: options.packageName || '@revolut/', | ||
skip: Boolean(options.packageName), | ||
}); | ||
const { folderName } = await (0, enquirer_1.prompt)({ | ||
name: 'folderName', | ||
message: 'Name of the destination folder', | ||
type: 'input', | ||
initial: options.folderName || getDefaultAppFolder(template, packageName), | ||
skip: Boolean(options.folderName), | ||
}); | ||
const { publicUrl } = await (0, enquirer_1.prompt)({ | ||
name: 'publicUrl', | ||
message: 'Application PUBLIC_URL', | ||
type: 'input', | ||
initial: options.publicUrl || | ||
`${template === 'backoffice-microfrontend' ? '/microfrontends' : ''}/${getUnscopedPackageName(packageName)}`, | ||
validate: (value) => { | ||
const requiredPrefix = template === 'backoffice-microfrontend' ? '/microfrontends/' : '/'; | ||
if (!value.startsWith(requiredPrefix)) { | ||
return `Should start with ${requiredPrefix}`; | ||
} | ||
return true; | ||
}, | ||
skip: Boolean(options.publicUrl) || | ||
!(constants_1.TEMPLATE_FILES_MAPPING[template] && | ||
constants_1.TEMPLATE_FILES_MAPPING[template].includes('.env.production')), | ||
}); | ||
const copyTemplateSpinner = (0, ora_1.default)('Copy template to selected folder').start(); | ||
const templateDir = `${webCliCwd.cwd()}/templates/${template}`; | ||
try { | ||
fs_jetpack_1.default.copy(templateDir, `${callerDirCwd}/${folderName}`); | ||
copyTemplateSpinner.succeed(); | ||
} | ||
catch (e) { | ||
copyTemplateSpinner.fail(); | ||
console.error((0, chalk_1.redBright)('Folder already exists, please, try again with different folder name.')); | ||
console.error(); | ||
console.error((0, chalk_1.cyan)('Copy command below to save some typing:')); | ||
console.error((0, chalk_1.green)(`revolut-web-cli scaffold -pn ${packageName} -t ${template}`)); | ||
console.error(); | ||
console.error(); | ||
console.error((0, chalk_1.redBright)('Original error:')); | ||
console.error(e); | ||
process.exit(1); | ||
} | ||
const fillingTemplatesSpinner = (0, ora_1.default)('Replacing placeholders in template files').start(); | ||
const scaffoldedProjectRootCwd = fs_jetpack_1.default.cwd(folderName); | ||
const templateFilesDirsToReadAndOverwrite = constants_1.TEMPLATE_FILES_MAPPING[template]; | ||
templateFilesDirsToReadAndOverwrite.forEach((templateFileDir) => { | ||
const templateFile = scaffoldedProjectRootCwd.read(templateFileDir); | ||
if (!templateFile) { | ||
fillingTemplatesSpinner.fail(); | ||
console.error((0, chalk_1.redBright)('Cannot find template file!')); | ||
process.exit(1); | ||
return; | ||
} | ||
const changed = templateFile | ||
.replace('{packageName}', packageName) | ||
.replace('{publicUrl}', publicUrl); | ||
scaffoldedProjectRootCwd.write(templateFileDir, changed); | ||
}); | ||
fillingTemplatesSpinner.succeed(); | ||
const isRushRepo = !options.ignoreRush && (0, utils_1.isRushManagedRepo)(); | ||
if (isRushRepo) { | ||
const { RushConfiguration } = await Promise.resolve().then(() => __importStar(require('@microsoft/rush-lib'))); | ||
RushConfiguration.tryFindRushJsonLocation({ | ||
startingFolder: process.cwd(), | ||
}); | ||
const rushConfig = RushConfiguration.loadFromDefaultLocation({ | ||
startingFolder: process.cwd(), | ||
}); | ||
const rushDataMinerService = RushConfigDataMiner_1.RushConfigDataMiner.getInstance(rushConfig); | ||
const allNonPeerMonorepoDependencies = rushDataMinerService.getAllNonPeerDependencies(); | ||
// If it's needed we ensure we have consistent versions with Rush monorepo in this new package.json | ||
if (rushConfig.ensureConsistentVersions) { | ||
const ensureRushConsistentVersionsSpinner = (0, ora_1.default)('Ensure rush.js consistent versions are set').start(); | ||
const scaffoldedProjectPackageJson = JSON.parse(scaffoldedProjectRootCwd.read('package.json')); | ||
scaffoldedProjectPackageJson.dependencies = (0, utils_1.alignDependenciesWithMonorepoVersions)((_a = scaffoldedProjectPackageJson.dependencies) !== null && _a !== void 0 ? _a : {}, allNonPeerMonorepoDependencies); | ||
scaffoldedProjectPackageJson.devDependencies = | ||
(0, utils_1.alignDependenciesWithMonorepoVersions)((_b = scaffoldedProjectPackageJson.devDependencies) !== null && _b !== void 0 ? _b : {}, allNonPeerMonorepoDependencies); | ||
scaffoldedProjectRootCwd.write('package.json', JSON.stringify(scaffoldedProjectPackageJson, null, 2)); | ||
ensureRushConsistentVersionsSpinner.succeed(); | ||
} | ||
const addingPackageToRushJson = (0, ora_1.default)('Adding package to rush.json').start(); | ||
const rushConfigEditor = RushConfigEditor_1.RushConfigEditor.getInstance(rushConfig); | ||
const scaffoldedProjectFolderAbsoluteToRoot = scaffoldedProjectRootCwd | ||
.cwd() | ||
.split(`${rushConfig.rushJsonFolder}/`)[1]; | ||
const project = { | ||
packageName, | ||
projectFolder: scaffoldedProjectFolderAbsoluteToRoot, | ||
shouldPublish: false, | ||
cyclicDependencyProjects: [], | ||
}; | ||
template === 'backoffice-library' && (project.versionPolicyName = 'library'); | ||
rushConfigEditor.addProject(project); | ||
rushConfigEditor.saveIfModified(); | ||
addingPackageToRushJson.succeed(); | ||
} | ||
console.log((0, chalk_1.green)('🛠 Scaffold successful!')); | ||
}); | ||
.action(actions_1.scaffoldWebAppAction); | ||
// Scaffold infra | ||
program | ||
.command('scaffold-infra') | ||
.description('Scaffold infrastructure configs for web app') | ||
.usage('--app-name my-app --app-domain my-app.revolut.com') | ||
.option('-an, --app-name <name>', 'Application name') | ||
.option('-ad, --app-domain <domain>', 'Application side domain name') | ||
.option('-sr, --sentry-report-uri [url]', 'Sentry CSP report-uri url (see https://docs.sentry.io/product/security-policy-reporting/#content-security-policy for more details)') | ||
.action(actions_1.scaffoldInfrastructureAction); | ||
program.parse(process.argv); | ||
//# sourceMappingURL=index.js.map |
"use strict"; | ||
Object.defineProperty(exports, "__esModule", { value: true }); | ||
const rush_lib_1 = require("@microsoft/rush-lib"); | ||
const RushConfigDataMiner_1 = require("../RushConfigDataMiner"); | ||
const RushConfigEditor_1 = require("../RushConfigEditor"); | ||
const utils_1 = require("../utils"); | ||
const rushConfig = rush_lib_1.RushConfiguration.loadFromConfigurationFile('./resources/rush.json'); | ||
describe('RushConfigDataMiner', () => { | ||
it('Returns same instance for the same config', () => { | ||
const dataMiner1 = RushConfigDataMiner_1.RushConfigDataMiner.getInstance(rushConfig); | ||
const dataMiner2 = RushConfigDataMiner_1.RushConfigDataMiner.getInstance(rushConfig); | ||
const dataMiner1 = utils_1.RushConfigDataMiner.getInstance(rushConfig); | ||
const dataMiner2 = utils_1.RushConfigDataMiner.getInstance(rushConfig); | ||
expect(dataMiner1).toBe(dataMiner2); | ||
@@ -16,4 +15,4 @@ }); | ||
it('Returns same instance for the same config', () => { | ||
const dataEditor1 = RushConfigEditor_1.RushConfigEditor.getInstance(rushConfig); | ||
const dataEditor2 = RushConfigEditor_1.RushConfigEditor.getInstance(rushConfig); | ||
const dataEditor1 = utils_1.RushConfigEditor.getInstance(rushConfig); | ||
const dataEditor2 = utils_1.RushConfigEditor.getInstance(rushConfig); | ||
expect(dataEditor1).toBe(dataEditor2); | ||
@@ -20,0 +19,0 @@ }); |
{ | ||
"name": "@revolut/web-cli", | ||
"version": "1.4.2", | ||
"version": "1.5.0", | ||
"license": "Apache-2.0", | ||
@@ -5,0 +5,0 @@ "description": "Interactive CLI tool for web projects to provide automation for various tasks", |
@@ -9,3 +9,3 @@ export type TemplateName = | ||
export const TEMPLATES: TemplateName[] = [ | ||
'app', // TBD | ||
'app', | ||
'backoffice-library', | ||
@@ -32,1 +32,11 @@ 'backoffice-microfrontend', | ||
} | ||
export enum TemplateKind { | ||
WebApp = 'WebApp', | ||
Infrastructure = 'Infrastructure', | ||
} | ||
export const TEMPLATE_DIR: Record<TemplateKind, string> = { | ||
[TemplateKind.WebApp]: 'web-app', | ||
[TemplateKind.Infrastructure]: 'infrastructure', | ||
} |
export * from './constants' | ||
export * from './RushConfigDataMiner' | ||
export * from './utils/RushConfigDataMiner' |
197
src/index.ts
#!/usr/bin/env node | ||
import { Command } from 'commander' | ||
import updateNotifier from 'update-notifier' | ||
import { prompt } from 'enquirer' | ||
import { cyan, green, redBright, yellow } from 'chalk' | ||
import ora from 'ora' | ||
import jetpack from 'fs-jetpack' | ||
import type { IRushConfigurationProjectJson } from '@microsoft/rush-lib/lib/api/RushConfigurationProject' | ||
import { green, redBright, yellow } from 'chalk' | ||
import pkg from '../package.json' | ||
import { TEMPLATE_FILES_MAPPING, TEMPLATES, TemplateName } from './constants' | ||
import { RushConfigDataMiner } from './RushConfigDataMiner' | ||
import { RushConfigEditor } from './RushConfigEditor' | ||
import { alignDependenciesWithMonorepoVersions, isRushManagedRepo } from './utils' | ||
import { scaffoldInfrastructureAction, scaffoldWebAppAction } from './actions' | ||
import { TEMPLATES, TemplateName } from './constants' | ||
type ScaffoldOptions = { | ||
folderName: string | ||
packageName: string | ||
publicUrl?: string | ||
template: TemplateName | ||
ignoreRush: boolean | ||
} | ||
updateNotifier({ pkg }).notify() | ||
interface ScaffoldProgram extends Command, Partial<ScaffoldOptions> {} | ||
const program = new Command() | ||
program.version(pkg.version) | ||
const callerDirCwd = jetpack.cwd() | ||
const webCliCwd = jetpack.cwd(__dirname, '..') | ||
function getUnscopedPackageName(packageName: string): string { | ||
return packageName.includes('@') ? packageName.split('/')[1] : packageName | ||
} | ||
function getDefaultAppFolder(template: TemplateName, packageName: string) { | ||
const unscopedPackageName = getUnscopedPackageName(packageName) | ||
switch (template) { | ||
case 'backoffice-app': | ||
return `backoffice-ui-apps/${unscopedPackageName}` | ||
case 'backoffice-library': | ||
return `packages/${unscopedPackageName}` | ||
default: | ||
return `${unscopedPackageName}` | ||
} | ||
} | ||
// Scaffold web app | ||
program | ||
@@ -75,147 +42,17 @@ .command('scaffold') | ||
) | ||
.action(async (options: ScaffoldProgram) => { | ||
// Read inputs and ask to provide if not provided | ||
const { template } = await prompt<{ | ||
template: TemplateName | ||
}>({ | ||
name: 'template', | ||
message: 'Select template.', | ||
type: 'select', | ||
choices: TEMPLATES, | ||
initial: options.template as unknown as number, | ||
skip: Boolean(options.template), | ||
}) | ||
const { packageName } = await prompt<{ packageName: string }>({ | ||
name: 'packageName', | ||
message: 'Name of the package', | ||
type: 'input', | ||
initial: options.packageName || '@revolut/', | ||
skip: Boolean(options.packageName), | ||
}) | ||
const { folderName } = await prompt<{ folderName: string }>({ | ||
name: 'folderName', | ||
message: 'Name of the destination folder', | ||
type: 'input', | ||
initial: options.folderName || getDefaultAppFolder(template, packageName), | ||
skip: Boolean(options.folderName), | ||
}) | ||
const { publicUrl } = await prompt<{ publicUrl: string }>({ | ||
name: 'publicUrl', | ||
message: 'Application PUBLIC_URL', | ||
type: 'input', | ||
initial: | ||
options.publicUrl || | ||
`${ | ||
template === 'backoffice-microfrontend' ? '/microfrontends' : '' | ||
}/${getUnscopedPackageName(packageName)}`, | ||
validate: (value) => { | ||
const requiredPrefix = | ||
template === 'backoffice-microfrontend' ? '/microfrontends/' : '/' | ||
if (!value.startsWith(requiredPrefix)) { | ||
return `Should start with ${requiredPrefix}` | ||
} | ||
.action(scaffoldWebAppAction) | ||
return true | ||
}, | ||
skip: | ||
Boolean(options.publicUrl) || | ||
!( | ||
TEMPLATE_FILES_MAPPING[template] && | ||
TEMPLATE_FILES_MAPPING[template].includes('.env.production') | ||
), | ||
}) | ||
// Scaffold infra | ||
program | ||
.command('scaffold-infra') | ||
.description('Scaffold infrastructure configs for web app') | ||
.usage('--app-name my-app --app-domain my-app.revolut.com') | ||
.option('-an, --app-name <name>', 'Application name') | ||
.option('-ad, --app-domain <domain>', 'Application side domain name') | ||
.option( | ||
'-sr, --sentry-report-uri [url]', | ||
'Sentry CSP report-uri url (see https://docs.sentry.io/product/security-policy-reporting/#content-security-policy for more details)', | ||
) | ||
.action(scaffoldInfrastructureAction) | ||
const copyTemplateSpinner = ora('Copy template to selected folder').start() | ||
const templateDir = `${webCliCwd.cwd()}/templates/${template}` | ||
try { | ||
jetpack.copy(templateDir, `${callerDirCwd}/${folderName}`) | ||
copyTemplateSpinner.succeed() | ||
} catch (e) { | ||
copyTemplateSpinner.fail() | ||
console.error( | ||
redBright('Folder already exists, please, try again with different folder name.'), | ||
) | ||
console.error() | ||
console.error(cyan('Copy command below to save some typing:')) | ||
console.error(green(`revolut-web-cli scaffold -pn ${packageName} -t ${template}`)) | ||
console.error() | ||
console.error() | ||
console.error(redBright('Original error:')) | ||
console.error(e) | ||
process.exit(1) | ||
} | ||
const fillingTemplatesSpinner = ora( | ||
'Replacing placeholders in template files', | ||
).start() | ||
const scaffoldedProjectRootCwd = jetpack.cwd(folderName) | ||
const templateFilesDirsToReadAndOverwrite = TEMPLATE_FILES_MAPPING[template] | ||
templateFilesDirsToReadAndOverwrite.forEach((templateFileDir) => { | ||
const templateFile = scaffoldedProjectRootCwd.read(templateFileDir) | ||
if (!templateFile) { | ||
fillingTemplatesSpinner.fail() | ||
console.error(redBright('Cannot find template file!')) | ||
process.exit(1) | ||
return | ||
} | ||
const changed = templateFile | ||
.replace('{packageName}', packageName) | ||
.replace('{publicUrl}', publicUrl) | ||
scaffoldedProjectRootCwd.write(templateFileDir, changed) | ||
}) | ||
fillingTemplatesSpinner.succeed() | ||
const isRushRepo = !options.ignoreRush && isRushManagedRepo() | ||
if (isRushRepo) { | ||
const { RushConfiguration } = await import('@microsoft/rush-lib') | ||
RushConfiguration.tryFindRushJsonLocation({ | ||
startingFolder: process.cwd(), | ||
}) | ||
const rushConfig = RushConfiguration.loadFromDefaultLocation({ | ||
startingFolder: process.cwd(), | ||
}) | ||
const rushDataMinerService = RushConfigDataMiner.getInstance(rushConfig) | ||
const allNonPeerMonorepoDependencies = | ||
rushDataMinerService.getAllNonPeerDependencies() | ||
// If it's needed we ensure we have consistent versions with Rush monorepo in this new package.json | ||
if (rushConfig.ensureConsistentVersions) { | ||
const ensureRushConsistentVersionsSpinner = ora( | ||
'Ensure rush.js consistent versions are set', | ||
).start() | ||
const scaffoldedProjectPackageJson = JSON.parse( | ||
scaffoldedProjectRootCwd.read('package.json') as string, | ||
) | ||
scaffoldedProjectPackageJson.dependencies = alignDependenciesWithMonorepoVersions( | ||
scaffoldedProjectPackageJson.dependencies ?? {}, | ||
allNonPeerMonorepoDependencies, | ||
) | ||
scaffoldedProjectPackageJson.devDependencies = | ||
alignDependenciesWithMonorepoVersions( | ||
scaffoldedProjectPackageJson.devDependencies ?? {}, | ||
allNonPeerMonorepoDependencies, | ||
) | ||
scaffoldedProjectRootCwd.write( | ||
'package.json', | ||
JSON.stringify(scaffoldedProjectPackageJson, null, 2), | ||
) | ||
ensureRushConsistentVersionsSpinner.succeed() | ||
} | ||
const addingPackageToRushJson = ora('Adding package to rush.json').start() | ||
const rushConfigEditor = RushConfigEditor.getInstance(rushConfig) | ||
const scaffoldedProjectFolderAbsoluteToRoot = scaffoldedProjectRootCwd | ||
.cwd() | ||
.split(`${rushConfig.rushJsonFolder}/`)[1] | ||
const project: IRushConfigurationProjectJson = { | ||
packageName, | ||
projectFolder: scaffoldedProjectFolderAbsoluteToRoot, | ||
shouldPublish: false, | ||
cyclicDependencyProjects: [], | ||
} | ||
template === 'backoffice-library' && (project.versionPolicyName = 'library') | ||
rushConfigEditor.addProject(project) | ||
rushConfigEditor.saveIfModified() | ||
addingPackageToRushJson.succeed() | ||
} | ||
console.log(green('🛠 Scaffold successful!')) | ||
}) | ||
program.parse(process.argv) |
import { RushConfiguration } from '@microsoft/rush-lib' | ||
import { RushConfigDataMiner } from '../RushConfigDataMiner' | ||
import { RushConfigEditor } from '../RushConfigEditor' | ||
import { RushConfigEditor, RushConfigDataMiner } from '../utils' | ||
@@ -5,0 +4,0 @@ const rushConfig = RushConfiguration.loadFromConfigurationFile('./resources/rush.json') |
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Sorry, the diff of this file is not supported yet
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
852753
7.33%379
15.2%3492
17.62%19
18.75%5
25%