Feat/generator 2 iteration (#398)

* chore: eslintrc fix

* chore: update package json with new build scripts, correct build folder

* feat: build ui scripts

* chore: start fixing eslint

* chore: fix interfaces name

* feat: add copy dist source to build with cp (for now)
This commit is contained in:
Alessio Occhipinti 2019-12-23 17:34:01 +01:00 committed by Mattia Astorino
parent bf9a2bb6ed
commit c040e556ae
15 changed files with 225 additions and 168 deletions

View file

@ -4,6 +4,11 @@
"xo-typescript" "xo-typescript"
], ],
"rules": { "rules": {
"@typescript-eslint/indent": ["error", 2, { "SwitchCase": 1 }] "@typescript-eslint/indent": ["error", 2, { "SwitchCase": 1 }],
"@typescript-eslint/member-naming": 0,
"@typescript-eslint/interface-name-prefix": ["error", { "prefixWithI": "always" }]
},
"env": {
"browser": true
} }
} }

2
env.ts
View file

@ -1,3 +1,5 @@
import * as path from 'path'; import * as path from 'path';
export const SRC_FOLDER_PATH = path.resolve('./src');
export const BUILD_FOLDER_PATH = path.resolve('./build'); export const BUILD_FOLDER_PATH = path.resolve('./build');
export const TS_BUILD_FOLDER_PATH = path.resolve('./dist');

View file

