From 3d4b1c3bbcbefa603a05b0e72014b1a073afff8b Mon Sep 17 00:00:00 2001 From: Tomer Horowitz Date: Thu, 12 Sep 2024 22:20:50 +0300 Subject: [PATCH] chore: Update typescript peer dependency to version 5.5.4 --- package.json | 2 +- src/index.d.ts | 53 +++++++++++++--- src/index.ts | 84 +++++++++++++++++-------- yarn.lock | 167 ++++++++++++++++--------------------------------- 4 files changed, 159 insertions(+), 147 deletions(-) diff --git a/package.json b/package.json index 7f587f2..746dee6 100644 --- a/package.json +++ b/package.json @@ -17,7 +17,7 @@ "xo": "^0.59.3" }, "peerDependencies": { - "typescript": "^5.6.2" + "typescript": "^5.5.4" }, "scripts": { "build": "tsc", diff --git a/src/index.d.ts b/src/index.d.ts index ff3e67a..5cea09f 100644 --- a/src/index.d.ts +++ b/src/index.d.ts @@ -16,12 +16,12 @@ export type SingleOrArray = T | T[]; * Represents a logger object. */ export type Logger = { - trace: (...args: any) => any; - debug: (...args: any) => any; - info: (...args: any) => any; - warn: (...args: any) => any; - error: (...args: any) => any; -} + trace: (...arguments_: any) => any; + debug: (...arguments_: any) => any; + info: (...arguments_: any) => any; + warn: (...arguments_: any) => any; + error: (...arguments_: any) => any; +}; /** * Represents any function that takes any number of arguments and returns any value. @@ -52,8 +52,8 @@ export type ArgumentPaths = SingleOrArray;} & - ({store: FactoryStore; config: FactoryConfig} | {store: Store}); +export type CachedFunctionInitializerOptions = {logger?: Partial} & +({store: FactoryStore; config: FactoryConfig} | {store: Store}); /** * Options for a cached function. @@ -73,4 +73,41 @@ export type CachedFunctionOptions = Partial = { + /** + * The options used to cache the function. + */ + options: CachedFunctionOptions; + /** + * The status of the cache. + * - `'hit'` - The cache was found. + * - `'miss'` - The cache was not found. + */ + status?: CacheStatus; + /** + * The cache key used to store the value. + */ + key?: string; + /** + * The result returned by the function/cache. + */ + result: T; + /** + * Whether the cache `set` operation was called. + */ + created: boolean; }; diff --git a/src/index.ts b/src/index.ts index 0d310eb..a79045b 100644 --- a/src/index.ts +++ b/src/index.ts @@ -3,21 +3,20 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ import _ from 'lodash'; -import { - type Cache, caching, type Store, -} from 'cache-manager'; +import {type Cache, caching, type Store} from 'cache-manager'; import { type CachedFunctionInitializerOptions, type CachedFunctionOptions, type CacheableFunction, type ArgumentPaths, - Logger, + type Logger, + type CachedFunctionResult, } from './index.d'; let cache: Cache | undefined; let logger: Logger = { - info(...args: any) {}, - debug(...args: any) {}, - trace(...args: any) {}, - warn(...args: any) {}, - error(...args: any) {}, + info(...arguments_: any) {}, // eslint-disable-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function + debug(...arguments_: any) {}, // eslint-disable-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function + trace(...arguments_: any) {}, // eslint-disable-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function + warn(...arguments_: any) {}, // eslint-disable-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function + error(...arguments_: any) {}, // eslint-disable-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function }; /** @@ -41,9 +40,9 @@ export async function getOrInitializeCache(options?: CachedFunc logger = options.logger as Logger; } - logger?.trace('Initializing cache'); + logger.trace('Initializing cache'); cache ||= await ('config' in options! ? caching(options.store, options.config) : caching(options!.store)); - logger?.trace('Cache initialized'); + logger.trace('Cache initialized'); return cache as Cache; } @@ -53,7 +52,7 @@ export async function getOrInitializeCache(options?: CachedFunc */ export function resetCache() { cache = undefined; - logger?.warn('You have called resetCache, which is deprecated and basically does nothing. To close any open connections, please retrieve the cache object from getOrInitializeCache and close it directly.'); + logger.warn('You have called resetCache, which is deprecated and basically does nothing. To close any open connections, please retrieve the cache object from getOrInitializeCache and close it directly.'); } /** @@ -66,10 +65,10 @@ export function resetCache() { * @throws {Error} If a path in the selector does not exist in the provided arguments. * @throws {TypeError} If a path in the selector points to a function, which is not serializable. */ -export function selectorToCacheKey(arguments_: Parameters, selector: ArgumentPaths) { +export function selectorToCacheKey(arguments_: Parameters, selector: ArgumentPaths, namespace?: string): string { const selectors = _.castArray(selector); if (selectors.length === 0) { - logger?.trace(arguments_, 'No selectors provided, using the entire arguments object as the cache key'); + logger.trace(arguments_, 'No selectors provided, using the entire arguments object as the cache key'); return JSON.stringify(arguments_); } @@ -85,7 +84,12 @@ export function selectorToCacheKey(arguments_: Para return value; }); + const result = _.zipObject(selectors, values); + if (namespace) { + result.namespace = namespace; + } + return JSON.stringify(result); } @@ -99,34 +103,64 @@ export function selectorToCacheKey(arguments_: Para * @returns A promise that resolves to the result of the function. */ export function cachedFunction(function_: F, options?: CachedFunctionOptions) { - return async (...arguments_: Parameters): Promise> => { + return async (...arguments_: Parameters): Promise | CachedFunctionResult>> => { const cacheOptions = _.merge({}, options ?? {}, function_.cacheOptions ?? {}); if (_.keys(cacheOptions).length === 0) { throw new Error('No cache options provided, either use the @CacheOptions decorator or provide options to cachedFunction directly.'); } - if (!cacheOptions.noCache) { - logger.trace('Cache is disabled, calling the original function directly'); + if (cacheOptions.noCache && cacheOptions.returnRawValue) { + logger.trace('Cache is disabled via `noCache=true`. Calling the original function directly and returning the raw value'); return function_(...arguments_) as ReturnType; } + if (cacheOptions.noCache && !cacheOptions.returnRawValue) { + logger.trace('Cache is disabled via `noCache=true`. Calling the original function directly and returning a `CachedFunctionResult` object'); + return { + result: function_(...arguments_) as ReturnType, + created: false, + options: cacheOptions, + }; + } + const cacheKey = selectorToCacheKey(arguments_, cacheOptions.selector!); const cache = await getOrInitializeCache(options as CachedFunctionInitializerOptions); - logger?.trace({cacheKey}, 'Checking cache'); + logger.trace({cacheKey}, 'Checking cache'); const cacheValue = await cache.get>(cacheKey); - if (!cacheOptions.force && cacheValue !== undefined) { - logger?.trace({cacheKey}, 'Cache hit'); + if (!cacheOptions.force && !_.isNil(cacheValue) && cacheOptions.returnRawValue) { + logger.trace({cacheKey}, 'Cache hit'); return cacheValue; } - logger?.trace({cacheKey}, 'Cache miss'); + if (!cacheOptions.force && !_.isNil(cacheValue) && !cacheOptions.returnRawValue) { + logger.trace({cacheKey}, 'Cache hit'); + return { + key: cacheKey, + result: cacheValue, + status: 'hit', + created: false, + options: cacheOptions, + }; + } + + logger.trace({cacheKey}, 'Cache miss'); const result = await function_(...arguments_) as ReturnType; - logger?.trace({cacheKey}, 'Setting cache'); + logger.trace({cacheKey}, 'Setting cache'); await cache.set(cacheKey, result, cacheOptions.ttl); - logger?.trace({cacheKey}, 'Cache set'); + logger.trace({cacheKey}, 'Cache set'); + + if (cacheOptions.returnRawValue) { + return result; + } - return result; + return { + key: cacheKey, + result, + status: 'miss', + created: true, + options: cacheOptions, + }; }; } @@ -169,7 +203,7 @@ export function CacheOptions( descriptor: TypedPropertyDescriptor, ): any => { if (!descriptor.value) { - logger?.warn('CacheOptions decorator is only supported on methods'); + logger.warn('CacheOptions decorator is only supported on methods'); return; } diff --git a/yarn.lock b/yarn.lock index 4776d42..bd2138a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2236,18 +2236,17 @@ __metadata: linkType: hard "@stylistic/eslint-plugin@npm:^2.6.1": - version: 2.7.2 - resolution: "@stylistic/eslint-plugin@npm:2.7.2" + version: 2.8.0 + resolution: "@stylistic/eslint-plugin@npm:2.8.0" dependencies: - "@types/eslint": "npm:^9.6.1" - "@typescript-eslint/utils": "npm:^8.3.0" + "@typescript-eslint/utils": "npm:^8.4.0" eslint-visitor-keys: "npm:^4.0.0" espree: "npm:^10.1.0" estraverse: "npm:^5.3.0" picomatch: "npm:^4.0.2" peerDependencies: eslint: ">=8.40.0" - checksum: 10c0/266bd65bdc252e4562e8c1c3819bafcec9705cebc3c4f41ce6c2ed3deeaa0ed6ccdffd00a108f51422ae201d32618bd1055cd4977aabccbf8a729fbca1e2bf1e + checksum: 10c0/e85fc3ecad6df8b18e4c8e25ae4dfb330565efe5b91176fa84ec0fb636f07b1efa75eddc91fb36d146fc983a3538efc294f04d4b5636b3a708da123c70470671 languageName: node linkType: hard @@ -2278,16 +2277,6 @@ __metadata: languageName: node linkType: hard -"@types/eslint@npm:^9.6.1": - version: 9.6.1 - resolution: "@types/eslint@npm:9.6.1" - dependencies: - "@types/estree": "npm:*" - "@types/json-schema": "npm:*" - checksum: 10c0/69ba24fee600d1e4c5abe0df086c1a4d798abf13792d8cfab912d76817fe1a894359a1518557d21237fbaf6eda93c5ab9309143dee4c59ef54336d1b3570420e - languageName: node - linkType: hard - "@types/estree@npm:*": version: 1.0.5 resolution: "@types/estree@npm:1.0.5" @@ -2441,13 +2430,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:8.4.0": - version: 8.4.0 - resolution: "@typescript-eslint/scope-manager@npm:8.4.0" +"@typescript-eslint/scope-manager@npm:8.5.0": + version: 8.5.0 + resolution: "@typescript-eslint/scope-manager@npm:8.5.0" dependencies: - "@typescript-eslint/types": "npm:8.4.0" - "@typescript-eslint/visitor-keys": "npm:8.4.0" - checksum: 10c0/95188c663df7db106529c6b93c4c7c61647ed34ab6dd48114e41ddf49140ff606c5501ce2ae451a988ec49b5d3874ea96ff212fc102802327b10affd2ff80a37 + "@typescript-eslint/types": "npm:8.5.0" + "@typescript-eslint/visitor-keys": "npm:8.5.0" + checksum: 10c0/868602f9324a6e15fcae017acd3b0832e9f2c8c8cd315667df37c2e7c765cda5fba7c4bede931f32cc04819ba97cf74a5fddb085c6f1c7993f1fb085ba126422 languageName: node linkType: hard @@ -2499,10 +2488,10 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/types@npm:8.4.0": - version: 8.4.0 - resolution: "@typescript-eslint/types@npm:8.4.0" - checksum: 10c0/15e09ced84827c349553530a31822f06ae5bad456c03d561b7d0c64b6ad9b5d7ca795e030bd93e65d5a2cd41bfde36ed08dcd2ff9feaa8b60a67080827f47ecb +"@typescript-eslint/types@npm:8.5.0": + version: 8.5.0 + resolution: "@typescript-eslint/types@npm:8.5.0" + checksum: 10c0/f0b666b5c001b9779bfd9e4c7d031843d07264429d5bcf5d636f26f96cd5d949a33f5d6a645b8d74b93daf565a468476a6a4935dd7135a200250fb03acbe4988 languageName: node linkType: hard @@ -2544,12 +2533,12 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:8.4.0": - version: 8.4.0 - resolution: "@typescript-eslint/typescript-estree@npm:8.4.0" +"@typescript-eslint/typescript-estree@npm:8.5.0": + version: 8.5.0 + resolution: "@typescript-eslint/typescript-estree@npm:8.5.0" dependencies: - "@typescript-eslint/types": "npm:8.4.0" - "@typescript-eslint/visitor-keys": "npm:8.4.0" + "@typescript-eslint/types": "npm:8.5.0" + "@typescript-eslint/visitor-keys": "npm:8.5.0" debug: "npm:^4.3.4" fast-glob: "npm:^3.3.2" is-glob: "npm:^4.0.3" @@ -2559,7 +2548,7 @@ __metadata: peerDependenciesMeta: typescript: optional: true - checksum: 10c0/170702b024121cff9268f53de8054796b0ce025f9a78d6f2bc850a360e5f3f7032ba3ee9d4b7392726308273a5f3ade5ab31b1788b504b514bc15afc07302b37 + checksum: 10c0/f62f03d0c5dc57b2b54dbe1cbd027966f774f241279655f46c64145abb54b765176a0cd40447583ba56ada306181da9a82e39b777c78128e105e4ea98c609350 languageName: node linkType: hard @@ -2591,17 +2580,17 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/utils@npm:^8.3.0": - version: 8.4.0 - resolution: "@typescript-eslint/utils@npm:8.4.0" +"@typescript-eslint/utils@npm:^8.4.0": + version: 8.5.0 + resolution: "@typescript-eslint/utils@npm:8.5.0" dependencies: "@eslint-community/eslint-utils": "npm:^4.4.0" - "@typescript-eslint/scope-manager": "npm:8.4.0" - "@typescript-eslint/types": "npm:8.4.0" - "@typescript-eslint/typescript-estree": "npm:8.4.0" + "@typescript-eslint/scope-manager": "npm:8.5.0" + "@typescript-eslint/types": "npm:8.5.0" + "@typescript-eslint/typescript-estree": "npm:8.5.0" peerDependencies: eslint: ^8.57.0 || ^9.0.0 - checksum: 10c0/8c9c36b3aa23f9bcc28cc4b10f0fa2996f1bc6cdd75135f08c2ef734baa30dbd2a8b92f344b90518e1fd07a486936734789fc7e90b780221a7707dad8e9c9364 + checksum: 10c0/0cb0bfdaf0da79d13c0d0379478eb14b5825d235873bc7181e70c4f6297fa1c74431ef730cbc2912fe1814dd8d46c6515ce22b39c57e8f03c337aa152fd49a4e languageName: node linkType: hard @@ -2625,13 +2614,13 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:8.4.0": - version: 8.4.0 - resolution: "@typescript-eslint/visitor-keys@npm:8.4.0" +"@typescript-eslint/visitor-keys@npm:8.5.0": + version: 8.5.0 + resolution: "@typescript-eslint/visitor-keys@npm:8.5.0" dependencies: - "@typescript-eslint/types": "npm:8.4.0" + "@typescript-eslint/types": "npm:8.5.0" eslint-visitor-keys: "npm:^3.4.3" - checksum: 10c0/339199b7fbb9ac83b530d03ab25f6bc5ceb688c9cd0ae460112cd14ee78ca7284a845aef5620cdf70170980123475ec875e85ebf595c60255ba3c0d6fe48c714 + checksum: 10c0/8b9e81968ad36e8af18ac17b63c4e0764612451ca085676c939b723549052243f63577d2706bc2da48174f11bf47587ab47e6e0b7c5b28d9f3c1ef7b9aad322d languageName: node linkType: hard @@ -2723,9 +2712,9 @@ __metadata: linkType: hard "ansi-regex@npm:^6.0.1": - version: 6.0.1 - resolution: "ansi-regex@npm:6.0.1" - checksum: 10c0/cbe16dbd2c6b2735d1df7976a7070dd277326434f0212f43abf6d87674095d247968209babdaad31bb00882fa68807256ba9be340eec2f1004de14ca75f52a08 + version: 6.1.0 + resolution: "ansi-regex@npm:6.1.0" + checksum: 10c0/a91daeddd54746338478eef88af3439a7edf30f8e23196e2d6ed182da9add559c601266dbef01c2efa46a958ad6f1f8b176799657616c702b5b02e799e7fd8dc languageName: node linkType: hard @@ -3137,7 +3126,7 @@ __metadata: reflect-metadata: "npm:^0.2.2" xo: "npm:^0.59.3" peerDependencies: - typescript: ^5.6.2 + typescript: ^5.5.4 languageName: unknown linkType: soft @@ -3185,9 +3174,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.30001646": - version: 1.0.30001658 - resolution: "caniuse-lite@npm:1.0.30001658" - checksum: 10c0/e01f19ac72f056d2b4b680ff2e83d1abf99c0ce0863593bc6abbc40c53589a5c1697b4605b0937a3a431addb2145615e941b91c10d6b63475b7292500339406f + version: 1.0.30001660 + resolution: "caniuse-lite@npm:1.0.30001660" + checksum: 10c0/d28900b56c597176d515c3175ca75c454f2d30cb2c09a44d7bdb009bb0c4d8a2557905adb77642889bbe9feb85fbfe9d974c8b8e53521fb4b50ee16ab246104e languageName: node linkType: hard @@ -3694,9 +3683,9 @@ __metadata: linkType: hard "electron-to-chromium@npm:^1.5.4": - version: 1.5.18 - resolution: "electron-to-chromium@npm:1.5.18" - checksum: 10c0/2c553c4e7618e887398af0fb7ddd8055beb69d37a810ad73fcea0f3e9027f1fc879ef280151fb6bae8e5b961f5597452eafc1ae5a0adca5bd49211545a34afe7 + version: 1.5.20 + resolution: "electron-to-chromium@npm:1.5.20" + checksum: 10c0/d119ccebcb415dc6341072b4a2bd0c9052d94eccf93776d47f5781b9c28393407f9e30718380ee59cb2a280db6b2e36943ffe4a7cdac9e432246380a24f48fa1 languageName: node linkType: hard @@ -4323,35 +4312,7 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-react@npm:^7.35.0": - version: 7.35.2 - resolution: "eslint-plugin-react@npm:7.35.2" - dependencies: - array-includes: "npm:^3.1.8" - array.prototype.findlast: "npm:^1.2.5" - array.prototype.flatmap: "npm:^1.3.2" - array.prototype.tosorted: "npm:^1.1.4" - doctrine: "npm:^2.1.0" - es-iterator-helpers: "npm:^1.0.19" - estraverse: "npm:^5.3.0" - hasown: "npm:^2.0.2" - jsx-ast-utils: "npm:^2.4.1 || ^3.0.0" - minimatch: "npm:^3.1.2" - object.entries: "npm:^1.1.8" - object.fromentries: "npm:^2.0.8" - object.values: "npm:^1.2.0" - prop-types: "npm:^15.8.1" - resolve: "npm:^2.0.0-next.5" - semver: "npm:^6.3.1" - string.prototype.matchall: "npm:^4.0.11" - string.prototype.repeat: "npm:^1.0.0" - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 || ^9.7 - checksum: 10c0/5f891f5a77e902a0ca8d10b23d0b800e90a09400187febe5986c5078d6277baa4b974d6acdbba25baae065dbcf12eb9241b5f5782527d0780314c2ee5006a8af - languageName: node - linkType: hard - -"eslint-plugin-react@npm:^7.35.2": +"eslint-plugin-react@npm:^7.35.0, eslint-plugin-react@npm:^7.35.2": version: 7.36.1 resolution: "eslint-plugin-react@npm:7.36.1" dependencies: @@ -5046,11 +5007,11 @@ __metadata: linkType: hard "get-tsconfig@npm:^4.7.0, get-tsconfig@npm:^4.7.5": - version: 4.8.0 - resolution: "get-tsconfig@npm:4.8.0" + version: 4.8.1 + resolution: "get-tsconfig@npm:4.8.1" dependencies: resolve-pkg-maps: "npm:^1.0.0" - checksum: 10c0/943721c996d9a77351aa7c07956de77baece97f997bd30f3247f46907e4b743f7b9da02c7b3692a36f0884d3724271faeb88ed1c3aca3aba2afe3f27d6c4aeb3 + checksum: 10c0/536ee85d202f604f4b5fb6be81bcd6e6d9a96846811e83e9acc6de4a04fb49506edea0e1b8cf1d5ee7af33e469916ec2809d4c5445ab8ae015a7a51fbd1572f9 languageName: node linkType: hard @@ -5921,9 +5882,9 @@ __metadata: linkType: hard "is-unicode-supported@npm:^2.0.0": - version: 2.0.0 - resolution: "is-unicode-supported@npm:2.0.0" - checksum: 10c0/3013dfb8265fe9f9a0d1e9433fc4e766595631a8d85d60876c457b4bedc066768dab1477c553d02e2f626d88a4e019162706e04263c94d74994ef636a33b5f94 + version: 2.1.0 + resolution: "is-unicode-supported@npm:2.1.0" + checksum: 10c0/a0f53e9a7c1fdbcf2d2ef6e40d4736fdffff1c9f8944c75e15425118ff3610172c87bf7bc6c34d3903b04be59790bb2212ddbe21ee65b5a97030fc50370545a5 languageName: node linkType: hard @@ -7631,9 +7592,9 @@ __metadata: linkType: hard "promise-call-limit@npm:^3.0.1": - version: 3.0.1 - resolution: "promise-call-limit@npm:3.0.1" - checksum: 10c0/2bf66a7238b9986c9b1ae0b3575c1446485b85b4befd9ee359d8386d26050d053cb2aaa57e0fc5d91e230a77e29ad546640b3afe3eb86bcfc204aa0d330f49b4 + version: 3.0.2 + resolution: "promise-call-limit@npm:3.0.2" + checksum: 10c0/1f984c16025925594d738833f5da7525b755f825a198d5a0cac1c0280b4f38ecc3c32c1f4e5ef614ddcfd6718c1a8c3f98a3290ae6f421342281c9a88c488bf7 languageName: node linkType: hard @@ -8887,7 +8848,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:*": +"typescript@npm:*, typescript@npm:^5.5.3": version: 5.6.2 resolution: "typescript@npm:5.6.2" bin: @@ -8897,17 +8858,7 @@ __metadata: languageName: node linkType: hard -"typescript@npm:^5.5.3": - version: 5.5.4 - resolution: "typescript@npm:5.5.4" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/422be60f89e661eab29ac488c974b6cc0a660fb2228003b297c3d10c32c90f3bcffc1009b43876a082515a3c376b1eefcce823d6e78982e6878408b9a923199c - languageName: node - linkType: hard - -"typescript@patch:typescript@npm%3A*#optional!builtin": +"typescript@patch:typescript@npm%3A*#optional!builtin, typescript@patch:typescript@npm%3A^5.5.3#optional!builtin": version: 5.6.2 resolution: "typescript@patch:typescript@npm%3A5.6.2#optional!builtin::version=5.6.2&hash=8c6c40" bin: @@ -8917,16 +8868,6 @@ __metadata: languageName: node linkType: hard -"typescript@patch:typescript@npm%3A^5.5.3#optional!builtin": - version: 5.5.4 - resolution: "typescript@patch:typescript@npm%3A5.5.4#optional!builtin::version=5.5.4&hash=379a07" - bin: - tsc: bin/tsc - tsserver: bin/tsserver - checksum: 10c0/73409d7b9196a5a1217b3aaad929bf76294d3ce7d6e9766dd880ece296ee91cf7d7db6b16c6c6c630ee5096eccde726c0ef17c7dfa52b01a243e57ae1f09ef07 - languageName: node - linkType: hard - "uglify-js@npm:^3.1.4": version: 3.19.3 resolution: "uglify-js@npm:3.19.3"