feat: i18n package
This commit is contained in:
parent
a3aca20099
commit
ebe9786987
10 changed files with 373 additions and 19 deletions
|
@ -4,6 +4,7 @@ export {
|
||||||
LocalstorageStorage,
|
LocalstorageStorage,
|
||||||
tl,
|
tl,
|
||||||
defaultDcs,
|
defaultDcs,
|
||||||
|
assertNever,
|
||||||
} from '@mtcute/core'
|
} from '@mtcute/core'
|
||||||
|
|
||||||
export * from './types'
|
export * from './types'
|
||||||
|
|
7
packages/i18n/README.md
Normal file
7
packages/i18n/README.md
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
# @mtcute/i18n
|
||||||
|
|
||||||
|
> I18n for MTCute
|
||||||
|
|
||||||
|
This package implements utility for i18n functionality in `@mtcute/client` based apps.
|
||||||
|
|
||||||
|
Documentation is TBA.
|
18
packages/i18n/package.json
Normal file
18
packages/i18n/package.json
Normal file
|
@ -0,0 +1,18 @@
|
||||||
|
{
|
||||||
|
"name": "@mtcute/i18n",
|
||||||
|
"private": true,
|
||||||
|
"version": "1.0.0",
|
||||||
|
"description": "I18n for MTCute",
|
||||||
|
"author": "Alisa Sireneva <me@tei.su>",
|
||||||
|
"license": "LGPL-3.0",
|
||||||
|
"main": "src/index.ts",
|
||||||
|
"scripts": {
|
||||||
|
"test": "mocha -r ts-node/register \"tests/**/*.spec.ts\"",
|
||||||
|
"coverage": "nyc npm run test",
|
||||||
|
"build": "tsc",
|
||||||
|
"docs": "npx typedoc"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@mtcute/client": "workspace:^1.0.0"
|
||||||
|
}
|
||||||
|
}
|
74
packages/i18n/src/index.ts
Normal file
74
packages/i18n/src/index.ts
Normal file
|
@ -0,0 +1,74 @@
|
||||||
|
import { MtArgumentError, ParsedUpdate } from '@mtcute/client'
|
||||||
|
import { I18nValue, MtcuteI18nFunction, OtherLanguageWrap } from './types'
|
||||||
|
import { createI18nStringsIndex, extractLanguageFromUpdate } from './utils'
|
||||||
|
|
||||||
|
export interface MtcuteI18nParameters<Strings> {
|
||||||
|
/**
|
||||||
|
* Primary language which will also be used as a fallback
|
||||||
|
*/
|
||||||
|
primaryLanguage: {
|
||||||
|
/**
|
||||||
|
* Two letter language code.
|
||||||
|
*/
|
||||||
|
name: string
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Strings for the language.
|
||||||
|
*/
|
||||||
|
strings: Strings
|
||||||
|
}
|
||||||
|
|
||||||
|
otherLanguages?: Record<string, OtherLanguageWrap<Strings>>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Language that will be used if no language is specified
|
||||||
|
*
|
||||||
|
* Defaults to {@link primaryLanguage}
|
||||||
|
*/
|
||||||
|
defaultLanguage?: string
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createMtcuteI18n<Strings>(
|
||||||
|
params: MtcuteI18nParameters<Strings>
|
||||||
|
): MtcuteI18nFunction<Strings> {
|
||||||
|
const {
|
||||||
|
primaryLanguage,
|
||||||
|
otherLanguages,
|
||||||
|
defaultLanguage = primaryLanguage.name,
|
||||||
|
} = params
|
||||||
|
|
||||||
|
const indexes: Record<string, Record<string, I18nValue>> = {}
|
||||||
|
const fallbackIndex = (indexes[primaryLanguage.name] =
|
||||||
|
createI18nStringsIndex(primaryLanguage.strings))
|
||||||
|
if (otherLanguages) {
|
||||||
|
Object.keys(otherLanguages).forEach((lang) => {
|
||||||
|
indexes[lang] = createI18nStringsIndex(otherLanguages[lang])
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(defaultLanguage in indexes)) {
|
||||||
|
throw new MtArgumentError(
|
||||||
|
'defaultLanguage is not a registered language'
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
const tr = (lang: ParsedUpdate['data'] | string | null, key: string, ...params: any[]) => {
|
||||||
|
if (lang === null) lang = defaultLanguage
|
||||||
|
|
||||||
|
if (typeof lang === 'object') {
|
||||||
|
lang = extractLanguageFromUpdate(lang) ?? defaultLanguage
|
||||||
|
}
|
||||||
|
|
||||||
|
const strings = indexes[lang] ?? fallbackIndex
|
||||||
|
|
||||||
|
let val = strings[key] ?? fallbackIndex[key] ?? `[missing: ${key}]`
|
||||||
|
|
||||||
|
if (typeof val === 'function') {
|
||||||
|
val = val(...params)
|
||||||
|
}
|
||||||
|
|
||||||
|
return val
|
||||||
|
}
|
||||||
|
|
||||||
|
return tr as MtcuteI18nFunction<Strings>
|
||||||
|
}
|
39
packages/i18n/src/types.ts
Normal file
39
packages/i18n/src/types.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import { ParsedUpdate } from '@mtcute/client'
|
||||||
|
|
||||||
|
type Values<T> = T[keyof T]
|
||||||
|
type SafeGet<T, K extends string> = T extends Record<K, any> ? T[K] : never
|
||||||
|
|
||||||
|
export type I18nValue = string | ((...args: any[]) => string)
|
||||||
|
|
||||||
|
type NestedKeysDelimited<T> = Values<{
|
||||||
|
[key in Extract<keyof T, string>]: T[key] extends I18nValue
|
||||||
|
? key
|
||||||
|
: `${key}.${T[key] extends infer R ? NestedKeysDelimited<R> : never}`
|
||||||
|
}>
|
||||||
|
|
||||||
|
type GetValueNested<T, K extends string> = K extends `${infer P}.${infer Q}`
|
||||||
|
? GetValueNested<SafeGet<T, P>, Q>
|
||||||
|
: SafeGet<T, K>
|
||||||
|
|
||||||
|
type ExtractParameter<Strings, K extends string> = GetValueNested<
|
||||||
|
Strings,
|
||||||
|
K
|
||||||
|
> extends (...params: infer R) => any
|
||||||
|
? R
|
||||||
|
: never
|
||||||
|
|
||||||
|
export type MtcuteI18nFunction<Strings> = <
|
||||||
|
K extends NestedKeysDelimited<Strings>
|
||||||
|
>(
|
||||||
|
lang: ParsedUpdate['data'] | string | null,
|
||||||
|
key: K,
|
||||||
|
...params: ExtractParameter<Strings, K>
|
||||||
|
) => string
|
||||||
|
|
||||||
|
export type OtherLanguageWrap<Strings> = {
|
||||||
|
[key in keyof Strings]?: Strings[key] extends I18nValue
|
||||||
|
? I18nValue
|
||||||
|
: Strings[key] extends Record<string, any>
|
||||||
|
? OtherLanguageWrap<Strings[key]>
|
||||||
|
: never
|
||||||
|
}
|
68
packages/i18n/src/utils.ts
Normal file
68
packages/i18n/src/utils.ts
Normal file
|
@ -0,0 +1,68 @@
|
||||||
|
import {
|
||||||
|
ParsedUpdate,
|
||||||
|
assertNever,
|
||||||
|
User,
|
||||||
|
Message,
|
||||||
|
DeleteMessageUpdate,
|
||||||
|
ChatMemberUpdate,
|
||||||
|
InlineQuery,
|
||||||
|
ChosenInlineResult,
|
||||||
|
CallbackQuery,
|
||||||
|
PollUpdate,
|
||||||
|
PollVoteUpdate,
|
||||||
|
UserStatusUpdate,
|
||||||
|
BotStoppedUpdate,
|
||||||
|
BotChatJoinRequestUpdate,
|
||||||
|
} from '@mtcute/client'
|
||||||
|
import { I18nValue } from './types'
|
||||||
|
|
||||||
|
export function createI18nStringsIndex(
|
||||||
|
strings: Record<string, any>
|
||||||
|
): Record<string, I18nValue> {
|
||||||
|
const ret: Record<string, I18nValue> = {}
|
||||||
|
|
||||||
|
function add(obj: Record<string, any>, prefix: string) {
|
||||||
|
for (const key in obj) {
|
||||||
|
const val = obj[key]
|
||||||
|
|
||||||
|
if (typeof val === 'object') {
|
||||||
|
add(val, prefix + key + '.')
|
||||||
|
} else {
|
||||||
|
ret[prefix + key] = val
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
add(strings, '')
|
||||||
|
|
||||||
|
return ret
|
||||||
|
}
|
||||||
|
|
||||||
|
export function extractLanguageFromUpdate(
|
||||||
|
update: ParsedUpdate['data']
|
||||||
|
): string | null | undefined {
|
||||||
|
switch (update.constructor) {
|
||||||
|
case Message:
|
||||||
|
// if sender is Chat it will just be undefined
|
||||||
|
return ((update as Message).sender as User).language
|
||||||
|
case ChatMemberUpdate:
|
||||||
|
case InlineQuery:
|
||||||
|
case ChosenInlineResult:
|
||||||
|
case CallbackQuery:
|
||||||
|
case PollVoteUpdate:
|
||||||
|
case BotStoppedUpdate:
|
||||||
|
case BotChatJoinRequestUpdate:
|
||||||
|
return (
|
||||||
|
update as
|
||||||
|
| ChatMemberUpdate
|
||||||
|
| InlineQuery
|
||||||
|
| ChosenInlineResult
|
||||||
|
| CallbackQuery
|
||||||
|
| PollVoteUpdate
|
||||||
|
| BotStoppedUpdate
|
||||||
|
| BotChatJoinRequestUpdate
|
||||||
|
).user.language
|
||||||
|
}
|
||||||
|
|
||||||
|
return null
|
||||||
|
}
|
94
packages/i18n/tests/i18n.spec.ts
Normal file
94
packages/i18n/tests/i18n.spec.ts
Normal file
|
@ -0,0 +1,94 @@
|
||||||
|
import { describe, it } from 'mocha'
|
||||||
|
import { expect } from 'chai'
|
||||||
|
import { createMtcuteI18n } from '../src'
|
||||||
|
import { OtherLanguageWrap } from '../src/types'
|
||||||
|
import { Message, PeersIndex } from '@mtcute/client'
|
||||||
|
|
||||||
|
describe('i18n', () => {
|
||||||
|
const en = {
|
||||||
|
direct: 'Hello',
|
||||||
|
fn: () => 'World',
|
||||||
|
withArgs: (name: string) => `Welcome ${name}`,
|
||||||
|
withArgsObj: ({ name }: { name: string }) => `Welcome ${name}`,
|
||||||
|
nested: {
|
||||||
|
string: 'Hello',
|
||||||
|
nested: {
|
||||||
|
fn: () => 'Hello',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
const ru: OtherLanguageWrap<typeof en> = {
|
||||||
|
direct: 'Привет',
|
||||||
|
// fn: () => 'World',
|
||||||
|
withArgs: (name: string) => `Привет ${name}`,
|
||||||
|
// withArgsObj: ({ name }: { name: string }) => `Welcome ${name}`,
|
||||||
|
nested: {
|
||||||
|
// string: 'Hello',
|
||||||
|
nested: {
|
||||||
|
fn: 'Привет',
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const tr = createMtcuteI18n({
|
||||||
|
primaryLanguage: {
|
||||||
|
name: 'en',
|
||||||
|
strings: en,
|
||||||
|
},
|
||||||
|
otherLanguages: { ru },
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should work with direct string', () => {
|
||||||
|
expect(tr('en', 'direct')).to.equal('Hello')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should work with function without args', () => {
|
||||||
|
expect(tr('en', 'fn')).to.equal('World')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should work with function with args', () => {
|
||||||
|
expect(tr('en', 'withArgs', '')).to.equal('Welcome ')
|
||||||
|
expect(tr('en', 'withArgs', 'John')).to.equal('Welcome John')
|
||||||
|
expect(tr('en', 'withArgsObj', { name: 'John' })).to.equal(
|
||||||
|
'Welcome John'
|
||||||
|
)
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should work with nested values', () => {
|
||||||
|
expect(tr('en', 'nested.string')).to.equal('Hello')
|
||||||
|
expect(tr('en', 'nested.nested.fn')).to.equal('Hello')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should work with other languages', () => {
|
||||||
|
expect(tr('ru', 'direct')).to.equal('Привет')
|
||||||
|
expect(tr('ru', 'withArgs', 'Ваня')).to.equal('Привет Ваня')
|
||||||
|
expect(tr('ru', 'nested.nested.fn')).to.equal('Привет')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fallback to primary language when string is not translated', () => {
|
||||||
|
expect(tr('ru', 'fn')).to.equal('World')
|
||||||
|
expect(tr('ru', 'withArgsObj', { name: 'Ваня' })).to.equal(
|
||||||
|
'Welcome Ваня'
|
||||||
|
)
|
||||||
|
expect(tr('ru', 'nested.string')).to.equal('Hello')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should fallback to primary language when language is not available', () => {
|
||||||
|
expect(tr('kz', 'direct')).to.equal('Hello')
|
||||||
|
expect(tr(null, 'direct')).to.equal('Hello')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('should parse language from a message', () => {
|
||||||
|
const message = new Message(
|
||||||
|
null as any,
|
||||||
|
{ _: 'message', peerId: { _: 'peerUser', userId: 1 } } as any,
|
||||||
|
PeersIndex.from({
|
||||||
|
users: [
|
||||||
|
{ _: 'user', id: 1, firstName: 'Пыня', langCode: 'ru' },
|
||||||
|
],
|
||||||
|
})
|
||||||
|
)
|
||||||
|
|
||||||
|
expect(tr(message, 'direct')).to.equal('Привет')
|
||||||
|
})
|
||||||
|
})
|
37
packages/i18n/tests/types.ts
Normal file
37
packages/i18n/tests/types.ts
Normal file
|
@ -0,0 +1,37 @@
|
||||||
|
/* eslint-disable */
|
||||||
|
// This is a test for TypeScript typings
|
||||||
|
// This file is never executed, only compiled
|
||||||
|
|
||||||
|
import { Message } from '@mtcute/client'
|
||||||
|
import { createMtcuteI18n } from '../src'
|
||||||
|
import { OtherLanguageWrap } from '../src/types'
|
||||||
|
|
||||||
|
const en = {
|
||||||
|
basic: {
|
||||||
|
hello: 'Hello',
|
||||||
|
world: () => 'World',
|
||||||
|
welcome: (name: string) => `Welcome ${name}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const ru: OtherLanguageWrap<typeof en> = {
|
||||||
|
basic: {
|
||||||
|
hello: 'Привет',
|
||||||
|
// world: () => 'Мир',
|
||||||
|
welcome: (name: string) => `Привет ${name}`,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
const tr = createMtcuteI18n({
|
||||||
|
primaryLanguage: {
|
||||||
|
name: 'en',
|
||||||
|
strings: en,
|
||||||
|
},
|
||||||
|
otherLanguages: { ru },
|
||||||
|
})
|
||||||
|
|
||||||
|
declare const ref: Message
|
||||||
|
|
||||||
|
const a = tr(ref, 'basic.hello')
|
||||||
|
const b = tr('ru', 'basic.world') // will fallback to en
|
||||||
|
const c = tr(null, 'basic.welcome', 'John')
|
19
packages/i18n/tsconfig.json
Normal file
19
packages/i18n/tsconfig.json
Normal file
|
@ -0,0 +1,19 @@
|
||||||
|
{
|
||||||
|
"extends": "../../tsconfig.json",
|
||||||
|
"compilerOptions": {
|
||||||
|
"outDir": "./dist"
|
||||||
|
},
|
||||||
|
"include": [
|
||||||
|
"./src"
|
||||||
|
],
|
||||||
|
"typedocOptions": {
|
||||||
|
"name": "@mtcute/html-parser",
|
||||||
|
"includeVersion": true,
|
||||||
|
"out": "../../docs/packages/html-parser",
|
||||||
|
"listInvalidSymbolLinks": true,
|
||||||
|
"excludePrivate": true,
|
||||||
|
"entryPoints": [
|
||||||
|
"./src/index.ts"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,4 +1,4 @@
|
||||||
lockfileVersion: 5.4
|
lockfileVersion: 5.3
|
||||||
|
|
||||||
importers:
|
importers:
|
||||||
|
|
||||||
|
@ -34,8 +34,8 @@ importers:
|
||||||
'@types/node': 14.18.16
|
'@types/node': 14.18.16
|
||||||
'@types/node-forge': 1.0.2
|
'@types/node-forge': 1.0.2
|
||||||
'@types/ws': 7.4.7
|
'@types/ws': 7.4.7
|
||||||
'@typescript-eslint/eslint-plugin': 4.33.0_3ekaj7j3owlolnuhj3ykrb7u7i
|
'@typescript-eslint/eslint-plugin': 4.33.0_d91404fd3b7596e5b6874ef0a887f4fa
|
||||||
'@typescript-eslint/parser': 4.33.0_hxadhbs2xogijvk7vq4t2azzbu
|
'@typescript-eslint/parser': 4.33.0_eslint@7.32.0+typescript@4.7.4
|
||||||
chai: 4.3.6
|
chai: 4.3.6
|
||||||
dotenv-flow: 3.2.0
|
dotenv-flow: 3.2.0
|
||||||
eslint: 7.32.0
|
eslint: 7.32.0
|
||||||
|
@ -47,7 +47,7 @@ importers:
|
||||||
prettier: 2.6.2
|
prettier: 2.6.2
|
||||||
rimraf: 3.0.2
|
rimraf: 3.0.2
|
||||||
semver: 7.3.7
|
semver: 7.3.7
|
||||||
ts-node: 10.8.1_n4ne3vfoqubxgiypogr36fpdje
|
ts-node: 10.8.1_6f1a4dd4ae850373230f71a3bf15e349
|
||||||
typedoc: 0.23.2_typescript@4.7.4
|
typedoc: 0.23.2_typescript@4.7.4
|
||||||
typescript: 4.7.4
|
typescript: 4.7.4
|
||||||
|
|
||||||
|
@ -153,6 +153,12 @@ importers:
|
||||||
dependencies:
|
dependencies:
|
||||||
'@mtcute/core': link:../core
|
'@mtcute/core': link:../core
|
||||||
|
|
||||||
|
packages/i18n:
|
||||||
|
specifiers:
|
||||||
|
'@mtcute/client': workspace:^1.0.0
|
||||||
|
devDependencies:
|
||||||
|
'@mtcute/client': link:../client
|
||||||
|
|
||||||
packages/markdown-parser:
|
packages/markdown-parser:
|
||||||
specifiers:
|
specifiers:
|
||||||
'@mtcute/client': workspace:^1.0.0
|
'@mtcute/client': workspace:^1.0.0
|
||||||
|
@ -691,7 +697,7 @@ packages:
|
||||||
'@types/node': 14.18.16
|
'@types/node': 14.18.16
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/eslint-plugin/4.33.0_3ekaj7j3owlolnuhj3ykrb7u7i:
|
/@typescript-eslint/eslint-plugin/4.33.0_d91404fd3b7596e5b6874ef0a887f4fa:
|
||||||
resolution: {integrity: sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==}
|
resolution: {integrity: sha512-aINiAxGVdOl1eJyVjaWn/YcVAq4Gi/Yo35qHGCnqbWVz61g39D0h23veY/MA0rFFGfxK7TySg2uwDeNv+JgVpg==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -702,8 +708,8 @@ packages:
|
||||||
typescript:
|
typescript:
|
||||||
optional: true
|
optional: true
|
||||||
dependencies:
|
dependencies:
|
||||||
'@typescript-eslint/experimental-utils': 4.33.0_hxadhbs2xogijvk7vq4t2azzbu
|
'@typescript-eslint/experimental-utils': 4.33.0_eslint@7.32.0+typescript@4.7.4
|
||||||
'@typescript-eslint/parser': 4.33.0_hxadhbs2xogijvk7vq4t2azzbu
|
'@typescript-eslint/parser': 4.33.0_eslint@7.32.0+typescript@4.7.4
|
||||||
'@typescript-eslint/scope-manager': 4.33.0
|
'@typescript-eslint/scope-manager': 4.33.0
|
||||||
debug: 4.3.4
|
debug: 4.3.4
|
||||||
eslint: 7.32.0
|
eslint: 7.32.0
|
||||||
|
@ -717,7 +723,7 @@ packages:
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/experimental-utils/4.33.0_hxadhbs2xogijvk7vq4t2azzbu:
|
/@typescript-eslint/experimental-utils/4.33.0_eslint@7.32.0+typescript@4.7.4:
|
||||||
resolution: {integrity: sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==}
|
resolution: {integrity: sha512-zeQjOoES5JFjTnAhI5QY7ZviczMzDptls15GFsI6jyUOq0kOf9+WonkhtlIhh0RgHRnqj5gdNxW5j1EvAyYg6Q==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -735,7 +741,7 @@ packages:
|
||||||
- typescript
|
- typescript
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/@typescript-eslint/parser/4.33.0_hxadhbs2xogijvk7vq4t2azzbu:
|
/@typescript-eslint/parser/4.33.0_eslint@7.32.0+typescript@4.7.4:
|
||||||
resolution: {integrity: sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==}
|
resolution: {integrity: sha512-ZohdsbXadjGBSK0/r+d87X0SBmKzOq4/S5nzK6SBgJspFo9/CUDJ7hjayuze+JK7CZQLDMroqytp7pOcFKTxZA==}
|
||||||
engines: {node: ^10.12.0 || >=12.0.0}
|
engines: {node: ^10.12.0 || >=12.0.0}
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
@ -1083,8 +1089,6 @@ packages:
|
||||||
ssri: 9.0.0
|
ssri: 9.0.0
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
unique-filename: 1.1.1
|
unique-filename: 1.1.1
|
||||||
transitivePeerDependencies:
|
|
||||||
- bluebird
|
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/caching-transform/4.0.0:
|
/caching-transform/4.0.0:
|
||||||
|
@ -2353,7 +2357,6 @@ packages:
|
||||||
socks-proxy-agent: 6.2.0
|
socks-proxy-agent: 6.2.0
|
||||||
ssri: 9.0.0
|
ssri: 9.0.0
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bluebird
|
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
@ -2581,7 +2584,6 @@ packages:
|
||||||
tar: 6.1.11
|
tar: 6.1.11
|
||||||
which: 2.0.2
|
which: 2.0.2
|
||||||
transitivePeerDependencies:
|
transitivePeerDependencies:
|
||||||
- bluebird
|
|
||||||
- supports-color
|
- supports-color
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
|
@ -2874,11 +2876,6 @@ packages:
|
||||||
|
|
||||||
/promise-inflight/1.0.1:
|
/promise-inflight/1.0.1:
|
||||||
resolution: {integrity: sha1-mEcocL8igTL8vdhoEputEsPAKeM=}
|
resolution: {integrity: sha1-mEcocL8igTL8vdhoEputEsPAKeM=}
|
||||||
peerDependencies:
|
|
||||||
bluebird: '*'
|
|
||||||
peerDependenciesMeta:
|
|
||||||
bluebird:
|
|
||||||
optional: true
|
|
||||||
dev: false
|
dev: false
|
||||||
|
|
||||||
/promise-retry/2.0.1:
|
/promise-retry/2.0.1:
|
||||||
|
@ -3318,7 +3315,7 @@ packages:
|
||||||
resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=}
|
resolution: {integrity: sha1-gYT9NH2snNwYWZLzpmIuFLnZq2o=}
|
||||||
dev: true
|
dev: true
|
||||||
|
|
||||||
/ts-node/10.8.1_n4ne3vfoqubxgiypogr36fpdje:
|
/ts-node/10.8.1_6f1a4dd4ae850373230f71a3bf15e349:
|
||||||
resolution: {integrity: sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==}
|
resolution: {integrity: sha512-Wwsnao4DQoJsN034wePSg5nZiw4YKXf56mPIAeD6wVmiv+RytNSWqc2f3fKvcUoV+Yn2+yocD71VOfQHbmVX4g==}
|
||||||
hasBin: true
|
hasBin: true
|
||||||
peerDependencies:
|
peerDependencies:
|
||||||
|
|
Loading…
Reference in a new issue