diff --git a/package.json b/package.json index 40f904a..85f9bf4 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "@twind/typescript-plugin", - "version": "0.3.2", + "version": "0.3.3", "description": "TypeScript language service plugin that adds IntelliSense for twind", "//": "mark as private to prevent accidental publish - use 'yarn release'", "private": true, @@ -25,6 +25,7 @@ ".": "./src/index.ts", "./package.json": "./package.json" }, + "// Disable browser builds": "", "browser": false, "scripts": { "build": "distilt", @@ -87,7 +88,7 @@ }, "sideEffects": false, "peerDependencies": { - "twind": ">=0.16.8 <2" + "twind": ">=0.16.9 <2" }, "peerDependenciesMeta": { "twind": { @@ -96,10 +97,10 @@ }, "dependencies": { "cssbeautify": "^0.3.1", - "esbuild": "^0.9.3", "fast-json-stable-stringify": "^2.1.0", "match-sorter": "^6.3.0", - "twind": "^0.16.8", + "sucrase": "^3.17.1", + "twind": "^0.16.9", "typescript": "^4.1.0", "typescript-template-language-service-decorator": "^2.2.0", "vscode-languageserver-types": "^3.13.0" @@ -109,7 +110,7 @@ "@types/node": "^14.14.34", "@typescript-eslint/eslint-plugin": "^4.9.1", "@typescript-eslint/parser": "^4.9.1", - "distilt": "^0.10.3", + "distilt": "^0.10.4", "esbuild-register": "^2.3.0", "eslint": "^7.15.0", "eslint-config-prettier": "^7.0.0", diff --git a/src/colors.ts b/src/colors.ts index 3c50b73..e8e5be1 100644 --- a/src/colors.ts +++ b/src/colors.ts @@ -1,4 +1,4 @@ -const KNOWN_COLORS = new Set(['transparent', 'currentColor']) +export const KNOWN_COLORS = new Set(['transparent', 'currentColor']) const NAMED_COLORS = new Map([ ['aliceblue', '#f0f8ff'], diff --git a/src/language-service.ts b/src/language-service.ts index 951e148..3a994ea 100644 --- a/src/language-service.ts +++ b/src/language-service.ts @@ -120,6 +120,10 @@ export class TwindLanguageService implements TemplateLanguageService { this._twind = new Twind(typescript, info, configurationManager, logger) } + public get enabled(): boolean { + return this._twind.enabled + } + public getCompletionsAtPosition( context: TemplateContext, position: ts.LineAndCharacter, @@ -180,7 +184,7 @@ export class TwindLanguageService implements TemplateLanguageService { JSON.stringify( { [completion.theme.section]: { - [completion.theme.key]: completion.theme.value, + [completion.theme.key || '…']: completion.theme.value || '…', }, }, null, diff --git a/src/load.ts b/src/load.ts index 6d7965a..6441622 100644 --- a/src/load.ts +++ b/src/load.ts @@ -2,8 +2,7 @@ import type * as ts from 'typescript/lib/tsserverlibrary' import * as Path from 'path' import Module from 'module' - -import { buildSync } from 'esbuild' +import { fileURLToPath } from 'url' import type { Configuration } from 'twind' @@ -21,58 +20,34 @@ const TAILWIND_CONFIG_FILES = [ 'tailwind.config.cjs', ] -// TODO use typescript to check files -// this.typescript.server.toNormalizedPath(fileName) -// info.project.containsFile() export const findConfig = (project: ts.server.Project, cwd = process.cwd()): string | undefined => { const locatePath = (files: string[]) => files.map((file) => Path.resolve(cwd, file)).find((file) => project.fileExists(file)) return ( + locatePath(TWIND_CONFIG_FILES) || locatePath(TWIND_CONFIG_FILES.map((file) => Path.join('config', file))) || locatePath(TWIND_CONFIG_FILES.map((file) => Path.join('src', file))) || locatePath(TWIND_CONFIG_FILES.map((file) => Path.join('public', file))) || - locatePath(TWIND_CONFIG_FILES) || locatePath(TAILWIND_CONFIG_FILES) ) } export const loadFile = (file: string, cwd = process.cwd()): T => { - const result = buildSync({ - bundle: true, - entryPoints: [file], - format: 'cjs', - platform: 'node', - target: 'es2018', // `node${process.versions.node}`, - external: Module.builtinModules, - // Follow WMR rules - mainFields: ['esmodules', 'modern', 'module', 'jsnext:main', 'main'], - conditions: ['development', 'esmodules', 'module', 'node', 'import', 'require', 'default'], - sourcemap: 'inline', - minify: false, - splitting: false, - write: false, - absWorkingDir: cwd, - }) - - const module = { exports: {} as { default?: Configuration } & Configuration } - - new Function( - 'exports', - 'require', - 'module', - '__filename', - '__dirname', - result.outputFiles[0].text, - )( - module.exports, - Module.createRequire?.(file) || Module.createRequireFromPath(file), - module, - file, - Path.dirname(file), - ) + try { + // eslint-disable-next-line @typescript-eslint/ban-ts-comment + // @ts-ignore + const from = fileURLToPath(import.meta.url) - return module.exports as T + const require = Module.createRequire?.(from) || Module.createRequireFromPath(from) + + require('sucrase/register') + + // eslint-disable-next-line @typescript-eslint/no-var-requires + return require(Path.resolve(cwd, file)) as T + } catch { + return {} as T + } } export const loadConfig = (configFile: string, cwd = process.cwd()): Configuration => { diff --git a/src/plugin.ts b/src/plugin.ts index 944a357..001863b 100644 --- a/src/plugin.ts +++ b/src/plugin.ts @@ -80,7 +80,7 @@ export class TwindPlugin { // eslint-disable-next-line @typescript-eslint/no-explicit-any getCompletionEntryDetails: (fileName, position, name, ...rest: any[]) => { - if (enable) { + if (enable && ttls.enabled) { const context = helper.getTemplate(fileName, position) if (context) { @@ -97,7 +97,7 @@ export class TwindPlugin { }, getCompletionsAtPosition: (fileName, position, options) => { - if (enable) { + if (enable && ttls.enabled) { const context = helper.getTemplate(fileName, position) if (context) { @@ -112,7 +112,7 @@ export class TwindPlugin { }, getQuickInfoAtPosition: (fileName, position) => { - if (enable) { + if (enable && ttls.enabled) { const context = helper.getTemplate(fileName, position) if (context) { @@ -136,7 +136,7 @@ export class TwindPlugin { getSemanticDiagnostics: (fileName) => { const diagnostics = [...languageService.getSemanticDiagnostics(fileName)] - if (enable) { + if (enable && ttls.enabled) { helper.getAllTemplates(fileName).forEach((context) => { for (const diagnostic of ttls.getSemanticDiagnostics(context)) { diagnostics.push({ diff --git a/src/source-helper.ts b/src/source-helper.ts index 84a4ee7..8344760 100644 --- a/src/source-helper.ts +++ b/src/source-helper.ts @@ -76,7 +76,11 @@ class PlaceholderSubstituter { } } +const kText = Symbol('kText') + class StandardTemplateContext /* implements TemplateContext */ { + private [kText]: string | undefined = undefined + constructor( public readonly typescript: typeof ts, public readonly fileName: string, @@ -113,13 +117,16 @@ class StandardTemplateContext /* implements TemplateContext */ { // @memoize public get text(): string { - return this.typescript.isTemplateExpression(this.node) - ? PlaceholderSubstituter.replacePlaceholders( - this.typescript, - this.templateSettings, - this.node, - ) - : this.node.text + return ( + this[kText] || + (this[kText] = this.typescript.isTemplateExpression(this.node) + ? PlaceholderSubstituter.replacePlaceholders( + this.typescript, + this.templateSettings, + this.node, + ) + : this.node.text) + ) } // @memoize diff --git a/src/source-matcher.ts b/src/source-matcher.ts index b322537..8775cdc 100644 --- a/src/source-matcher.ts +++ b/src/source-matcher.ts @@ -53,6 +53,7 @@ export const getSourceMatchers = ( kind: [SyntaxKind.Identifier, SyntaxKind.StringLiteral], text: 'base', }, + // Do not match CSS objects: `base: { color: 'blue' }` initializer: (node: ts.Node) => node.kind != SyntaxKind.ObjectLiteralExpression, // https://github.com/microsoft/typescript-template-language-service-decorator/blob/main/src/nodes.ts#L62 // TODO styled.button, styled() @@ -74,6 +75,8 @@ export const getSourceMatchers = ( kind: [SyntaxKind.Identifier, SyntaxKind.StringLiteral], text: 'use', }, + // Do not match CSS objects: `use: { color: 'blue' }` + initializer: (node: ts.Node) => node.kind !== SyntaxKind.ObjectLiteralExpression, parent: { kind: SyntaxKind.ObjectLiteralExpression, parent: { @@ -103,6 +106,8 @@ export const getSourceMatchers = ( // style({ variants: { [...]: { [...]: '...' }} }) { kind: SyntaxKind.PropertyAssignment, + // Do not match CSS objects + initializer: (node: ts.Node) => node.kind != SyntaxKind.ObjectLiteralExpression, parent: { kind: SyntaxKind.ObjectLiteralExpression, parent: { diff --git a/src/twind.ts b/src/twind.ts index cb887a3..a9744c4 100644 --- a/src/twind.ts +++ b/src/twind.ts @@ -1,6 +1,6 @@ import * as path from 'path' import Module from 'module' -import { fileURLToPath, pathToFileURL } from 'url' +import { fileURLToPath } from 'url' import type { Logger } from 'typescript-template-language-service-decorator' import type * as TS from 'typescript/lib/tsserverlibrary' @@ -22,7 +22,7 @@ import type { import { theme, create, silent } from 'twind' import { VirtualSheet, virtualSheet } from 'twind/sheets' import { getConfig, loadFile } from './load' -import { getColor } from './colors' +import { getColor, KNOWN_COLORS } from './colors' import type { ConfigurationManager } from './configuration' import { watch } from './watch' @@ -102,19 +102,17 @@ const detailsFromThemeValue =
( .filter(Boolean) .join('/') } - } - if (typeof value == 'string') return value - if (typeof value == 'number') return '' + value + case 'fontFamily': { + return Array.isArray(value) ? value.filter(Boolean).join(', ') : (value as string) + } + } - // https://github.com/tailwindlabs/tailwindcss/blob/master/src/util/transformThemeValue.js - // only testing for sections that uses an array for values if ( - Array.isArray(value) && - !['fontSize', 'outline'].includes(section) && - value.every((x) => x == null || typeof x == 'string' || typeof x == 'number') + typeof value == 'string' && + ((/color/i.test(section) && !KNOWN_COLORS.has(value)) || /\s/.test(value)) ) { - return value.filter(Boolean).join(', ') + return value } return undefined @@ -225,6 +223,10 @@ export class Twind { }) } + public get enabled(): boolean { + return Boolean(this.state?.twindDTSSourceFile) + } + private _reset(): void { this.logger.log('reset state') this._state = this._completions = undefined @@ -250,12 +252,12 @@ export class Twind { ) if (configFile) { - this.logger.log(`Loaded twind config from ${configFile}`) + this.logger.log(`loaded twind config from ${configFile}`) // Reset all state on config file changes this._watchers.push(watch(configFile, () => this._reset(), { once: true })) } else { - this.logger.log(`No twind config found`) + this.logger.log(`no local twind config found`) } const sheet = virtualSheet() @@ -269,7 +271,9 @@ export class Twind { .resolveModuleNames(['twind'], program.getRootFileNames()[0]) .map((moduleName) => moduleName?.resolvedFileName)[0] - this.logger.log('local twind dts: ' + twindDTSFile) + if (twindDTSFile) { + this.logger.log(`found local twind dts at ${twindDTSFile}`) + } let twindDTSSourceFile = (twindDTSFile && @@ -280,32 +284,36 @@ export class Twind { // No local twind but a twind.config -> use our twind if ( - !twindDTSFile && !twindDTSSourceFile && + !twindDTSFile && configFile && /twind\.config\.\w+$/.test(configFile) ) { // eslint-disable-next-line @typescript-eslint/ban-ts-comment // @ts-ignore - const from: string | URL = import.meta.url || pathToFileURL(__filename) + const from = fileURLToPath(import.meta.url) - const { resolve } = - Module.createRequire?.(from) || Module.createRequireFromPath(fileURLToPath(from)) + const { resolve } = Module.createRequire?.(from) || Module.createRequireFromPath(from) try { twindDTSFile = resolve('twind').replace(/\.\w+$/, '.d.ts') - this.logger.log('builtin twind dts: ' + twindDTSFile) + if (twindDTSFile) { + this.logger.log(`found builtin twind dts at ${twindDTSFile}`) + } } catch { // ignore } } - if (twindDTSFile) { + if (!twindDTSSourceFile && twindDTSFile) { + const options = program.getCompilerOptions() + program = this.typescript.createProgram({ - rootNames: [...program.getRootFileNames(), twindDTSFile], - options: program.getCompilerOptions(), - // projectReferences?: readonly ProjectReference[]; - // host?: program.getCom + rootNames: [...program.getRootFileNames(), twindDTSFile.replace(/\.d\.ts$/, '.js')], + options: { + ...options, + typeRoots: [...(options.typeRoots || []), path.dirname(twindDTSFile)], + }, oldProgram: program, }) @@ -314,19 +322,39 @@ export class Twind { .find((sourceFile) => sourceFile.fileName.endsWith('twind/twind.d.ts')) } - this.logger.log('twindDTSSourceFile: ' + twindDTSSourceFile?.fileName) - if (twindDTSSourceFile) { + this.logger.log(`using twind completions from ${twindDTSSourceFile.fileName}`) this._watchers.push(watch(twindDTSSourceFile.fileName, () => this._reset(), { once: true })) + } else { + this.logger.log(`no twind completions found`) } const twindFile = twindDTSSourceFile?.fileName.replace(/\.d\.ts/, '.js') + let version: string | undefined = 'undefined' + if (twindFile) { this._watchers.push(watch(twindFile, () => this._reset(), { once: true })) + + const packageJSON = this.info.project.readFile( + path.join(path.dirname(twindFile), 'package.json'), + ) + + if (packageJSON) { + try { + version = (JSON.parse(packageJSON) || {}).version + } catch { + // ignore + } + } } - this.logger.log('twindFile: ' + twindFile) + if (twindFile) { + this.logger.log(`loading twind${version ? '@' + version : ''} from ${twindFile}`) + } else { + this.logger.log(`using builtin twind`) + } + // Prefer local twind const { tw } = ( (twindFile && (loadFile(twindFile, program.getCurrentDirectory()) as typeof import('twind'))?.create) || @@ -536,7 +564,7 @@ export class Twind { detailsFromThemeValue(theme.section, theme.value), ), )) || - interpolation || + translateInterpolation(interpolation) || detailFromCSS(sheet, tw, value, interpolation)) ) }, @@ -616,7 +644,7 @@ export class Twind { createCompletionToken(className, { kind: screens.has(className) ? 'screen' : undefined, raw: directive, - detail: key == '[' ? 'arbitrary value' : undefined, + label: className.endsWith('[') && key === '[' ? `${className}…]` : undefined, theme: key == '[' ? { section: sectionKey as keyof Theme, key: '', value: '' } @@ -641,6 +669,7 @@ export class Twind { prefix, createCompletionToken(prefix, { raw: directive, + label: `${prefix}…${suffix}`, interpolation: value as CompletionToken['interpolation'], }), ) @@ -672,7 +701,11 @@ function generateCSS( sheet.reset() if (interpolation) { - value += getSampleInterpolation(interpolation) + value = value.replace(/…/g, getSampleInterpolation(interpolation)) + } + + if (value.endsWith('-[')) { + value += '…]' } if (value.endsWith(':')) { @@ -700,6 +733,9 @@ function generateCSS( .trim() } +// TODO do not match @keyframes +const CSS_DECLARATION_RE = /[{;]\s*([A-Z\d-]+)\s*:\s*([^;}]+)/gi + function detailFromCSS( sheet: VirtualSheet, tw: TW, @@ -707,7 +743,11 @@ function detailFromCSS( interpolation?: CompletionToken['interpolation'], ): string { if (interpolation) { - value += getSampleInterpolation(interpolation) + value = value.replace(/…/g, getSampleInterpolation(interpolation)) + } + + if (value.endsWith('-[')) { + value += '…]' } let style: CSSRules = {} @@ -727,7 +767,7 @@ function detailFromCSS( // - if at-rule use at rule // - if variant: use &:hover, &>* - if (key && /^@|&/.test(key)) { + if (value.endsWith(':') && key && /^@|&/.test(key)) { // TODO beautify children: siblings // TODO order of suggestions // TODO grouping prefix is ommited @@ -738,9 +778,14 @@ function detailFromCSS( const css = generateCSS(sheet, tw, value) let result = '' - for (const [, property, value] of css.matchAll(/[{;]\s*([A-Z\d-]+)\s*:\s*([^;}]+)/gi)) { + + // Reset as we break early + CSS_DECLARATION_RE.lastIndex = 0 + for (let match: RegExpExecArray | null; (match = CSS_DECLARATION_RE.exec(css)); ) { + const [, property, value] = match + if (result.length < 30) { - result += (result && '; ') + `${property}: ${value}` + result += (result && '; ') + `${property}: ${convertRem(value)}` } else { result += '; …' break @@ -749,3 +794,18 @@ function detailFromCSS( return result } + +function translateInterpolation( + interpolation?: CompletionToken['interpolation'], +): string | undefined { + switch (interpolation) { + case `string`: // NonEmptyString + return 'any string' + case `number`: // NonNegativeNumber + return 'a number greater or equal zero' + case `nonzero`: // PositiveNumber + return 'a number greater zero' + } + + return interpolation +} diff --git a/yarn.lock b/yarn.lock index 4f649b3..cea3ecd 100644 --- a/yarn.lock +++ b/yarn.lock @@ -208,6 +208,11 @@ ansi-styles@^4.1.0: dependencies: color-convert "^2.0.1" +any-promise@^1.0.0: + version "1.3.0" + resolved "https://registry.npmjs.org/any-promise/-/any-promise-1.3.0.tgz#abc6afeedcea52e809cdc0376aed3ce39635d17f" + integrity sha1-q8av7tzqUugJzcA3au0845Y10X8= + argparse@^1.0.7: version "1.0.10" resolved "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz#bcd6791ea5ae09725e17e5ad988134cd40b3d911" @@ -291,6 +296,11 @@ color-name@~1.1.4: resolved "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== +commander@^4.0.0: + version "4.1.1" + resolved "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz#9fd602bd936294e9e9ef46a3f4d6964044b18068" + integrity sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA== + concat-map@0.0.1: version "0.0.1" resolved "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" @@ -344,10 +354,10 @@ dir-glob@^3.0.1: dependencies: path-type "^4.0.0" -distilt@^0.10.3: - version "0.10.3" - resolved "https://registry.npmjs.org/distilt/-/distilt-0.10.3.tgz#24bba0228a7df163522bc00444775a61ef8a4d8f" - integrity sha512-ieyPdDJSUQ0fOAiXwnPIfv4jRjhP3v6zzC544RjD2gMhnV/MVMY62fQkHkDh7b4zmU88vahvINaIXLA9wDv31A== +distilt@^0.10.4: + version "0.10.4" + resolved "https://registry.npmjs.org/distilt/-/distilt-0.10.4.tgz#814211450ead65619bc79f917dc6b93820fc1e11" + integrity sha512-+F1cpyQ53YgxLffA2PIqgWO6QH1HB9uQhfXJHhohxmH06ilWbVxuZiYuFenv2aVrPBIBfq0TVubHJnnr4Y7ydQ== dependencies: es-module-lexer "^0.3.26" esbuild "^0.9.3" @@ -685,7 +695,7 @@ glob-parent@^5.0.0, glob-parent@^5.1.0: dependencies: is-glob "^4.0.1" -glob@^7.1.3: +glob@7.1.6, glob@^7.1.3: version "7.1.6" resolved "https://registry.npmjs.org/glob/-/glob-7.1.6.tgz#141f33b81a7c2492e125594307480c46679278a6" integrity sha512-LwaxwyZ72Lk7vZINtNNrywX0ZuLyStrdDtabefZKAY5ZGJhVtgdznluResxNmPitE0SAO+O26sWTHeKSI2wMBA== @@ -850,6 +860,11 @@ levn@^0.4.1: prelude-ls "^1.2.1" type-check "~0.4.0" +lines-and-columns@^1.1.6: + version "1.1.6" + resolved "https://registry.npmjs.org/lines-and-columns/-/lines-and-columns-1.1.6.tgz#1c00c743b433cd0a4e80758f7b64a57440d9ff00" + integrity sha1-HADHQ7QzzQpOgHWPe2SldEDZ/wA= + locate-path@^6.0.0: version "6.0.0" resolved "https://registry.npmjs.org/locate-path/-/locate-path-6.0.0.tgz#55321eb309febbc59c4801d931a72452a681d286" @@ -924,11 +939,25 @@ ms@2.1.2: resolved "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009" integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w== +mz@^2.7.0: + version "2.7.0" + resolved "https://registry.npmjs.org/mz/-/mz-2.7.0.tgz#95008057a56cafadc2bc63dde7f9ff6955948e32" + integrity sha512-z81GNO7nnYMEhrGh9LeymoE4+Yr0Wn5McHIZMK5cfQCl+NDX08sCZgUc9/6MHni9IWuFLm1Z3HTCXu2z9fN62Q== + dependencies: + any-promise "^1.0.0" + object-assign "^4.0.1" + thenify-all "^1.0.0" + natural-compare@^1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz#4abebfeed7541f2c27acfb29bdbbd15c8d5ba4f7" integrity sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc= +node-modules-regexp@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz#8d9dbe28964a4ac5712e9131642107c71e90ec40" + integrity sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA= + npm-run-path@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz#b7ecd1e5ed53da8e37a55e1c2269e0b97ed748ea" @@ -936,6 +965,11 @@ npm-run-path@^4.0.1: dependencies: path-key "^3.0.0" +object-assign@^4.0.1: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + integrity sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM= + once@^1.3.0: version "1.4.0" resolved "https://registry.npmjs.org/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1" @@ -1008,6 +1042,13 @@ picomatch@^2.0.5, picomatch@^2.2.1: resolved "https://registry.npmjs.org/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== +pirates@^4.0.1: + version "4.0.1" + resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.1.tgz#643a92caf894566f91b2b986d2c66950a8e2fb87" + integrity sha512-WuNqLTbMI3tmfef2TKxlQmAiLHKtFhlsCZnPIpuv2Ow0RDVO8lfy1Opf4NUzlMXLjPl+Men7AuVdX6TA+s+uGA== + dependencies: + node-modules-regexp "^1.0.0" + pkg-dir@^5.0.0: version "5.0.0" resolved "https://registry.npmjs.org/pkg-dir/-/pkg-dir-5.0.0.tgz#a02d6aebe6ba133a928f74aec20bafdfe6b8e760" @@ -1200,6 +1241,18 @@ style-vendorizer@^2.0.0: resolved "https://registry.npmjs.org/style-vendorizer/-/style-vendorizer-2.0.0.tgz#0c46cec94069f1c768d31c3d307ed045646f503c" integrity sha512-CeqwnrtXd/DKIadVNdJDtHnpCmsc28rWVWLmgpF2HdzTiWFVCE1F1OzWWwskOEtWpOpgm6NrjccfkNGo8qW4MA== +sucrase@^3.17.1: + version "3.17.1" + resolved "https://registry.npmjs.org/sucrase/-/sucrase-3.17.1.tgz#b5e35ca7d99db2cc82b3e942934c3746b41ff8e2" + integrity sha512-04cNLFAhS4NBG2Z/MTkLY6HdoBsqErv3wCncymFlfFtnpMthurlWYML2RlID4M2BbiJSu1eZdQnE8Lcz4PCe2g== + dependencies: + commander "^4.0.0" + glob "7.1.6" + lines-and-columns "^1.1.6" + mz "^2.7.0" + pirates "^4.0.1" + ts-interface-checker "^0.1.9" + supports-color@^5.3.0: version "5.5.0" resolved "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz#e2e69a44ac8772f78a1ec0b35b689df6530efc8f" @@ -1229,6 +1282,20 @@ text-table@^0.2.0: resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz#7f5ee823ae805207c00af2df4a84ec3fcfa570b4" integrity sha1-f17oI66AUgfACvLfSoTsP8+lcLQ= +thenify-all@^1.0.0: + version "1.6.0" + resolved "https://registry.npmjs.org/thenify-all/-/thenify-all-1.6.0.tgz#1a1918d402d8fc3f98fbf234db0bcc8cc10e9726" + integrity sha1-GhkY1ALY/D+Y+/I02wvMjMEOlyY= + dependencies: + thenify ">= 3.1.0 < 4" + +"thenify@>= 3.1.0 < 4": + version "3.3.1" + resolved "https://registry.npmjs.org/thenify/-/thenify-3.3.1.tgz#8932e686a4066038a016dd9e2ca46add9838a95f" + integrity sha512-RVZSIV5IG10Hk3enotrhvz0T9em6cyHBLkH/YAZuKqd8hRkKhSfCGIcP2KUY0EPxndzANBmNllzWPwak+bheSw== + dependencies: + any-promise "^1.0.0" + to-regex-range@^5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/to-regex-range/-/to-regex-range-5.0.1.tgz#1648c44aae7c8d988a326018ed72f5b4dd0392e4" @@ -1241,6 +1308,11 @@ totalist@^2.0.0: resolved "https://registry.npmjs.org/totalist/-/totalist-2.0.0.tgz#db6f1e19c0fa63e71339bbb8fba89653c18c7eec" integrity sha512-+Y17F0YzxfACxTyjfhnJQEe7afPA0GSpYlFkl2VFMxYP7jshQf9gXV7cH47EfToBumFThfKBvfAcoUn6fdNeRQ== +ts-interface-checker@^0.1.9: + version "0.1.13" + resolved "https://registry.npmjs.org/ts-interface-checker/-/ts-interface-checker-0.1.13.tgz#784fd3d679722bc103b1b4b8030bcddb5db2a699" + integrity sha512-Y/arvbn+rrz3JCKl9C4kVNfTfSm2/mEp5FSz5EsZSANGPSlQrpRI5M4PKF+mJnE52jOO90PnPSc3Ur3bTQw0gA== + tslib@^1.8.1: version "1.14.1" resolved "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" @@ -1253,10 +1325,10 @@ tsutils@^3.17.1: dependencies: tslib "^1.8.1" -twind@^0.16.8: - version "0.16.8" - resolved "https://registry.npmjs.org/twind/-/twind-0.16.8.tgz#164da6c889cb52607915bd5b97e62c969ca10cc3" - integrity sha512-9mnQS/q1U+U6cRSdoE/PozGSOpENZWjS/MOFzcd4dpCZQRWoGa5DKBuTRJiHZdSO9ClEnFjlVB8dGR4w4yTimw== +twind@^0.16.9: + version "0.16.9" + resolved "https://registry.npmjs.org/twind/-/twind-0.16.9.tgz#62d04a12d4a96f5f1e72e477af4e8634f356eaac" + integrity sha512-cOpijhtEMEaIhHQ4H3+K/APn1kAYkMtV3fMB/zBfXP+rmKiwjnNZSot8w8YNGnKDqLbV+uCSuFiZtPL60Jscaw== dependencies: csstype "^3.0.5" htmlparser2 "^6.0.0"