@ -24,16 +24,12 @@
"vscode": ">=1.39.0" "vscode": ">=1.39.0"
}, },
"scripts": { "scripts": {
"bu": "yarn cleanup && yarn build:ts && yarn build:generate-themes", "build": "yarn cleanup && yarn build:ts && yarn build:generate-themes && yarn build:ui",
"lint": "eslint .",
"build": "yarn cleanup && yarn build:ts && yarn build-themes && yarn build-ui",
"cleanup": "rimraf build && rimraf dist", "cleanup": "rimraf build && rimraf dist",
"lint": "eslint .",
"build:ui": "node dist/scripts/ui/index.js",
"build:generate-themes": "node dist/scripts/generator/index.js", "build:generate-themes": "node dist/scripts/generator/index.js",
"build-ui": "gulp build:copy-ui && yarn build-ui-release-notes", "build:ts": "tsc -p ./tsconfig.json && cp -r dist/src/ build",
"build-ui-release-notes": "browserify out/src/webviews/ui/release-notes/index.js > out/ui/release-notes.js",
"build-ui-only": "yarn cleanup && yarn build-ts && yarn build-ui",
"build:ts": "tsc -p ./tsconfig.json",
"test": "tslint **.ts",
"postinstall": "node ./node_modules/vscode/bin/install && opencollective postinstall && tsc -p tsconfig.json" "postinstall": "node ./node_modules/vscode/bin/install && opencollective postinstall && tsc -p tsconfig.json"
}, },
"categories": [ "categories": [
@ -48,7 +44,7 @@
"*" "*"
], ],
"extensionKind": "ui", "extensionKind": "ui",
"main": "./out/src/material.theme.config", "main": "./build/material.theme.config",
"contributes": { "contributes": {
"commands": [ "commands": [
{ {
@ -95,52 +91,52 @@
"themes": [ "themes": [
{ {
"label": "Material Theme", "label": "Material Theme",
"path": "./out/themes/Material-Theme-Default.json", "path": "./build/themes/Material-Theme-Default.json",
"uiTheme": "vs-dark" "uiTheme": "vs-dark"
}, },
{ {
"label": "Material Theme High Contrast", "label": "Material Theme High Contrast",
"path": "./out/themes/Material-Theme-Default-High-Contrast.json", "path": "./build/themes/Material-Theme-Default-High-Contrast.json",
"uiTheme": "vs-dark" "uiTheme": "vs-dark"
}, },
{ {
"label": "Material Theme Darker", "label": "Material Theme Darker",
"path": "./out/themes/Material-Theme-Darker.json", "path": "./build/themes/Material-Theme-Darker.json",
"uiTheme": "vs-dark" "uiTheme": "vs-dark"
}, },
{ {
"label": "Material Theme Darker High Contrast", "label": "Material Theme Darker High Contrast",
"path": "./out/themes/Material-Theme-Darker-High-Contrast.json", "path": "./build/themes/Material-Theme-Darker-High-Contrast.json",
"uiTheme": "vs-dark" "uiTheme": "vs-dark"
}, },
{ {
"label": "Material Theme Palenight", "label": "Material Theme Palenight",
"path": "./out/themes/Material-Theme-Palenight.json", "path": "./build/themes/Material-Theme-Palenight.json",
"uiTheme": "vs-dark" "uiTheme": "vs-dark"
}, },
{ {
"label": "Material Theme Palenight High Contrast", "label": "Material Theme Palenight High Contrast",
"path": "./out/themes/Material-Theme-Palenight-High-Contrast.json", "path": "./build/themes/Material-Theme-Palenight-High-Contrast.json",
"uiTheme": "vs-dark" "uiTheme": "vs-dark"
}, },
{ {
"label": "Material Theme Ocean", "label": "Material Theme Ocean",
"path": "./out/themes/Material-Theme-Ocean.json", "path": "./build/themes/Material-Theme-Ocean.json",
"uiTheme": "vs-dark" "uiTheme": "vs-dark"
}, },
{ {
"label": "Material Theme Ocean High Contrast", "label": "Material Theme Ocean High Contrast",
"path": "./out/themes/Material-Theme-Ocean-High-Contrast.json", "path": "./build/themes/Material-Theme-Ocean-High-Contrast.json",
"uiTheme": "vs-dark" "uiTheme": "vs-dark"
}, },
{ {
"label": "Material Theme Lighter", "label": "Material Theme Lighter",
"path": "./out/themes/Material-Theme-Lighter.json", "path": "./build/themes/Material-Theme-Lighter.json",
"uiTheme": "vs" "uiTheme": "vs"
}, },
{ {
"label": "Material Theme Lighter High Contrast", "label": "Material Theme Lighter High Contrast",
"path": "./out/themes/Material-Theme-Lighter-High-Contrast.json", "path": "./build/themes/Material-Theme-Lighter-High-Contrast.json",
"uiTheme": "vs" "uiTheme": "vs"
} }
] ]
@ -163,6 +159,7 @@
"devDependencies": { "devDependencies": {
"@babel/register": "7.4.4", "@babel/register": "7.4.4",
"@moxer/vscode-theme-generator": "1.1.0", "@moxer/vscode-theme-generator": "1.1.0",
"@types/browserify": "12.0.36",
"@types/gulp-if": "0.0.33", "@types/gulp-if": "0.0.33",
"@types/gulp-util": "3.0.34", "@types/gulp-util": "3.0.34",
"@types/mustache": "0.8.32", "@types/mustache": "0.8.32",

View file

@ -25,9 +25,13 @@ const generate = async (): Promise<void> => {
}); });
}; };
try { const run = async (): Promise<void> => {
generate(); try {
} catch (error) { await generate();
console.error(error); } catch (error) {
process.exit(1); console.error('ERROR build:generate-themes', error);
} process.exit(1);
}
};
run();

44
scripts/ui/index.ts Normal file
View file

@ -0,0 +1,44 @@
import * as fs from 'fs-extra';
import * as path from 'path';
import browserify from 'browserify';
import {BUILD_FOLDER_PATH, SRC_FOLDER_PATH, TS_BUILD_FOLDER_PATH} from '../../env';
const UI_FOLDER_PATH = path.join(SRC_FOLDER_PATH, 'webviews', 'ui');
const UI_JS_FOLDER_PATH = path.join(TS_BUILD_FOLDER_PATH, 'src', 'webviews', 'ui');
const UI_FOLDER_BUILD_PATH = path.join(BUILD_FOLDER_PATH, 'ui');
const copyStatics = async (): Promise<void[]> => {
const paths = [{
src: path.join(UI_FOLDER_PATH, 'release-notes', 'release-notes.html'),
dest: path.join(UI_FOLDER_BUILD_PATH, 'release-notes.html')
}, {
src: path.join(UI_FOLDER_PATH, 'release-notes', 'style.css'),
dest: path.join(UI_FOLDER_BUILD_PATH, 'style.css')
}];
return Promise.all(paths.map(async path => fs.copyFile(path.src, path.dest)));
};
const buildJs = async (type: 'release-notes'): Promise<void> => {
const jsBuildPath = path.join(UI_FOLDER_BUILD_PATH, `${type}.js`);
const b = browserify();
await fs.createFile(jsBuildPath);
const jsBuildFileStream = fs.createWriteStream(jsBuildPath);
b.add(path.join(UI_JS_FOLDER_PATH, type, 'index.js'));
b.bundle().pipe(jsBuildFileStream);
return Promise.resolve();
};
const run = async (): Promise<void> => {
try {
await fs.mkdirp(UI_FOLDER_BUILD_PATH);
await copyStatics();
await buildJs('release-notes');
} catch (error) {
console.error('ERROR build:ui:', error);
process.exit(1);
}
};
run();

View file

@ -10,7 +10,7 @@ import checkInstallation from './helpers/check-installation';
import writeChangelog from './helpers/write-changelog'; import writeChangelog from './helpers/write-changelog';
import {ReleaseNotesWebview} from './webviews/ReleaseNotes'; import {ReleaseNotesWebview} from './webviews/ReleaseNotes';
export async function activate(context: ExtensionContext) { export async function activate(context: ExtensionContext): Promise<void> {
const installationType = checkInstallation(); const installationType = checkInstallation();
const releaseNotesView = new ReleaseNotesWebview(context); const releaseNotesView = new ReleaseNotesWebview(context);
@ -32,5 +32,5 @@ export async function activate(context: ExtensionContext) {
await updateAccent(accentPicked); await updateAccent(accentPicked);
}); });
Commands.registerCommand('materialTheme.showReleaseNotes', () => releaseNotesView.show()); Commands.registerCommand('materialTheme.showReleaseNotes', async () => releaseNotesView.show());
} }

