Toolkit: Remove plugin:create and component:create commands (#66729)

This commit is contained in:
Esteban Beltran 2023-04-19 15:15:37 +02:00 committed by GitHub
parent 46b73548b3
commit 5dac0c9871
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 4 additions and 662 deletions

View File

@ -878,10 +878,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Do not use any type assertions.", "5"],
[0, 0, 0, "Do not use any type assertions.", "6"]
],
"packages/grafana-toolkit/src/cli/tasks/component.create.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]
],
"packages/grafana-toolkit/src/cli/tasks/package.build.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@ -898,11 +894,6 @@ exports[`better eslint`] = {
"packages/grafana-toolkit/src/cli/tasks/plugin/bundle.managed.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"]
],
"packages/grafana-toolkit/src/cli/tasks/plugin/create.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"packages/grafana-toolkit/src/cli/tasks/searchTestDataSetup.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
@ -927,11 +918,6 @@ exports[`better eslint`] = {
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"packages/grafana-toolkit/src/cli/utils/prompt.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"],
[0, 0, 0, "Unexpected any. Specify a different type.", "2"]
],
"packages/grafana-toolkit/src/cli/utils/useSpinner.ts:5381": [
[0, 0, 0, "Unexpected any. Specify a different type.", "0"],
[0, 0, 0, "Unexpected any. Specify a different type.", "1"]

View File

@ -56,10 +56,8 @@
"@grafana/tsconfig": "^1.2.0-rc1",
"@grafana/ui": "10.0.0-pre",
"@jest/core": "27.5.1",
"@types/command-exists": "^1.2.0",
"@types/eslint": "8.4.1",
"@types/fs-extra": "^9.0.13",
"@types/inquirer": "^8.2.1",
"@types/jest": "27.4.1",
"@types/lodash": "4.14.181",
"@types/node": "16.11.26",
@ -75,7 +73,6 @@
"babel-loader": "^8.2.5",
"babel-plugin-angularjs-annotate": "0.10.0",
"chalk": "^4.1.2",
"command-exists": "^1.2.9",
"commander": "^9.2.0",
"copy-webpack-plugin": "^9.0.1",
"css-loader": "^6.7.1",
@ -91,7 +88,6 @@
"globby": "^11.0.4",
"html-loader": "^3.1.0",
"html-webpack-plugin": "^5.5.0",
"inquirer": "^8.2.2",
"jest": "27.5.1",
"jest-canvas-mock": "2.3.1",
"jest-junit": "13.1.0",
@ -101,8 +97,6 @@
"md5-file": "^5.0.0",
"mini-css-extract-plugin": "^2.6.0",
"ora": "^5.4.1",
"pixelmatch": "^5.2.1",
"pngjs": "^6.0.0",
"postcss": "^8.4.12",
"postcss-flexbugs-fixes": "^5.0.2",
"postcss-loader": "^6.2.1",
@ -114,7 +108,6 @@
"sass": "^1.49.9",
"sass-loader": "^12.6.0",
"semver": "^7.3.7",
"simple-git": "^3.6.0",
"style-loader": "^3.3.1",
"terser-webpack-plugin": "^5.3.1",
"ts-jest": "27.1.3",

View File

@ -1,12 +1,10 @@
import chalk from 'chalk';
import { program } from 'commander';
import { componentCreateTask } from './tasks/component.create';
import { nodeVersionCheckerTask } from './tasks/nodeVersionChecker';
import { buildPackageTask } from './tasks/package.build';
import { pluginBuildTask } from './tasks/plugin.build';
import { ciBuildPluginTask, ciPackagePluginTask, ciPluginReportTask } from './tasks/plugin.ci';
import { pluginCreateTask } from './tasks/plugin.create';
import { pluginDevTask } from './tasks/plugin.dev';
import { pluginSignTask } from './tasks/plugin.sign';
import { pluginTestTask } from './tasks/plugin.tests';
@ -82,24 +80,6 @@ export const run = (includeInternalScripts = false) => {
);
await execTask(searchTestDataSetupTask)({ count: cmd.count });
});
// React generator
program
.command('component:create')
.description(
'[deprecated] Scaffold React components. Optionally add test, story and .mdx files. The components are created in the same dir the script is run from.'
)
.action(async () => {
console.log(
chalk.yellow.bold(
`⚠️ This command is deprecated and will be removed in v10. No further support will be provided. ⚠️`
)
);
console.log(
'if you were reliant on this command we recommend https://www.npmjs.com/package/react-gen-component'
);
await execTask(componentCreateTask)({});
});
}
program.option('-v, --version', 'Toolkit version').action(async () => {
@ -109,13 +89,12 @@ export const run = (includeInternalScripts = false) => {
program
.command('plugin:create [name]')
.description('[Deprecated] Creates plugin from template')
.action(async (cmd) => {
console.log(chalk.yellow('\n⚠ DEPRECATED. This command is deprecated and will be removed in v10. ⚠️'));
.description('[removed] Use grafana create-plugin instead')
.action(async () => {
console.log(
'Please migrate to grafana create-plugin https://github.com/grafana/plugin-tools/tree/main/packages/create-plugin\n'
'No longer supported. Use grafana create-plugin https://github.com/grafana/plugin-tools/tree/main/packages/create-plugin\n'
);
await execTask(pluginCreateTask)({ name: cmd, silent: true });
process.exit(1);
});
program

View File

@ -1,88 +0,0 @@
import fs from 'fs';
import { prompt } from 'inquirer';
import { template as _template } from 'lodash';
import { componentTpl, docsTpl, storyTpl, testTpl } from '../templates';
import { pascalCase } from '../utils/pascalCase';
import { promptConfirm, promptInput, promptList } from '../utils/prompt';
import { Task, TaskRunner } from './task';
interface Details {
name?: string;
hasStory: boolean;
group?: string;
isStoryPublic: boolean;
hasTests: boolean;
}
interface GeneratorOptions {
details: Details;
path: string;
}
type ComponentGenerator = (options: GeneratorOptions) => Promise<any>;
const componentGroups = [
{ name: 'General', value: 'General' },
{ name: 'Forms', value: 'Forms' },
{ name: 'Panel', value: 'Panel' },
{ name: 'Visualizations', value: 'Visualizations' },
{ name: 'Others', value: 'Others' },
];
export const promptDetails = () => {
return prompt<Details>([
promptInput('name', 'Component name', true),
promptConfirm('hasTests', "Generate component's test file?"),
promptConfirm('hasStory', "Generate component's story file?"),
promptConfirm(
'isStoryPublic',
'Generate public story? (Selecting "No" will create an internal story)',
true,
({ hasStory }) => hasStory
),
promptList(
'group',
'Select component group for the story (e.g. Forms, Layout)',
() => componentGroups,
0,
({ hasStory }) => hasStory
),
]);
};
export const generateComponents: ComponentGenerator = async ({ details, path }) => {
const name = pascalCase(details.name);
const getCompiled = (template: string) => {
return _template(template)({ ...details, name });
};
const filePath = `${path}/${name}`;
let paths = [];
fs.writeFileSync(`${filePath}.tsx`, getCompiled(componentTpl));
paths.push(`${filePath}.tsx`);
if (details.hasTests) {
fs.writeFileSync(`${filePath}.test.tsx`, getCompiled(testTpl));
paths.push(`${filePath}.test.tsx`);
}
if (details.hasStory) {
const storyExt = details.isStoryPublic ? '.story.tsx' : '.story.internal.tsx';
fs.writeFileSync(`${filePath}${storyExt}`, getCompiled(storyTpl));
fs.writeFileSync(`${filePath}.mdx`, getCompiled(docsTpl));
paths.push(`${filePath}${storyExt}`, `${filePath}.mdx`);
}
console.log('Generated files:');
console.log(paths.join('\n'));
};
const componentCreateRunner: TaskRunner<any> = async () => {
const destPath = process.cwd();
const details = await promptDetails();
await generateComponents({ details, path: destPath });
};
export const componentCreateTask = new Task('component:create', componentCreateRunner);

View File

@ -1,57 +0,0 @@
import { prompt } from 'inquirer';
import path from 'path';
import { promptConfirm } from '../utils/prompt';
import {
fetchTemplate,
formatPluginDetails,
getPluginIdFromName,
prepareJsonFiles,
printGrafanaTutorialsDetails,
promptPluginDetails,
promptPluginType,
removeGitFiles,
verifyGitExists,
removeLockFile,
} from './plugin/create';
import { Task, TaskRunner } from './task';
interface PluginCreateOptions {
name?: string;
}
const pluginCreateRunner: TaskRunner<PluginCreateOptions> = async ({ name }) => {
const destPath = path.resolve(process.cwd(), getPluginIdFromName(name || ''));
let pluginDetails;
// 1. Verifying if git exists in user's env as templates are cloned from git templates
await verifyGitExists();
// 2. Prompt plugin template
const { type } = await promptPluginType();
// 3. Fetch plugin template from GitHub
await fetchTemplate({ type, dest: destPath });
// 4. Prompt plugin details
do {
pluginDetails = await promptPluginDetails(name);
formatPluginDetails(pluginDetails);
} while ((await prompt<{ confirm: boolean }>(promptConfirm('confirm', 'Is that ok?'))).confirm === false);
// 5. Update json files (package.json, src/plugin.json)
await prepareJsonFiles({ type: type, pluginDetails, pluginPath: destPath });
// 6. Starter templates include `yarn.lock` files which will rarely (if ever) be in sync with `latest` dist-tag
// so best to remove it after cloning.
removeLockFile({ pluginPath: destPath });
// 7. Remove cloned repository .git dir
await removeGitFiles(destPath);
// 8. Promote Grafana Tutorials :)
printGrafanaTutorialsDetails(type);
};
export const pluginCreateTask = new Task<PluginCreateOptions>('plugin:create task', pluginCreateRunner);

View File

@ -1,199 +0,0 @@
import chalk from 'chalk';
import commandExists from 'command-exists';
import { promises as fs, readFileSync, existsSync, unlinkSync } from 'fs';
import { prompt } from 'inquirer';
import { kebabCase } from 'lodash';
import path from 'path';
import gitPromise from 'simple-git';
import { promptConfirm, promptInput } from '../../utils/prompt';
import { rmdir } from '../../utils/rmdir';
import { useSpinner } from '../../utils/useSpinner';
const simpleGit = gitPromise(process.cwd());
interface PluginDetails {
name: string;
org: string;
description: string;
author: boolean | string;
url: string;
keywords: string;
}
type PluginType = 'panel-plugin' | 'datasource-plugin' | 'backend-datasource-plugin';
const PluginNames: Record<PluginType, string> = {
'panel-plugin': 'Grafana Panel Plugin',
'datasource-plugin': 'Grafana Data Source Plugin',
'backend-datasource-plugin': 'Grafana Backend Datasource Plugin',
};
const RepositoriesPaths: Record<PluginType, string> = {
'panel-plugin': 'https://github.com/grafana/simple-react-panel.git',
'datasource-plugin': 'https://github.com/grafana/simple-datasource.git',
'backend-datasource-plugin': 'https://github.com/grafana/simple-datasource-backend.git',
};
const TutorialPaths: Record<PluginType, string> = {
'panel-plugin': 'https://grafana.com/tutorials/build-a-panel-plugin',
'datasource-plugin': 'https://grafana.com/tutorials/build-a-data-source-plugin',
'backend-datasource-plugin': 'TODO',
};
export const getGitUsername = async () => {
const name = await simpleGit.raw(['config', '--global', 'user.name']);
return name || '';
};
export const getPluginIdFromName = (name: string) => kebabCase(name);
export const getPluginId = (pluginDetails: PluginDetails) =>
`${kebabCase(pluginDetails.org)}-${getPluginIdFromName(pluginDetails.name)}`;
export const getPluginKeywords = (pluginDetails: PluginDetails) =>
pluginDetails.keywords
.split(',')
.map((k) => k.trim())
.filter((k) => k !== '');
export const verifyGitExists = async () => {
return new Promise((resolve, reject) => {
commandExists('git', (err, exists) => {
if (exists) {
resolve(true);
}
reject(new Error('git is not installed'));
});
});
};
export const promptPluginType = async () =>
prompt<{ type: PluginType }>([
{
type: 'list',
message: 'Select plugin type',
name: 'type',
choices: [
{ name: 'Panel Plugin', value: 'panel-plugin' },
{ name: 'Datasource Plugin', value: 'datasource-plugin' },
{ name: 'Backend Datasource Plugin', value: 'backend-datasource-plugin' },
],
},
]);
export const promptPluginDetails = async (name?: string) => {
const username = (await getGitUsername()).trim();
const responses = await prompt<PluginDetails>([
promptInput('name', 'Plugin name', true, name),
promptInput('org', 'Organization (used as part of plugin ID)', true),
promptInput('description', 'Description'),
promptInput('keywords', 'Keywords (separated by comma)'),
// Try using git specified username
promptConfirm('author', `Author (${username})`, username, username !== ''),
// Prompt for manual author entry if no git user.name specified
promptInput('author', `Author`, true, undefined, (answers: any) => !answers.author || username === ''),
promptInput('url', 'Your URL (i.e. organisation url)'),
]);
return {
...responses,
author: responses.author === true ? username : responses.author,
};
};
export const fetchTemplate = ({ type, dest }: { type: PluginType; dest: string }) =>
useSpinner('Fetching plugin template...', async () => {
const url = RepositoriesPaths[type];
if (!url) {
throw new Error('Unknown plugin type');
}
await simpleGit.clone(url, dest);
});
export const prepareJsonFiles = ({
type,
pluginDetails,
pluginPath,
}: {
type: PluginType;
pluginDetails: PluginDetails;
pluginPath: string;
}) =>
useSpinner('Saving package.json and plugin.json files', async () => {
const packageJsonPath = path.resolve(pluginPath, 'package.json');
const pluginJsonPath = path.resolve(pluginPath, 'src/plugin.json');
const packageJson: any = JSON.parse(readFileSync(packageJsonPath, 'utf8'));
const pluginJson: any = JSON.parse(readFileSync(pluginJsonPath, 'utf8'));
const pluginId = `${kebabCase(pluginDetails.org)}-${getPluginIdFromName(pluginDetails.name)}`;
packageJson.name = pluginId;
packageJson.author = pluginDetails.author;
packageJson.description = pluginDetails.description;
pluginJson.name = pluginDetails.name;
pluginJson.id = pluginId;
if (type === 'backend-datasource-plugin') {
pluginJson.backend = true;
pluginJson.executable = 'gpx_' + pluginDetails.name;
}
pluginJson.info = {
...pluginJson.info,
description: pluginDetails.description,
author: {
name: pluginDetails.author,
url: pluginDetails.url,
},
keywords: getPluginKeywords(pluginDetails),
};
await Promise.all(
[packageJson, pluginJson].map((f, i) => {
const filePath = i === 0 ? packageJsonPath : pluginJsonPath;
return fs.writeFile(filePath, JSON.stringify(f, null, 2));
})
);
});
export const removeGitFiles = (pluginPath: string) =>
useSpinner('Cleaning', async () => rmdir(`${path.resolve(pluginPath, '.git')}`));
/* eslint-disable no-console */
export const formatPluginDetails = (details: PluginDetails) => {
console.group();
console.log();
console.log(chalk.bold.yellow('Your plugin details'));
console.log('---');
console.log(chalk.bold('Name: '), details.name);
console.log(chalk.bold('ID: '), getPluginId(details));
console.log(chalk.bold('Description: '), details.description);
console.log(chalk.bold('Keywords: '), getPluginKeywords(details));
console.log(chalk.bold('Author: '), details.author);
console.log(chalk.bold('Organisation: '), details.org);
console.log(chalk.bold('Website: '), details.url);
console.log();
console.groupEnd();
};
export const printGrafanaTutorialsDetails = (type: PluginType) => {
console.group();
console.log();
console.log(chalk.bold.yellow(`Congrats! You have just created ${PluginNames[type]}.`));
console.log('Please run `yarn install` to install frontend dependencies.');
console.log();
if (type !== 'backend-datasource-plugin') {
console.log(`${PluginNames[type]} tutorial: ${TutorialPaths[type]}`);
}
console.log(
'Learn more about Grafana Plugins at https://grafana.com/docs/grafana/latest/plugins/developing/development/'
);
console.log();
console.groupEnd();
};
/* eslint-enable no-console */
export const removeLockFile = ({ pluginPath }: { pluginPath: string }) => {
const lockFilePath = path.resolve(pluginPath, 'yarn.lock');
if (existsSync(lockFilePath)) {
unlinkSync(lockFilePath);
}
};

View File

@ -1,12 +0,0 @@
export const testTpl = `
import React from 'react';
import { render, screen } from '@testing-library/react';
import { <%= name %> } from './<%= name %>';
describe('<%= name %>', () => {
it.skip('should render', () => {
});
});
`;

View File

@ -1,10 +0,0 @@
export const componentTpl = `import React from 'react';
export interface Props {};
export const <%= name %> = (props: Props) => {
return (
<div>Hello world!</div>
)
};
`;

View File

@ -1,16 +0,0 @@
export const docsTpl = `import { ArgsTable } from '@storybook/addon-docs/blocks';
import { <%= name %> } from './<%= name %>';
# <%= name %>
### Usage
\`\`\`jsx
import { <%= name %> } from '@grafana/ui';
<<%= name %> />
\`\`\`
### Props
<ArgsTable of={<%= name %>} />
`;

View File

@ -1,4 +0,0 @@
export { componentTpl } from './component.tsx.template';
export { storyTpl } from './story.tsx.template';
export { docsTpl } from './docs.mdx.template';
export { testTpl } from './component.test.tsx.template';

View File

@ -1,22 +0,0 @@
export const storyTpl = `
import React from 'react';
import { <%= name %> } from './<%= name %>';
import { withCenteredStory } from '@grafana/ui/src/utils/storybook/withCenteredStory';
import mdx from './<%= name %>.mdx';
export default {
title: '<%= group %>/<%= name %>',
component: <%= name %>,
decorators: [withCenteredStory],
parameters: {
docs: {
page: mdx,
},
},
};
export const Basic = () => {
return <<%= name %> />;
};
`;

View File

@ -1,3 +0,0 @@
import { flow, camelCase, upperFirst } from 'lodash';
export const pascalCase = flow([camelCase, upperFirst]);

View File

@ -1,79 +0,0 @@
import inquirer, {
Question,
InputQuestion,
CheckboxQuestion,
NumberQuestion,
PasswordQuestion,
EditorQuestion,
ConfirmQuestion,
ListQuestion,
ChoiceOptions,
} from 'inquirer';
type QuestionWithValidation<A extends inquirer.Answers = inquirer.Answers> =
| InputQuestion<A>
| CheckboxQuestion<A>
| NumberQuestion<A>
| PasswordQuestion<A>
| EditorQuestion<A>;
export const answerRequired = <A extends inquirer.Answers>(question: QuestionWithValidation<A>): Question<A> => {
return {
...question,
validate: (answer: A) => answer.trim() !== '' || `${question.name} is required`,
};
};
export const promptInput = <A extends inquirer.Answers>(
name: string,
message: string | ((answers: A) => string),
required = false,
def: any = undefined,
when: boolean | ((answers: A) => boolean | Promise<boolean>) = true
) => {
const model: InputQuestion<A> = {
type: 'input',
name,
message,
default: def,
when,
};
return required ? answerRequired(model) : model;
};
export const promptList = <A extends inquirer.Answers>(
name: string,
message: string | ((answers: A) => string),
choices: () => ChoiceOptions[],
def: any = undefined,
when: boolean | ((answers: A) => boolean | Promise<boolean>) = true
) => {
const model: ListQuestion<A> = {
type: 'list',
name,
message,
choices,
default: def,
when,
};
return model;
};
export const promptConfirm = <A extends inquirer.Answers>(
name: string,
message: string | ((answers: A) => string),
def: any = undefined,
when: boolean | ((answers: A) => boolean | Promise<boolean>) = true
) => {
const model: ConfirmQuestion<A> = {
type: 'confirm',
name,
message,
default: def,
when,
};
return model;
};

View File

@ -1,23 +0,0 @@
import fs = require('fs');
import path = require('path');
/**
* Remove directory recursively
* Ref https://stackoverflow.com/a/42505874
*/
export const rmdir = (dirPath: string) => {
if (!fs.existsSync(dirPath)) {
return;
}
fs.readdirSync(dirPath).forEach((entry) => {
const entryPath = path.join(dirPath, entry);
if (fs.lstatSync(entryPath).isDirectory()) {
rmdir(entryPath);
} else {
fs.unlinkSync(entryPath);
}
});
fs.rmdirSync(dirPath);
};

103
yarn.lock
View File

@ -3380,10 +3380,8 @@ __metadata:
"@grafana/tsconfig": ^1.2.0-rc1
"@grafana/ui": 10.0.0-pre
"@jest/core": 27.5.1
"@types/command-exists": ^1.2.0
"@types/eslint": 8.4.1
"@types/fs-extra": ^9.0.13
"@types/inquirer": ^8.2.1
"@types/jest": 27.4.1
"@types/lodash": 4.14.181
"@types/node": 16.11.26
@ -3399,7 +3397,6 @@ __metadata:
babel-loader: ^8.2.5
babel-plugin-angularjs-annotate: 0.10.0
chalk: ^4.1.2
command-exists: ^1.2.9
commander: ^9.2.0
copy-webpack-plugin: ^9.0.1
css-loader: ^6.7.1
@ -3415,7 +3412,6 @@ __metadata:
globby: ^11.0.4
html-loader: ^3.1.0
html-webpack-plugin: ^5.5.0
inquirer: ^8.2.2
jest: 27.5.1
jest-canvas-mock: 2.3.1
jest-junit: 13.1.0
@ -3425,8 +3421,6 @@ __metadata:
md5-file: ^5.0.0
mini-css-extract-plugin: ^2.6.0
ora: ^5.4.1
pixelmatch: ^5.2.1
pngjs: ^6.0.0
postcss: ^8.4.12
postcss-flexbugs-fixes: ^5.0.2
postcss-loader: ^6.2.1
@ -3438,7 +3432,6 @@ __metadata:
sass: ^1.49.9
sass-loader: ^12.6.0
semver: ^7.3.7
simple-git: ^3.6.0
style-loader: ^3.3.1
terser-webpack-plugin: ^5.3.1
ts-jest: 27.1.3
@ -9002,13 +8995,6 @@ __metadata:
languageName: node
linkType: hard
"@types/command-exists@npm:^1.2.0":
version: 1.2.0
resolution: "@types/command-exists@npm:1.2.0"
checksum: 7c5a626c38898d0267375dbf24ea374e6fcc8a85837f38eeb4485a5699a905eda89941059ea4f82ffc92b2207b29bdd7f7ab8dcbae95ed661b65cafe958e3fb1
languageName: node
linkType: hard
"@types/common-tags@npm:^1.8.0":
version: 1.8.1
resolution: "@types/common-tags@npm:1.8.1"
@ -9617,16 +9603,6 @@ __metadata:
languageName: node
linkType: hard
"@types/inquirer@npm:^8.2.1":
version: 8.2.1
resolution: "@types/inquirer@npm:8.2.1"
dependencies:
"@types/through": "*"
rxjs: ^7.2.0
checksum: 5362d0b1cbec3887c9d5a671a0b19c58cf54066456c8967dd7ee799dfcc242cc8cd8959440c0f2fe7768becaf721b45fd30c222e6b9bcca378f45c68af43bab5
languageName: node
linkType: hard
"@types/is-function@npm:^1.0.0":
version: 1.0.1
resolution: "@types/is-function@npm:1.0.1"
@ -10478,15 +10454,6 @@ __metadata:
languageName: node
linkType: hard
"@types/through@npm:*":
version: 0.0.30
resolution: "@types/through@npm:0.0.30"
dependencies:
"@types/node": "*"
checksum: 9578470db0b527c26e246a1220ae9bffc6bf47f20f89c54aac467c083ab1f7e16c00d9a7b4bb6cb4e2dfae465027270827e5908a6236063f6214625e50585d78
languageName: node
linkType: hard
"@types/tinycolor2@npm:1.4.3":
version: 1.4.3
resolution: "@types/tinycolor2@npm:1.4.3"
@ -14409,13 +14376,6 @@ __metadata:
languageName: node
linkType: hard
"command-exists@npm:^1.2.9":
version: 1.2.9
resolution: "command-exists@npm:1.2.9"
checksum: 729ae3d88a2058c93c58840f30341b7f82688a573019535d198b57a4d8cb0135ced0ad7f52b591e5b28a90feb2c675080ce916e56254a0f7c15cb2395277cac3
languageName: node
linkType: hard
"command-score@npm:^0.1.2":
version: 0.1.2
resolution: "command-score@npm:0.1.2"
@ -21679,28 +21639,6 @@ __metadata:
languageName: node
linkType: hard
"inquirer@npm:^8.2.2":
version: 8.2.2
resolution: "inquirer@npm:8.2.2"
dependencies:
ansi-escapes: ^4.2.1
chalk: ^4.1.1
cli-cursor: ^3.1.0
cli-width: ^3.0.0
external-editor: ^3.0.3
figures: ^3.0.0
lodash: ^4.17.21
mute-stream: 0.0.8
ora: ^5.4.1
run-async: ^2.4.0
rxjs: ^7.5.5
string-width: ^4.1.0
strip-ansi: ^6.0.0
through: ^2.3.6
checksum: 69a2cf32f51af0e94dd66c597fdca42b890ff521b537dbfe1fd532c19a751d54893b7896523691ec30357f6212a80a2417fec7bf34411f369bbf151bdbc95ae9
languageName: node
linkType: hard
"inquirer@npm:^8.2.4":
version: 8.2.4
resolution: "inquirer@npm:8.2.4"
@ -28601,17 +28539,6 @@ __metadata:
languageName: node
linkType: hard
"pixelmatch@npm:^5.2.1":
version: 5.2.1
resolution: "pixelmatch@npm:5.2.1"
dependencies:
pngjs: ^4.0.1
bin:
pixelmatch: bin/pixelmatch
checksum: 0ec7a87168e51b80812d1c39fe1a278e2266dc1e9c426418c2a9d7f0c6465de3c03c51dbf7e6b97c5ba72a043ec3fb576571cdde1f88b12ef0851bf9bfd16da0
languageName: node
linkType: hard
"pkg-dir@npm:^3.0.0":
version: 3.0.0
resolution: "pkg-dir@npm:3.0.0"
@ -28676,20 +28603,6 @@ __metadata:
languageName: node
linkType: hard
"pngjs@npm:^4.0.1":
version: 4.0.1
resolution: "pngjs@npm:4.0.1"
checksum: 9497e08a6c2d850630ba7c8d3738fd36c9db1af7ee8b8c2d4b664e450807a280936dfa1489deb60e6943b968bedd58c9aa93def25a765579d745ea44467fc47f
languageName: node
linkType: hard
"pngjs@npm:^6.0.0":
version: 6.0.0
resolution: "pngjs@npm:6.0.0"
checksum: ab6c285086060087097eab9fe6b5a528a24f9e79c03dea2b4fd6264ed4fdb5beff4a3257eeeaf2a9dc18249b539609c2a4e4013c567164a1f6b5ba2c974d5ecb
languageName: node
linkType: hard
"pnp-webpack-plugin@npm:1.6.4":
version: 1.6.4
resolution: "pnp-webpack-plugin@npm:1.6.4"
@ -32655,15 +32568,6 @@ __metadata:
languageName: node
linkType: hard
"rxjs@npm:^7.2.0":
version: 7.4.0
resolution: "rxjs@npm:7.4.0"
dependencies:
tslib: ~2.1.0
checksum: 6b33172a760dcad6882fdc836ee8cf1ebe160dd7eaad95c45a12338ffdaa96eb41e48e6c25bbd3d1fdf45075949ff447954bc17a9d01c688558a67967d09c114
languageName: node
linkType: hard
"rxjs@npm:^7.5.5":
version: 7.5.5
resolution: "rxjs@npm:7.5.5"
@ -35760,13 +35664,6 @@ __metadata:
languageName: node
linkType: hard
"tslib@npm:~2.1.0":
version: 2.1.0
resolution: "tslib@npm:2.1.0"
checksum: aa189c8179de0427b0906da30926fd53c59d96ec239dff87d6e6bc831f608df0cbd6f77c61dabc074408bd0aa0b9ae4ec35cb2c15f729e32f37274db5730cb78
languageName: node
linkType: hard
"tsutils@npm:^3.21.0":
version: 3.21.0
resolution: "tsutils@npm:3.21.0"