feat(core/cache): support cache (#876)
* feat(core/cache): support cache * build(create-nocobase-app): remove --cache-store-package cli option * perf(core/cache): modify default cache config and remove unnecessary logic code (cherry picked from commit 6e6086de7a908f38fe516e5340cb2154229c3843) # Conflicts: # packages/core/server/src/application.ts # packages/core/server/src/helper.ts
This commit is contained in:
parent
3082a7d6f8
commit
92fda15efd
@ -27,6 +27,10 @@ DB_STORAGE=storage/db/nocobase.sqlite
|
|||||||
# DB_PASSWORD=nocobase
|
# DB_PASSWORD=nocobase
|
||||||
# DB_LOGGING=on
|
# DB_LOGGING=on
|
||||||
|
|
||||||
|
################# CACHE #################
|
||||||
|
# default is memory cache, when develop mode,code's change will be clear memory cache, so can use 'cache-manager-fs-hash'
|
||||||
|
# CACHE_CONFIG={"storePackage":"cache-manager-fs-hash","ttl":86400,"max":1000}
|
||||||
|
|
||||||
################# STORAGE (Initialization only) #################
|
################# STORAGE (Initialization only) #################
|
||||||
|
|
||||||
INIT_ROOT_EMAIL=admin@nocobase.com
|
INIT_ROOT_EMAIL=admin@nocobase.com
|
||||||
|
3
.gitignore
vendored
3
.gitignore
vendored
@ -17,4 +17,5 @@ coverage
|
|||||||
docs-dist/
|
docs-dist/
|
||||||
.npmrc
|
.npmrc
|
||||||
dist/
|
dist/
|
||||||
docker/**/storage
|
docker/**/storage
|
||||||
|
cache/diskstore-*
|
||||||
|
5
packages/app/server/src/config/cache.ts
Normal file
5
packages/app/server/src/config/cache.ts
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
import { createDefaultCacheConfig } from '@nocobase/cache';
|
||||||
|
|
||||||
|
const cacheConfig = !!process.env.CACHE_CONFIG ? JSON.parse(process.env.CACHE_CONFIG) : createDefaultCacheConfig();
|
||||||
|
|
||||||
|
export default cacheConfig;
|
@ -1,9 +1,11 @@
|
|||||||
import database from './database';
|
import database from './database';
|
||||||
import plugins from './plugins';
|
import plugins from './plugins';
|
||||||
import resourcer from './resourcer';
|
import resourcer from './resourcer';
|
||||||
|
import cache from './cache';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
database,
|
database,
|
||||||
resourcer,
|
resourcer,
|
||||||
plugins,
|
plugins,
|
||||||
|
cache,
|
||||||
};
|
};
|
||||||
|
@ -13,7 +13,8 @@
|
|||||||
"types": "./lib/index.d.ts",
|
"types": "./lib/index.d.ts",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"@nocobase/database": "0.7.4-alpha.7",
|
"@nocobase/database": "0.7.4-alpha.7",
|
||||||
"@nocobase/resourcer": "0.7.4-alpha.7"
|
"@nocobase/resourcer": "0.7.4-alpha.7",
|
||||||
|
"@nocobase/cache": "0.7.4-alpha.7"
|
||||||
},
|
},
|
||||||
"repository": {
|
"repository": {
|
||||||
"type": "git",
|
"type": "git",
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
import Koa from 'koa';
|
import Koa from 'koa';
|
||||||
import { Database } from '@nocobase/database';
|
import { Database } from '@nocobase/database';
|
||||||
import { Action } from '@nocobase/resourcer';
|
import { Action } from '@nocobase/resourcer';
|
||||||
|
import { Cache } from '@nocobase/cache';
|
||||||
import lodash from 'lodash';
|
import lodash from 'lodash';
|
||||||
import * as actions from './actions';
|
import * as actions from './actions';
|
||||||
|
|
||||||
@ -10,9 +11,11 @@ export type Next = () => Promise<any>;
|
|||||||
|
|
||||||
export interface Context extends Koa.Context {
|
export interface Context extends Koa.Context {
|
||||||
db: Database;
|
db: Database;
|
||||||
|
cache: Cache;
|
||||||
action: Action;
|
action: Action;
|
||||||
body: any;
|
body: any;
|
||||||
app: any;
|
app: any;
|
||||||
|
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
8
packages/core/cache/.npmignore
vendored
Normal file
8
packages/core/cache/.npmignore
vendored
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
node_modules
|
||||||
|
*.log
|
||||||
|
docs
|
||||||
|
__tests__
|
||||||
|
jest.config.js
|
||||||
|
tsconfig.json
|
||||||
|
src
|
||||||
|
.fatherrc.ts
|
26
packages/core/cache/package.json
vendored
Normal file
26
packages/core/cache/package.json
vendored
Normal file
@ -0,0 +1,26 @@
|
|||||||
|
{
|
||||||
|
"name": "@nocobase/cache",
|
||||||
|
"version": "0.7.4-alpha.7",
|
||||||
|
"description": "",
|
||||||
|
"license": "Apache-2.0",
|
||||||
|
"licenses": [
|
||||||
|
{
|
||||||
|
"type": "Apache-2.0",
|
||||||
|
"url": "http://www.apache.org/licenses/LICENSE-2.0"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"main": "./lib/index.js",
|
||||||
|
"types": "./lib/index.d.ts",
|
||||||
|
"dependencies": {
|
||||||
|
"cache-manager": "^4.1.0"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/cache-manager": "^4.0.2",
|
||||||
|
"cache-manager-fs-hash": "^1.0.0"
|
||||||
|
},
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "git+https://github.com/nocobase/nocobase.git",
|
||||||
|
"directory": "packages/cache"
|
||||||
|
}
|
||||||
|
}
|
74
packages/core/cache/src/__tests__/index.test.ts
vendored
Normal file
74
packages/core/cache/src/__tests__/index.test.ts
vendored
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
import { createCache, createDefaultCacheConfig } from '@nocobase/cache';
|
||||||
|
|
||||||
|
export function sleep(ms: number) {
|
||||||
|
return new Promise((resolve) => {
|
||||||
|
setTimeout(resolve, ms);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
describe('cache', () => {
|
||||||
|
it('createCache-with-mem', async () => {
|
||||||
|
const cacheConfig = createDefaultCacheConfig();
|
||||||
|
cacheConfig.ttl = 1;
|
||||||
|
const cache = createCache(cacheConfig);
|
||||||
|
await cache.set('name', 'Emma');
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(100);
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(1005);
|
||||||
|
expect(await cache.get('name')).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('createCache-with-single-config', async () => {
|
||||||
|
let cacheConfigStr =
|
||||||
|
'{"store":"memory","ttl":1,"max":10}';
|
||||||
|
let cacheConfig = JSON.parse(cacheConfigStr);
|
||||||
|
let cache = createCache(cacheConfig);
|
||||||
|
await cache.set('name', 'Emma');
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(100);
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(1005);
|
||||||
|
expect(await cache.get('name')).toBeUndefined();
|
||||||
|
|
||||||
|
cacheConfigStr =
|
||||||
|
'[{"store":"memory","ttl":1,"max":10}]';
|
||||||
|
cacheConfig = JSON.parse(cacheConfigStr);
|
||||||
|
cache = createCache(cacheConfig);
|
||||||
|
await cache.set('name', 'Emma');
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(100);
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(1005);
|
||||||
|
expect(await cache.get('name')).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('createCache-with-default-cache-manager-fs-hash', async () => {
|
||||||
|
const cacheConfig = createDefaultCacheConfig();
|
||||||
|
cacheConfig.ttl = 1;
|
||||||
|
cacheConfig.storePackage = 'cache-manager-fs-hash';
|
||||||
|
const cache = createCache(cacheConfig);
|
||||||
|
await cache.set('name', 'Emma');
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(100);
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(1005);
|
||||||
|
expect(await cache.get('name')).toBeUndefined();
|
||||||
|
});
|
||||||
|
|
||||||
|
it('createCache-multi-cache', async () => {
|
||||||
|
const cacheConfigStr =
|
||||||
|
'[{"store":"memory","ttl":1,"max":10},{"storePackage":"cache-manager-fs-hash","ttl":10,"max":100}]';
|
||||||
|
const cacheConfig = JSON.parse(cacheConfigStr);
|
||||||
|
const cache = createCache(cacheConfig);
|
||||||
|
|
||||||
|
await cache.set('name', 'Emma');
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(1005);
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(5000);
|
||||||
|
expect(await cache.get('name')).toEqual('Emma');
|
||||||
|
await sleep(5000);
|
||||||
|
expect(await cache.get('name')).toBeUndefined();
|
||||||
|
});
|
||||||
|
});
|
70
packages/core/cache/src/index.ts
vendored
Normal file
70
packages/core/cache/src/index.ts
vendored
Normal file
@ -0,0 +1,70 @@
|
|||||||
|
import { CacheOptions, caching, CachingConfig, multiCaching, StoreConfig, WrapArgsType } from 'cache-manager';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* be used for create cache {@link createCache}
|
||||||
|
*/
|
||||||
|
export type ICacheConfig = StoreConfig &
|
||||||
|
CacheOptions & {
|
||||||
|
// every storeConfig init a store instance
|
||||||
|
storePackage?: string;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create a default cache config object
|
||||||
|
* @returns {ICacheConfig}
|
||||||
|
*/
|
||||||
|
export function createDefaultCacheConfig(): ICacheConfig {
|
||||||
|
return {
|
||||||
|
ttl: 86400, // seconds
|
||||||
|
max: 1000,
|
||||||
|
store: 'memory',
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* cache and multi cache common method and only keep promise method
|
||||||
|
*/
|
||||||
|
export interface Cache {
|
||||||
|
set<T>(key: string, value: T, options?: CachingConfig): Promise<T>;
|
||||||
|
|
||||||
|
set<T>(key: string, value: T, ttl: number): Promise<T>;
|
||||||
|
|
||||||
|
wrap<T>(...args: WrapArgsType<T>[]): Promise<T>;
|
||||||
|
|
||||||
|
get<T>(key: string): Promise<T | undefined>;
|
||||||
|
|
||||||
|
del(key: string): Promise<any>;
|
||||||
|
|
||||||
|
reset(): Promise<void>;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* create cache
|
||||||
|
* <br/> if cacheConfig is array and length gt 1 then will be return multi cache, else will be return cache
|
||||||
|
* @param {ICacheConfig | ICacheConfig[]} cacheConfig
|
||||||
|
* @returns {Cache}
|
||||||
|
*/
|
||||||
|
export function createCache(cacheConfig: ICacheConfig | ICacheConfig[] = createDefaultCacheConfig()): Cache {
|
||||||
|
if (Array.isArray(cacheConfig)) {
|
||||||
|
// multi cache
|
||||||
|
if (cacheConfig.length === 1) {
|
||||||
|
return createCacheByICacheConfig(cacheConfig[0]);
|
||||||
|
} else {
|
||||||
|
let caches = [];
|
||||||
|
for (const cacheConfigEle of cacheConfig) {
|
||||||
|
caches.push(createCacheByICacheConfig(cacheConfigEle));
|
||||||
|
}
|
||||||
|
return multiCaching(caches) as Cache;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
return createCacheByICacheConfig(cacheConfig);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function createCacheByICacheConfig(cacheConfig: ICacheConfig): Cache {
|
||||||
|
// if storePackage exist then load storePackage and instead store
|
||||||
|
if (cacheConfig.storePackage) {
|
||||||
|
cacheConfig.store = require(cacheConfig.storePackage);
|
||||||
|
}
|
||||||
|
return caching(cacheConfig);
|
||||||
|
}
|
@ -1,6 +1,6 @@
|
|||||||
import { promisify } from 'util';
|
|
||||||
import { ACL } from '@nocobase/acl';
|
import { ACL } from '@nocobase/acl';
|
||||||
import { registerActions } from '@nocobase/actions';
|
import { registerActions } from '@nocobase/actions';
|
||||||
|
import { Cache, createCache, ICacheConfig } from '@nocobase/cache';
|
||||||
import Database, { Collection, CollectionOptions, IDatabaseOptions } from '@nocobase/database';
|
import Database, { Collection, CollectionOptions, IDatabaseOptions } from '@nocobase/database';
|
||||||
import Resourcer, { ResourceOptions } from '@nocobase/resourcer';
|
import Resourcer, { ResourceOptions } from '@nocobase/resourcer';
|
||||||
import { applyMixins, AsyncEmitter, Toposort, ToposortOptions } from '@nocobase/utils';
|
import { applyMixins, AsyncEmitter, Toposort, ToposortOptions } from '@nocobase/utils';
|
||||||
@ -11,12 +11,14 @@ import Koa, { DefaultContext as KoaDefaultContext, DefaultState as KoaDefaultSta
|
|||||||
import compose from 'koa-compose';
|
import compose from 'koa-compose';
|
||||||
import { isBoolean } from 'lodash';
|
import { isBoolean } from 'lodash';
|
||||||
import semver from 'semver';
|
import semver from 'semver';
|
||||||
|
import { promisify } from 'util';
|
||||||
import { createACL } from './acl';
|
import { createACL } from './acl';
|
||||||
import { AppManager } from './app-manager';
|
import { AppManager } from './app-manager';
|
||||||
import { registerCli } from './commands';
|
import { registerCli } from './commands';
|
||||||
import { createI18n, createResourcer, registerMiddlewares } from './helper';
|
import { createI18n, createResourcer, registerMiddlewares } from './helper';
|
||||||
import { Plugin } from './plugin';
|
import { Plugin } from './plugin';
|
||||||
import { InstallOptions, PluginManager } from './plugin-manager';
|
import { InstallOptions, PluginManager } from './plugin-manager';
|
||||||
|
|
||||||
const packageJson = require('../package.json');
|
const packageJson = require('../package.json');
|
||||||
|
|
||||||
export type PluginConfiguration = string | [string, any];
|
export type PluginConfiguration = string | [string, any];
|
||||||
@ -27,6 +29,7 @@ export interface ResourcerOptions {
|
|||||||
|
|
||||||
export interface ApplicationOptions {
|
export interface ApplicationOptions {
|
||||||
database?: IDatabaseOptions | Database;
|
database?: IDatabaseOptions | Database;
|
||||||
|
cache?: ICacheConfig | ICacheConfig[];
|
||||||
resourcer?: ResourcerOptions;
|
resourcer?: ResourcerOptions;
|
||||||
bodyParser?: any;
|
bodyParser?: any;
|
||||||
cors?: any;
|
cors?: any;
|
||||||
@ -39,11 +42,13 @@ export interface ApplicationOptions {
|
|||||||
|
|
||||||
export interface DefaultState extends KoaDefaultState {
|
export interface DefaultState extends KoaDefaultState {
|
||||||
currentUser?: any;
|
currentUser?: any;
|
||||||
|
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface DefaultContext extends KoaDefaultContext {
|
export interface DefaultContext extends KoaDefaultContext {
|
||||||
db: Database;
|
db: Database;
|
||||||
|
cache: Cache;
|
||||||
resourcer: Resourcer;
|
resourcer: Resourcer;
|
||||||
i18n: any;
|
i18n: any;
|
||||||
[key: string]: any;
|
[key: string]: any;
|
||||||
@ -134,6 +139,8 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
|||||||
|
|
||||||
protected _resourcer: Resourcer;
|
protected _resourcer: Resourcer;
|
||||||
|
|
||||||
|
protected _cache: Cache;
|
||||||
|
|
||||||
protected _cli: Command;
|
protected _cli: Command;
|
||||||
|
|
||||||
protected _i18n: i18n;
|
protected _i18n: i18n;
|
||||||
@ -161,6 +168,10 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
|||||||
return this._db;
|
return this._db;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
get cache() {
|
||||||
|
return this._cache;
|
||||||
|
}
|
||||||
|
|
||||||
get resourcer() {
|
get resourcer() {
|
||||||
return this._resourcer;
|
return this._resourcer;
|
||||||
}
|
}
|
||||||
@ -203,8 +214,10 @@ export class Application<StateT = DefaultState, ContextT = DefaultContext> exten
|
|||||||
this._resourcer = createResourcer(options);
|
this._resourcer = createResourcer(options);
|
||||||
this._cli = new Command('nocobase').usage('[command] [options]');
|
this._cli = new Command('nocobase').usage('[command] [options]');
|
||||||
this._i18n = createI18n(options);
|
this._i18n = createI18n(options);
|
||||||
|
this._cache = createCache(options.cache);
|
||||||
this.context.db = this._db;
|
this.context.db = this._db;
|
||||||
this.context.resourcer = this._resourcer;
|
this.context.resourcer = this._resourcer;
|
||||||
|
this.context.cache = this._cache;
|
||||||
|
|
||||||
this._pm = new PluginManager({
|
this._pm = new PluginManager({
|
||||||
app: this,
|
app: this,
|
||||||
|
48
yarn.lock
48
yarn.lock
@ -4990,6 +4990,11 @@
|
|||||||
"@types/connect" "*"
|
"@types/connect" "*"
|
||||||
"@types/node" "*"
|
"@types/node" "*"
|
||||||
|
|
||||||
|
"@types/cache-manager@^4.0.2":
|
||||||
|
version "4.0.2"
|
||||||
|
resolved "https://registry.npmmirror.com/@types/cache-manager/-/cache-manager-4.0.2.tgz#5e76dd9e7881c23f332c2f48e5f326bd05ba9ac9"
|
||||||
|
integrity sha512-fT5FMdzsiSX0AbgnS5gDvHl2Nco0h5zYyjwDQy4yPC7Ww6DeGMVKPRqIZtg9HOXDV2kkc18SL1B0N8f0BecrCA==
|
||||||
|
|
||||||
"@types/connect@*":
|
"@types/connect@*":
|
||||||
version "3.4.35"
|
version "3.4.35"
|
||||||
resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
|
resolved "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz#5fcf6ae445e4021d1fc2219a4873cc73a3bb2ad1"
|
||||||
@ -6697,6 +6702,11 @@ async-validator@^4.0.2:
|
|||||||
resolved "https://registry.npmjs.org/async-validator/-/async-validator-4.0.7.tgz#034a0fd2103a6b2ebf010da75183bec299247afe"
|
resolved "https://registry.npmjs.org/async-validator/-/async-validator-4.0.7.tgz#034a0fd2103a6b2ebf010da75183bec299247afe"
|
||||||
integrity sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ==
|
integrity sha512-Pj2IR7u8hmUEDOwB++su6baaRi+QvsgajuFB9j95foM1N2gy5HM4z60hfusIO0fBPG5uLAEl6yCJr1jNSVugEQ==
|
||||||
|
|
||||||
|
async@3.2.3, async@^3.2.0, async@~3.2.0:
|
||||||
|
version "3.2.3"
|
||||||
|
resolved "https://registry.npmjs.org/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
|
||||||
|
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
|
||||||
|
|
||||||
async@^2.6.2:
|
async@^2.6.2:
|
||||||
version "2.6.4"
|
version "2.6.4"
|
||||||
resolved "https://registry.npmmirror.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
|
resolved "https://registry.npmmirror.com/async/-/async-2.6.4.tgz#706b7ff6084664cd7eae713f6f965433b5504221"
|
||||||
@ -6711,11 +6721,6 @@ async@^2.6.3, async@~2.6.1:
|
|||||||
dependencies:
|
dependencies:
|
||||||
lodash "^4.17.14"
|
lodash "^4.17.14"
|
||||||
|
|
||||||
async@^3.2.0, async@~3.2.0:
|
|
||||||
version "3.2.3"
|
|
||||||
resolved "https://registry.npmjs.org/async/-/async-3.2.3.tgz#ac53dafd3f4720ee9e8a160628f18ea91df196c9"
|
|
||||||
integrity sha512-spZRyzKL5l5BZQrr/6m/SqFdBN0q3OCI0f9rjfBzCMBIP4p75P620rR3gTmaksNOhmzgdxcaxdNfMy6anrbM0g==
|
|
||||||
|
|
||||||
asynckit@^0.4.0:
|
asynckit@^0.4.0:
|
||||||
version "0.4.0"
|
version "0.4.0"
|
||||||
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
resolved "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
|
||||||
@ -7457,6 +7462,22 @@ cache-content-type@^1.0.0:
|
|||||||
mime-types "^2.1.18"
|
mime-types "^2.1.18"
|
||||||
ylru "^1.2.0"
|
ylru "^1.2.0"
|
||||||
|
|
||||||
|
cache-manager-fs-hash@^1.0.0:
|
||||||
|
version "1.0.0"
|
||||||
|
resolved "https://registry.npmmirror.com/cache-manager-fs-hash/-/cache-manager-fs-hash-1.0.0.tgz#9a3f3fa239c48c54fc6b00575032b72c07dcad99"
|
||||||
|
integrity sha512-fK2vEAhWh7IAzBP+JwUEJkng0OPOxw3ji86SjQS5SWdLx2Cytku6xFNoQK32pedtuae/wBl/jA/X4abiAYHS/Q==
|
||||||
|
dependencies:
|
||||||
|
lockfile "^1.0.4"
|
||||||
|
|
||||||
|
cache-manager@^4.1.0:
|
||||||
|
version "4.1.0"
|
||||||
|
resolved "https://registry.npmmirror.com/cache-manager/-/cache-manager-4.1.0.tgz#aa986421f1c975a862d6de88edb9ab1d30f4bd39"
|
||||||
|
integrity sha512-ZGM6dLxrP65bfOZmcviWMadUOCICqpLs92+P/S5tj8onz+k+tB7Gr+SAgOUHCQtfm2gYEQDHiKeul4+tYPOJ8A==
|
||||||
|
dependencies:
|
||||||
|
async "3.2.3"
|
||||||
|
lodash.clonedeep "^4.5.0"
|
||||||
|
lru-cache "^7.10.1"
|
||||||
|
|
||||||
cacheable-request@^6.0.0:
|
cacheable-request@^6.0.0:
|
||||||
version "6.1.0"
|
version "6.1.0"
|
||||||
resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
|
resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-6.1.0.tgz#20ffb8bd162ba4be11e9567d823db651052ca912"
|
||||||
@ -14504,6 +14525,13 @@ locate-path@^6.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
p-locate "^5.0.0"
|
p-locate "^5.0.0"
|
||||||
|
|
||||||
|
lockfile@^1.0.4:
|
||||||
|
version "1.0.4"
|
||||||
|
resolved "https://registry.npmmirror.com/lockfile/-/lockfile-1.0.4.tgz#07f819d25ae48f87e538e6578b6964a4981a5609"
|
||||||
|
integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==
|
||||||
|
dependencies:
|
||||||
|
signal-exit "^3.0.2"
|
||||||
|
|
||||||
lodash-es@^4.17.11:
|
lodash-es@^4.17.11:
|
||||||
version "4.17.21"
|
version "4.17.21"
|
||||||
resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz#43e626c46e6591b7750beb2b50117390c609e3ee"
|
||||||
@ -14536,6 +14564,11 @@ lodash.clone@4.5.0, lodash.clone@^4.3.2:
|
|||||||
resolved "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6"
|
resolved "https://registry.npmjs.org/lodash.clone/-/lodash.clone-4.5.0.tgz#195870450f5a13192478df4bc3d23d2dea1907b6"
|
||||||
integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=
|
integrity sha1-GVhwRQ9aExkkeN9Lw9I9LeoZB7Y=
|
||||||
|
|
||||||
|
lodash.clonedeep@^4.5.0:
|
||||||
|
version "4.5.0"
|
||||||
|
resolved "https://registry.npmmirror.com/lodash.clonedeep/-/lodash.clonedeep-4.5.0.tgz#e23f3f9c4f8fbdde872529c1071857a086e5ccef"
|
||||||
|
integrity sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==
|
||||||
|
|
||||||
lodash.debounce@^4.0.8:
|
lodash.debounce@^4.0.8:
|
||||||
version "4.0.8"
|
version "4.0.8"
|
||||||
resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
resolved "https://registry.npmjs.org/lodash.debounce/-/lodash.debounce-4.0.8.tgz#82d79bff30a67c4005ffd5e2515300ad9ca4d7af"
|
||||||
@ -14735,6 +14768,11 @@ lru-cache@^6.0.0:
|
|||||||
dependencies:
|
dependencies:
|
||||||
yallist "^4.0.0"
|
yallist "^4.0.0"
|
||||||
|
|
||||||
|
lru-cache@^7.10.1:
|
||||||
|
version "7.14.0"
|
||||||
|
resolved "https://registry.npmmirror.com/lru-cache/-/lru-cache-7.14.0.tgz#21be64954a4680e303a09e9468f880b98a0b3c7f"
|
||||||
|
integrity sha512-EIRtP1GrSJny0dqb50QXRUNBxHJhcpxHC++M5tD7RYbvLLn5KVWKsbyswSSqDuU15UFi3bgTQIY8nhDMeF6aDQ==
|
||||||
|
|
||||||
luxon@^1.28.0:
|
luxon@^1.28.0:
|
||||||
version "1.28.0"
|
version "1.28.0"
|
||||||
resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf"
|
resolved "https://registry.yarnpkg.com/luxon/-/luxon-1.28.0.tgz#e7f96daad3938c06a62de0fb027115d251251fbf"
|
||||||
|
Loading…
Reference in New Issue
Block a user