View file

@ -1,13 +1,6 @@
import {WebviewController} from './Webview'; import {WebviewController} from './Webview';
import {
ExtensionContext
} from 'vscode';
export class ReleaseNotesWebview extends WebviewController<{}> { export class ReleaseNotesWebview extends WebviewController<{}> {
constructor(context: ExtensionContext) {
super(context);
}
get filename(): string { get filename(): string {
return 'release-notes.html'; return 'release-notes.html';
} }
@ -24,7 +17,7 @@ export class ReleaseNotesWebview extends WebviewController<{}> {
* This will be called by the WebviewController when init the view * This will be called by the WebviewController when init the view
* passing as `window.bootstrap` to the view. * passing as `window.bootstrap` to the view.
*/ */
getBootstrap() { getBootstrap(): {} {
return {}; return {};
} }
} }

View file

@ -1,18 +1,12 @@
import {WebviewController} from './Webview'; import {WebviewController} from './Webview';
import { import {
workspace as Workspace, workspace as Workspace
ExtensionContext
} from 'vscode'; } from 'vscode';
import {SettingsBootstrap} from './interfaces'; import {ISettingsBootstrap} from './interfaces';
import {getCustomSettings} from '../helpers/settings'; import {getCustomSettings} from '../helpers/settings';
import {getDefaultValues} from '../helpers/fs'; import {getDefaultValues} from '../helpers/fs';
export class SettingsWebview extends WebviewController<SettingsBootstrap> { export class SettingsWebview extends WebviewController<ISettingsBootstrap> {
constructor(context: ExtensionContext) {
super(context);
}
get filename(): string { get filename(): string {
return 'settings.html'; return 'settings.html';
} }
@ -25,26 +19,26 @@ export class SettingsWebview extends WebviewController<SettingsBootstrap> {
return 'Material Theme Settings'; return 'Material Theme Settings';
} }
private getAvailableScopes(): ['user' | 'workspace', string][] {
const scopes: ['user' | 'workspace', string][] = [['user', 'User']];
return scopes
.concat(
Workspace.workspaceFolders !== undefined && Workspace.workspaceFolders.length ?
['workspace', 'Workspace'] :
[]
);
}
/** /**
* This will be called by the WebviewController when init the view * This will be called by the WebviewController when init the view
* passing as `window.bootstrap` to the view. * passing as `window.bootstrap` to the view.
*/ */
getBootstrap() { getBootstrap(): ISettingsBootstrap {
return { return {
config: getCustomSettings(), config: getCustomSettings(),
defaults: getDefaultValues(), defaults: getDefaultValues(),
scope: 'user', scope: 'user',
scopes: this.getAvailableScopes() scopes: this.getAvailableScopes()
} as SettingsBootstrap; };
}
private getAvailableScopes(): Array<['user' | 'workspace', string]> {
const scopes: Array<['user' | 'workspace', string]> = [['user', 'User']];
return scopes
.concat(
Workspace.workspaceFolders?.length ?
['workspace', 'Workspace'] :
[]
);
} }
} }

View file

@ -13,13 +13,13 @@ import {
} from 'vscode'; } from 'vscode';
import {getCustomSettings} from '../helpers/settings'; import {getCustomSettings} from '../helpers/settings';
import {Invalidates, Message, SettingsChangedMessage} from './interfaces'; import {Invalidates, Message, ISettingsChangedMessage} from './interfaces';
export abstract class WebviewController<TBootstrap> extends Disposable { export abstract class WebviewController<TBootstrap> extends Disposable {
private panel: WebviewPanel | undefined; private panel: WebviewPanel | undefined;
private disposablePanel: Disposable | undefined; private disposablePanel: Disposable | undefined;
private invalidateOnVisible: Invalidates; private invalidateOnVisible: Invalidates;
private context: ExtensionContext; private readonly context: ExtensionContext;
constructor(context: ExtensionContext) { constructor(context: ExtensionContext) {
// Applying dispose callback for our disposable function // Applying dispose callback for our disposable function
@ -28,92 +28,12 @@ export abstract class WebviewController<TBootstrap> extends Disposable {
this.context = context; this.context = context;
} }
abstract get filename(): string; dispose(): void {
abstract get id(): string;
abstract get title(): string;
abstract getBootstrap(): TBootstrap;
dispose() {
if (this.disposablePanel) { if (this.disposablePanel) {
this.disposablePanel.dispose(); this.disposablePanel.dispose();
} }
} }
private async getHtml(): Promise<string> {
const doc = await Workspace
.openTextDocument(this.context.asAbsolutePath(path.join('out/ui', this.filename)));
return doc.getText();
}
private postMessage(message: Message, invalidates: Invalidates = 'all') {
if (this.panel === undefined) {
return false;
}
const result = this.panel.webview.postMessage(message);
// If post was ok, update invalidateOnVisible if different than default
if (!result && this.invalidateOnVisible !== 'all') {
this.invalidateOnVisible = invalidates;
}
return result;
}
private postUpdatedConfiguration() {
// Post full raw configuration
return this.postMessage({
type: 'settingsChanged',
config: getCustomSettings()
} as SettingsChangedMessage, 'config');
}
private onPanelDisposed() {
if (this.disposablePanel) {
this.disposablePanel.dispose();
}
this.panel = undefined;
}
private onViewStateChanged(event: WebviewPanelOnDidChangeViewStateEvent) {
console.log('WebviewEditor.onViewStateChanged', event.webviewPanel.visible);
if (!this.invalidateOnVisible || !event.webviewPanel.visible) {
return;
}
// Update the view since it can be outdated
const invalidContext = this.invalidateOnVisible;
this.invalidateOnVisible = undefined;
switch (invalidContext) {
case 'config':
// Post the new configuration to the view
return this.postUpdatedConfiguration();
default:
return this.show();
}
}
protected async onMessageReceived(event: Message) {
if (event === null) {
return;
}
console.log(`WebviewEditor.onMessageReceived: type=${event.type}, data=${JSON.stringify(event)}`);
switch (event.type) {
case 'saveSettings':
// TODO: update settings
return;
default:
return;
}
}
async show(): Promise<void> { async show(): Promise<void> {
const html = await this.getHtml(); const html = await this.getHtml();
@ -154,4 +74,82 @@ export abstract class WebviewController<TBootstrap> extends Disposable {
this.panel.webview.html = fullHtml; this.panel.webview.html = fullHtml;
} }
protected onMessageReceived(event: Message): void {
if (event === null) {
return;
}
console.log(`WebviewEditor.onMessageReceived: type=${event.type}, data=${JSON.stringify(event)}`);
switch (event.type) {
case 'saveSettings':
// TODO: update settings
break;
default:
break;
}
}
private async getHtml(): Promise<string> {
const doc = await Workspace
.openTextDocument(this.context.asAbsolutePath(path.join('out/ui', this.filename)));
return doc.getText();
}
private async postMessage(message: Message, invalidates: Invalidates = 'all'): Promise<boolean> {
if (this.panel === undefined) {
return false;
}
const result = await this.panel.webview.postMessage(message);
// If post was ok, update invalidateOnVisible if different than default
if (!result && this.invalidateOnVisible !== 'all') {
this.invalidateOnVisible = invalidates;
}
return result;
}
private async postUpdatedConfiguration(): Promise<boolean> {
// Post full raw configuration
return this.postMessage({
type: 'settingsChanged',
config: getCustomSettings()
} as ISettingsChangedMessage, 'config');
}
private onPanelDisposed(): void {
if (this.disposablePanel) {
this.disposablePanel.dispose();
}
this.panel = undefined;
}
private async onViewStateChanged(event: WebviewPanelOnDidChangeViewStateEvent): Promise<boolean | void> {
console.log('WebviewEditor.onViewStateChanged', event.webviewPanel.visible);
if (!this.invalidateOnVisible || !event.webviewPanel.visible) {
return;
}
// Update the view since it can be outdated
const invalidContext = this.invalidateOnVisible;
this.invalidateOnVisible = undefined;
switch (invalidContext) {
case 'config':
// Post the new configuration to the view
return this.postUpdatedConfiguration();
default:
return this.show();
}
}
abstract get filename(): string;
abstract get id(): string;
abstract get title(): string;
abstract getBootstrap(): TBootstrap;
} }

View file

@ -2,52 +2,55 @@ import {IThemeCustomSettings} from '../interfaces/itheme-custom-properties';
import {IDefaults} from '../interfaces/idefaults'; import {IDefaults} from '../interfaces/idefaults';
export interface IChangeType { export interface IChangeType {
children: { children: Array<{
text: String; text: string;
}[]; }>;
} }
export interface IPost { export interface IPost {
title: String; title: string;
version: String; version: string;
fixed: IChangeType[]; fixed: IChangeType[];
new: IChangeType[]; new: IChangeType[];
breaking: IChangeType[]; breaking: IChangeType[];
} }
export interface IPostNormalized { export interface IPostNormalized {
title: String; title: string;
version: String; version: string;
fixed: String[]; fixed: string[];
new: String[]; new: string[];
breaking: String[]; breaking: string[];
} }
export interface SettingsChangedMessage { export interface ISettingsChangedMessage {
type: 'settingsChanged'; type: 'settingsChanged';
config: IThemeCustomSettings; config: IThemeCustomSettings;
} }
export interface SaveSettingsMessage { export interface ISaveSettingsMessage {
type: 'saveSettings'; type: 'saveSettings';
changes: { changes: {
[key: string]: any; [key: string]: any;
}; };
removes: string[]; removes: string[];
scope: 'user' | 'workspace'; scope: 'user' | 'workspace';
uri: string; uri: string;
} }
export type Message = SaveSettingsMessage | SettingsChangedMessage; export type Message = ISaveSettingsMessage | ISettingsChangedMessage;
export type Invalidates = 'all' | 'config' | undefined; export type Invalidates = 'all' | 'config' | undefined;
export interface Bootstrap { export interface IBootstrap {
config: IThemeCustomSettings; config: IThemeCustomSettings;
} }
export interface SettingsBootstrap extends Bootstrap { export interface ISettingsBootstrap extends IBootstrap {
scope: 'user' | 'workspace'; scope: 'user' | 'workspace';
scopes: ['user' | 'workspace', string][]; scopes: Array<['user' | 'workspace', string]>;
defaults: IDefaults; defaults: IDefaults;
} }
declare global { declare global {
interface Window { bootstrap: Bootstrap | SettingsBootstrap | {}; } // eslint-disable-next-line @typescript-eslint/interface-name-prefix
interface Window {
bootstrap: IBootstrap | ISettingsBootstrap | {};
}
} }

View file

@ -2,18 +2,19 @@ import * as sanityClient from '@sanity/client';
import {IPost, IPostNormalized} from '../../interfaces'; import {IPost, IPostNormalized} from '../../interfaces';
// eslint-disable-next-line @typescript-eslint/explicit-function-return-type
const getClient = () => sanityClient({ const getClient = () => sanityClient({
projectId: 'v475t82f', projectId: 'v475t82f',
dataset: 'production' dataset: 'production'
}); });
const getReleaseNotes = (): Promise<object[]> => { const getReleaseNotes = async (): Promise<object[]> => {
const query = '*[_type == "release"] | order(version desc)'; const query = '*[_type == "release"] | order(version desc)';
const client = getClient(); const client = getClient();
return client.fetch(query); return client.fetch(query);
}; };
const renderTemplate = (posts: IPostNormalized[]) => { const renderTemplate = (posts: IPostNormalized[]): string => {
return `${posts.reduce((acc, {version, title, fixed, new: newItems, breaking}) => acc.concat(`<section class="Release"> return `${posts.reduce((acc, {version, title, fixed, new: newItems, breaking}) => acc.concat(`<section class="Release">
<header class="Release__Header"> <header class="Release__Header">
<span class="Release__Number">${version}</span> <span class="Release__Number">${version}</span>
@ -21,11 +22,11 @@ const renderTemplate = (posts: IPostNormalized[]) => {
</header> </header>
<ul class="Release-List"> <ul class="Release-List">
${fixed.reduce((accc: string, src) => ${fixed.reduce((accc: string, src) =>
src.length > 0 ? accc.concat(`<li data-type="fixed">${src}</li>`) : '', '')} src.length > 0 ? accc.concat(`<li data-type="fixed">${src}</li>`) : '', '')}
${newItems.reduce((accc: string, src) => ${newItems.reduce((accc: string, src) =>
src.length > 0 ? accc.concat(`<li data-type="new">${src}</li>`) : '', '')} src.length > 0 ? accc.concat(`<li data-type="new">${src}</li>`) : '', '')}
${breaking.reduce((accc: string, src) => ${breaking.reduce((accc: string, src) =>
src.length > 0 ? accc.concat(`<li data-type="breaking">${src}</li>`) : '', '')} src.length > 0 ? accc.concat(`<li data-type="breaking">${src}</li>`) : '', '')}
</ul> </ul>
</section>`), '')}`; </section>`), '')}`;
}; };

View file

@ -1,17 +1,17 @@
import {SettingsBootstrap} from '../../interfaces'; import {ISettingsBootstrap} from '../../interfaces';
import accentsSelector from './lib/accents-selector'; import accentsSelector from './lib/accents-selector';
const run = () => { const run = (): void => {
bind(); bind();
const {config, defaults} = window.bootstrap as SettingsBootstrap; const {config, defaults} = window.bootstrap as ISettingsBootstrap;
accentsSelector('[data-setting="accentSelector"]', defaults.accents, config.accent); accentsSelector('[data-setting="accentSelector"]', defaults.accents, config.accent);
console.log(defaults); console.log(defaults);
console.log(config); console.log(config);
}; };
const bind = () => { const bind = (): void => {
document.querySelector('#fixIconsCTA').addEventListener('click', () => { document.querySelector('#fixIconsCTA').addEventListener('click', () => {
console.log('Test click'); console.log('Test click');
}); });

View file

@ -9,7 +9,7 @@ const templateSingleAccent = (accentName: string, accentColor: string): string =
`; `;
}; };
export default (containerSelector: string, accentsObject: IAccents, currentAccent: string) => { export default (containerSelector: string, accentsObject: IAccents, currentAccent: string): void => {
const container = document.querySelector(containerSelector); const container = document.querySelector(containerSelector);
for (const accentKey of Object.keys(accentsObject)) { for (const accentKey of Object.keys(accentsObject)) {

View file

@ -7,6 +7,7 @@
"es7", "es7",
"dom" "dom"
], ],
"esModuleInterop": true,
"sourceMap": true, "sourceMap": true,
"allowUnreachableCode": false, "allowUnreachableCode": false,
"noUnusedLocals": true, "noUnusedLocals": true,

View file

@ -112,6 +112,14 @@
resolved "https://registry.yarnpkg.com/@sanity/timed-out/-/timed-out-4.0.2.tgz#c9f61f9a1609baa1eb3e4235a24ea2a775022cdf" resolved "https://registry.yarnpkg.com/@sanity/timed-out/-/timed-out-4.0.2.tgz#c9f61f9a1609baa1eb3e4235a24ea2a775022cdf"
integrity sha512-NBDKGj14g9Z+bopIvZcQKWCzJq5JSrdmzRR1CS+iyA3Gm8SnIWBfZa7I3mTg2X6Nu8LQXG0EPKXdOGozLS4i3w== integrity sha512-NBDKGj14g9Z+bopIvZcQKWCzJq5JSrdmzRR1CS+iyA3Gm8SnIWBfZa7I3mTg2X6Nu8LQXG0EPKXdOGozLS4i3w==
"@types/browserify@12.0.36":
version "12.0.36"
resolved "https://registry.yarnpkg.com/@types/browserify/-/browserify-12.0.36.tgz#a7b662550bd4102b38ba83ef4ad6db871ea91331"
integrity sha512-hYXvPod5upkYTC7auziOATFsu/0MGxozbzNI80sZV044JTF7UtstHeNOM52b+bg7/taZ3fheK7oeb+jpm4C0/w==
dependencies:
"@types/insert-module-globals" "*"
"@types/node" "*"
"@types/color-name@^1.1.1": "@types/color-name@^1.1.1":
version "1.1.1" version "1.1.1"
resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0"
@ -161,6 +169,13 @@
"@types/vinyl" "*" "@types/vinyl" "*"
chalk "^2.2.0" chalk "^2.2.0"
"@types/insert-module-globals@*":
version "7.0.1"
resolved "https://registry.yarnpkg.com/@types/insert-module-globals/-/insert-module-globals-7.0.1.tgz#234f9263f6b315088287e3597d7e98033804a031"
integrity sha512-qtSfo/jdYHO4jNO6QCp4CwR/TPrvR39Yan5K4nPU1iCmxcnTWiERKDXcvFGuXEmfpjrHeOCvrZPa0UrUsy+mvA==
dependencies:
"@types/node" "*"
"@types/json-schema@^7.0.3": "@types/json-schema@^7.0.3":
version "7.0.3" version "7.0.3"
resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636" resolved "https://registry.yarnpkg.com/@types/json-schema/-/json-schema-7.0.3.tgz#bdfd69d61e464dcc81b25159c270d75a73c1a636"