diff --git a/jest.config.ts b/jest.config.ts index b9717841..db8006b1 100644 --- a/jest.config.ts +++ b/jest.config.ts @@ -1,4 +1,4 @@ -const { getJestProjects } = require('@nx/jest'); +import { getJestProjects } from '@nx/jest'; export default { projects: getJestProjects(), diff --git a/libs/common/.eslintrc.json b/libs/common/.eslintrc.json new file mode 100644 index 00000000..5626944b --- /dev/null +++ b/libs/common/.eslintrc.json @@ -0,0 +1,18 @@ +{ + "extends": ["../../.eslintrc.json"], + "ignorePatterns": ["!**/*"], + "overrides": [ + { + "files": ["*.ts", "*.tsx", "*.js", "*.jsx"], + "rules": {} + }, + { + "files": ["*.ts", "*.tsx"], + "rules": {} + }, + { + "files": ["*.js", "*.jsx"], + "rules": {} + } + ] +} diff --git a/libs/common/README.md b/libs/common/README.md new file mode 100644 index 00000000..1573ff98 --- /dev/null +++ b/libs/common/README.md @@ -0,0 +1,11 @@ +# common + +This library was generated with [Nx](https://nx.dev). + +## Building + +Run `nx build common` to build the library. + +## Running unit tests + +Run `nx test common` to execute the unit tests via [Jest](https://jestjs.io). diff --git a/libs/common/jest.config.ts b/libs/common/jest.config.ts new file mode 100644 index 00000000..01e49dfb --- /dev/null +++ b/libs/common/jest.config.ts @@ -0,0 +1,17 @@ +/* eslint-disable */ +export default { + displayName: 'common', + preset: '../../jest.preset.js', + globals: {}, + transform: { + '^.+\\.[tj]s$': [ + 'ts-jest', + { + tsconfig: '/tsconfig.spec.json', + }, + ], + }, + moduleFileExtensions: ['ts', 'js', 'html'], + coverageDirectory: '../../coverage/libs/common', + testRunner: 'jest-jasmine2', +}; diff --git a/libs/common/package.json b/libs/common/package.json new file mode 100644 index 00000000..69254189 --- /dev/null +++ b/libs/common/package.json @@ -0,0 +1,8 @@ +{ + "name": "@mini-rx/common", + "version": "0.0.2", + "peerDependencies": { + "rxjs": "^6.4.0 || ^7.0.0" + }, + "sideEffects": false +} diff --git a/libs/common/project.json b/libs/common/project.json new file mode 100644 index 00000000..b1eae4b0 --- /dev/null +++ b/libs/common/project.json @@ -0,0 +1,56 @@ +{ + "name": "common", + "$schema": "../../node_modules/nx/schemas/project-schema.json", + "sourceRoot": "libs/common/src", + "projectType": "library", + "targets": { + "build": { + "executor": "@nx/rollup:rollup", + "outputs": ["{options.outputPath}"], + "options": { + "outputPath": "dist/libs/common", + "main": "libs/common/src/index.ts", + "tsConfig": "libs/common/tsconfig.lib.json", + "assets": [], + "project": "libs/common/package.json", + "format": ["esm", "cjs"], + "globals": [ + { + "global": "Rx", + "moduleId": "rxjs" + }, + { + "global": "Rx", + "moduleId": "rxjs/operators" + } + ] + } + }, + "publish": { + "command": "node tools/scripts/publish.mjs common {args.ver} {args.tag}", + "dependsOn": ["build"] + }, + "lint": { + "executor": "@nx/linter:eslint", + "outputs": ["{options.outputFile}"], + "options": { + "lintFilePatterns": ["libs/common/**/*.ts"] + } + }, + "test": { + "executor": "@nx/jest:jest", + "outputs": ["{workspaceRoot}/coverage/{projectRoot}"], + "options": { + "jestConfig": "libs/common/jest.config.ts", + "passWithNoTests": true + }, + "configurations": { + "ci": { + "ci": true, + "codeCoverage": true + } + } + } + }, + "tags": [] +} diff --git a/libs/common/src/index.ts b/libs/common/src/index.ts new file mode 100644 index 00000000..1e16a191 --- /dev/null +++ b/libs/common/src/index.ts @@ -0,0 +1,52 @@ +export { createMiniRxActionType, OperationType } from './lib/create-mini-rx-action-type'; +export { combineMetaReducers } from './lib/combine-meta-reducers'; +export { miniRxError } from './lib/mini-rx-error'; +export { sortExtensions } from './lib/sort-extensions'; + +export { mapResponse } from './lib/map-response'; +export { tapResponse } from './lib/tap-response'; +export { ofType } from './lib/of-type'; +export { createActionsOnQueue } from './lib/actions-on-queue'; +export { defaultEffectsErrorHandler } from './lib/default-effects-error-handler'; +export { + createRxEffect, + hasEffectMetaData, + HasEffectMetadata, + EffectConfig, + EFFECT_METADATA_KEY, +} from './lib/create-rx-effect'; + +export { LoggerExtension } from './lib/extensions/logger/logger.extension'; +export { UndoExtension } from './lib/extensions/undo/undo-extension'; +export { undo } from './lib/extensions/undo/undo'; +export { ImmutableStateExtension } from './lib/extensions/immutable-state/immutable-state.extension'; +export { + AbstractReduxDevtoolsExtension, + ReduxDevtoolsOptions, +} from './lib/extensions/redux-devtools/abstract-redux-devtools-extension'; + +export { createFeatureStoreReducer } from './lib/create-feature-store-reducer'; +export { createComponentStoreReducer } from './lib/create-component-store-reducer'; +export { generateId } from './lib/generate-id'; +export { calculateExtensions } from './lib/calculate-extensions'; +export { createReducerManager, ReducerManager } from './lib/reducer-manager'; +export { componentStoreConfig } from './lib/component-store-config'; + +export { ExtensionId } from './lib/enums'; +export { + Action, + Actions, + FeatureStoreConfig, + Reducer, + StateOrCallback, + MiniRxAction, + StoreExtension, + StoreConfig, + FeatureConfig, + MetaReducer, + ComponentStoreConfig, + ComponentStoreExtension, + AppState, + ReducerDictionary, + ReducerState, +} from './lib/models'; diff --git a/libs/common/src/lib/actions-on-queue.spec.ts b/libs/common/src/lib/actions-on-queue.spec.ts new file mode 100644 index 00000000..83856dd6 --- /dev/null +++ b/libs/common/src/lib/actions-on-queue.spec.ts @@ -0,0 +1,34 @@ +import { createActionsOnQueue } from './actions-on-queue'; +import { take } from 'rxjs'; + +describe('ActionsOnQueue', () => { + it('should dispatch actions', () => { + const spy = jest.fn(); + + const actionsOnQueue = createActionsOnQueue(); + actionsOnQueue.actions$.subscribe(spy); + + const action = { type: 'someAction' }; + actionsOnQueue.dispatch(action); + + expect(spy).toHaveBeenCalledWith(action); + }), + it('should queue actions', () => { + // Without queueScheduler this test would fail because of stack overflow (Read more here: https://blog.cloudboost.io/so-how-does-rx-js-queuescheduler-actually-work-188c1b46526e) + + const callLimit = 5000; + + const actionsOnQueue = createActionsOnQueue(); + + const spy = jest.fn().mockImplementation(() => { + // Every received action dispatches another action + actionsOnQueue.dispatch({ type: 'someAction' }); + }); + + actionsOnQueue.actions$.pipe(take(callLimit)).subscribe(spy); + + actionsOnQueue.dispatch({ type: 'someInitialAction' }); // Dispatch an action to start the whole thing + + expect(spy).toHaveBeenCalledTimes(callLimit); + }); +}); diff --git a/libs/common/src/lib/actions-on-queue.ts b/libs/common/src/lib/actions-on-queue.ts new file mode 100644 index 00000000..38b94549 --- /dev/null +++ b/libs/common/src/lib/actions-on-queue.ts @@ -0,0 +1,15 @@ +import { queueScheduler, Subject, observeOn } from 'rxjs'; +import { Action } from './models'; + +export function createActionsOnQueue() { + const actionsSource = new Subject(); + + return { + actions$: actionsSource.asObservable().pipe( + observeOn(queueScheduler) // Prevent stack overflow: https://blog.cloudboost.io/so-how-does-rx-js-queuescheduler-actually-work-188c1b46526e + ), + dispatch: (action: Action) => { + actionsSource.next(action); + }, + }; +} diff --git a/libs/common/src/lib/beautify-action.spec.ts b/libs/common/src/lib/beautify-action.spec.ts new file mode 100644 index 00000000..a971b01b --- /dev/null +++ b/libs/common/src/lib/beautify-action.spec.ts @@ -0,0 +1,33 @@ +import { beautifyAction } from './beautify-action'; +import { MiniRxAction } from './models'; +import { createMiniRxActionType, OperationType } from './create-mini-rx-action-type'; + +describe('beautifyAction', () => { + it('should remove extra fields from FeatureStore/ComponentStore Actions', () => { + const csAction: MiniRxAction = { + type: createMiniRxActionType(OperationType.SET_STATE, 'todos'), + stateOrCallback: {}, + }; + + expect(beautifyAction(csAction)).toEqual({ + type: '@mini-rx/todos/set-state', + payload: {}, + }); + + const fsAction: MiniRxAction = { + type: createMiniRxActionType(OperationType.SET_STATE, 'todos'), + stateOrCallback: {}, + featureId: 'someFeatureId', + }; + + expect(beautifyAction(fsAction)).toEqual({ + type: '@mini-rx/todos/set-state', + payload: {}, + }); + }), + it('should not touch other normal Actions', () => { + const action = { type: 'someAction' }; + + expect(beautifyAction(action)).toBe(action); + }); +}); diff --git a/libs/common/src/lib/beautify-action.ts b/libs/common/src/lib/beautify-action.ts new file mode 100644 index 00000000..a6245d23 --- /dev/null +++ b/libs/common/src/lib/beautify-action.ts @@ -0,0 +1,13 @@ +import { Action, MiniRxAction } from '../lib/models'; +import { isMiniRxAction } from './is-mini-rx-action'; + +// Only display type and payload in the LoggingExtension and Redux DevTools +export function beautifyAction(action: Action | MiniRxAction): Action { + if (isMiniRxAction(action)) { + return { + type: action.type, + payload: action.stateOrCallback, + }; + } + return action; +} diff --git a/libs/common/src/lib/calc-next-state.spec.ts b/libs/common/src/lib/calc-next-state.spec.ts new file mode 100644 index 00000000..f5b2a370 --- /dev/null +++ b/libs/common/src/lib/calc-next-state.spec.ts @@ -0,0 +1,13 @@ +import { calcNextState } from './calc-next-state'; + +describe('calcNextState', () => { + it('should calculate next state', () => { + const currentState = { count: 1 }; + expect(calcNextState(currentState, { count: 2 })).toEqual({ count: 2 }); + + // Witch callback + expect(calcNextState(currentState, (state) => ({ count: state.count + 2 }))).toEqual({ + count: 3, + }); + }); +}); diff --git a/libs/common/src/lib/calc-next-state.ts b/libs/common/src/lib/calc-next-state.ts new file mode 100644 index 00000000..8bd388a2 --- /dev/null +++ b/libs/common/src/lib/calc-next-state.ts @@ -0,0 +1,10 @@ +import { StateOrCallback } from './models'; + +export function calcNextState(state: T, stateOrCallback: StateOrCallback): T { + const newPartialState = + typeof stateOrCallback === 'function' ? stateOrCallback(state) : stateOrCallback; + return { + ...state, + ...newPartialState, + }; +} diff --git a/libs/common/src/lib/calculate-extensions.spec.ts b/libs/common/src/lib/calculate-extensions.spec.ts new file mode 100644 index 00000000..b6740ebe --- /dev/null +++ b/libs/common/src/lib/calculate-extensions.spec.ts @@ -0,0 +1,86 @@ +import { ComponentStoreExtension, MetaReducer } from './models'; +import { ExtensionId } from './enums'; +import { calculateExtensions } from './calculate-extensions'; + +class MockLoggerExtension implements ComponentStoreExtension { + id = ExtensionId.LOGGER; + sortOrder = 1; + hasCsSupport = true as const; + + init(): MetaReducer { + return (v) => v; + } +} + +class MockUndoExtension implements ComponentStoreExtension { + id = ExtensionId.UNDO; + sortOrder = 2; + hasCsSupport = true as const; + + init(): MetaReducer { + return (v) => v; + } +} + +class MockImmutableStateExtension implements ComponentStoreExtension { + id = ExtensionId.IMMUTABLE_STATE; + sortOrder = 3; + hasCsSupport = true as const; + + init(): MetaReducer { + return (v) => v; + } +} + +describe('calculateExtensions', () => { + it('should add local extensions', () => { + const extensions = [new MockLoggerExtension(), new MockUndoExtension()]; + expect(calculateExtensions({ extensions })).toStrictEqual(extensions); + }); + + it('should add global extensions', () => { + const extensions = [new MockLoggerExtension(), new MockUndoExtension()]; + expect(calculateExtensions(undefined, { extensions })).toStrictEqual(extensions); + }); + + it('should merge local and global extensions', () => { + const localExtensions = [new MockLoggerExtension()]; + const globalExtensions = [new MockUndoExtension(), new MockImmutableStateExtension()]; + + const extensions = calculateExtensions( + { extensions: localExtensions }, + { extensions: globalExtensions } + ); + + expect(extensions[0]).toBe(localExtensions[0]); + expect(extensions[1]).toBe(globalExtensions[0]); + expect(extensions[2]).toBe(globalExtensions[1]); + }); + + it('should merge local and global extensions (use local if extension is used globally and locally)', () => { + const localExtensions = [new MockLoggerExtension()]; + const globalExtensions = [new MockLoggerExtension(), new MockImmutableStateExtension()]; + + const extensions = calculateExtensions( + { extensions: localExtensions }, + { extensions: globalExtensions } + ); + + expect(extensions[0]).toBe(localExtensions[0]); + expect(extensions[1]).toBe(globalExtensions[1]); + }); + + it('should return empty extensions if no global or local extensions are defined', () => { + const extensions = calculateExtensions(); + expect(extensions).toEqual([]); + }); + + it('should sort extensions', () => { + const extensions = [new MockImmutableStateExtension(), new MockLoggerExtension()]; + + const extensionsSorted = calculateExtensions({ extensions }); + + expect(extensionsSorted[0]).toBe(extensions[1]); + expect(extensionsSorted[1]).toBe(extensions[0]); + }); +}); diff --git a/libs/common/src/lib/calculate-extensions.ts b/libs/common/src/lib/calculate-extensions.ts new file mode 100644 index 00000000..2f798b92 --- /dev/null +++ b/libs/common/src/lib/calculate-extensions.ts @@ -0,0 +1,54 @@ +import { ComponentStoreConfig, ComponentStoreExtension } from './models'; +import { sortExtensions } from './sort-extensions'; + +function mergeComponentStoreExtensions( + global: ComponentStoreExtension[], + local: ComponentStoreExtension[] +): ComponentStoreExtension[] { + // Local extensions overwrite the global extensions + // If extension is global and local => use local + // If extension is only global => use global + // If extension is only local => use local + + const extensions: ComponentStoreExtension[] = []; + let globalCopy = [...global]; + let localCopy = [...local]; + + global.forEach((globalExt) => { + local.forEach((localExt) => { + if (localExt.id === globalExt.id) { + // Found extension which is global and local + extensions.push(localExt); // Use local! + localCopy = localCopy.filter((item) => item.id !== localExt.id); // Remove found extension from local + globalCopy = globalCopy.filter((item) => item.id !== globalExt.id); // Remove found extension from global + } + }); + }); + + return [ + ...extensions, // Extensions which are global and local, but use local + ...localCopy, // Local only + ...globalCopy, // Global only + ]; +} + +export function calculateExtensions( + localConfig?: ComponentStoreConfig, + globalConfig?: ComponentStoreConfig +): ComponentStoreExtension[] { + let extensions: ComponentStoreExtension[] = []; + + if (localConfig?.extensions) { + if (localConfig.extensions && globalConfig?.extensions) { + extensions = mergeComponentStoreExtensions( + globalConfig.extensions, + localConfig.extensions + ); + } else { + extensions = localConfig.extensions; + } + } else if (globalConfig?.extensions) { + extensions = globalConfig.extensions; + } + return sortExtensions(extensions); +} diff --git a/libs/common/src/lib/combine-meta-reducers.spec.ts b/libs/common/src/lib/combine-meta-reducers.spec.ts new file mode 100644 index 00000000..8646daf5 --- /dev/null +++ b/libs/common/src/lib/combine-meta-reducers.spec.ts @@ -0,0 +1,47 @@ +import { AppState, Reducer } from './models'; +import { combineMetaReducers } from './combine-meta-reducers'; + +describe('combineMetaReducers', () => { + it('should combine meta reducers', () => { + // Meta Reducers are executed from left to right and before the app state reducer + + function rootMetaReducer1(reducer: Reducer): Reducer { + return (state, action) => { + if (action.type === 'metaTest') { + state = { + ...state, + metaTestFeature: state.metaTestFeature + 'b', + }; + } + + return reducer(state, action); + }; + } + + function rootMetaReducer2(reducer: Reducer): Reducer { + return (state, action) => { + if (action.type === 'metaTest') { + state = { + ...state, + metaTestFeature: state.metaTestFeature + 'c', + }; + } + + return reducer(state, action); + }; + } + + const appStateReducer: Reducer = (state, action) => ({ + metaTestFeature: state['metaTestFeature'] + 'd', + }); + const combinedMetaReducers = combineMetaReducers([rootMetaReducer1, rootMetaReducer2]); + + const reducer = combinedMetaReducers(appStateReducer); + + const state = reducer({ metaTestFeature: 'a' }, { type: 'metaTest' }); + + expect(state).toEqual({ + metaTestFeature: 'abcd', + }); + }); +}); diff --git a/libs/common/src/lib/combine-meta-reducers.ts b/libs/common/src/lib/combine-meta-reducers.ts new file mode 100644 index 00000000..6c215dce --- /dev/null +++ b/libs/common/src/lib/combine-meta-reducers.ts @@ -0,0 +1,12 @@ +import { MetaReducer, Reducer } from './models'; + +export function combineMetaReducers(metaReducers: MetaReducer[]): MetaReducer { + return (reducer: Reducer): Reducer => { + return metaReducers.reduceRight( + (previousValue: Reducer, currentValue: MetaReducer) => { + return currentValue(previousValue); + }, + reducer + ); + }; +} diff --git a/libs/common/src/lib/combine-reducers.spec.ts b/libs/common/src/lib/combine-reducers.spec.ts new file mode 100644 index 00000000..c2d57da8 --- /dev/null +++ b/libs/common/src/lib/combine-reducers.spec.ts @@ -0,0 +1,111 @@ +import { Action, Reducer } from './models'; +import { combineReducers } from './combine-reducers'; + +const action1: Action = { + type: 'showProductCode', +}; + +const action2: Action = { + type: 'showProductCode2', +}; + +const action3: Action = { + type: 'showProductCode3', +}; + +function reducer1(state: any, action: Action): any { + switch (action.type) { + case action1.type: + return { + ...state, + showProductCode: true, + }; + default: + return state; + } +} + +function reducer2(state: any, action: Action): any { + switch (action.type) { + case action2.type: + return { + ...state, + showProductCode2: false, + }; + default: + return state; + } +} + +function reducer3(state: any, action: Action): any { + switch (action.type) { + case action3.type: + return { + ...state, + showProductCode3: undefined, + }; + default: + return state; + } +} + +describe('combine Reducers', () => { + it('should combine reducers', () => { + const combinedReducer: Reducer = combineReducers({ + feature1: reducer1, + feature2: reducer2, + }); + + const newState = combinedReducer({}, action1); + expect(newState).toEqual({ feature1: { showProductCode: true } }); + + const newState2 = combinedReducer(newState, action2); + expect(newState2).toEqual({ + feature1: { showProductCode: true }, + feature2: { showProductCode2: false }, + }); + + const combinedReducer2 = combineReducers({ + feature1: reducer1, + feature2: reducer2, + feature3: reducer3, + }); + + const newState3 = combinedReducer2(newState2, action3); + + expect(newState3).toEqual({ + feature1: { showProductCode: true }, + feature2: { showProductCode2: false }, + feature3: { showProductCode3: undefined }, + }); + }); + + it('should remove keys from state which are not present in the reducer map', () => { + const combinedReducer: Reducer = combineReducers({ + feature1: reducer1, + feature2: reducer2, + }); + + const newState = combinedReducer( + { + feature1: { showProductCode: true }, + feature2: { showProductCode2: false }, + feature3: { showProductCode2: false }, + }, + action2 + ); + + expect(newState).toEqual({ + feature1: { showProductCode: true }, + feature2: { showProductCode2: false }, + }); + }); + + it('should fallback to an empty object as initial state', () => { + const combinedReducer: Reducer = combineReducers({}); + + const newState = combinedReducer(undefined, { type: 'someAction' }); + + expect(newState).toEqual({}); + }); +}); diff --git a/libs/signal-store/src/lib/combine-reducers.ts b/libs/common/src/lib/combine-reducers.ts similarity index 100% rename from libs/signal-store/src/lib/combine-reducers.ts rename to libs/common/src/lib/combine-reducers.ts diff --git a/libs/common/src/lib/component-store-config.spec.ts b/libs/common/src/lib/component-store-config.spec.ts new file mode 100644 index 00000000..da47a9e8 --- /dev/null +++ b/libs/common/src/lib/component-store-config.spec.ts @@ -0,0 +1,26 @@ +import { componentStoreConfig } from './component-store-config'; +import { ExtensionId } from './enums'; +import { MetaReducer } from './models'; + +describe('componentStoreConfig', () => { + it('should set and get Component Store config', () => { + const extension = { + id: ExtensionId.LOGGER, + sortOrder: 1, + init(): MetaReducer { + return (v) => v; + }, + }; + const config = componentStoreConfig(); + config.set({ extensions: [extension] }); + + expect(config.get()).toEqual({ extensions: [extension] }); + }); + + it('should throw if config is already set', () => { + const config = componentStoreConfig(); + config.set({ extensions: [] }); + + expect(() => config.set({ extensions: [] })).toThrow(); + }); +}); diff --git a/libs/common/src/lib/component-store-config.ts b/libs/common/src/lib/component-store-config.ts new file mode 100644 index 00000000..d3e04233 --- /dev/null +++ b/libs/common/src/lib/component-store-config.ts @@ -0,0 +1,23 @@ +import { ComponentStoreConfig } from './models'; +import { miniRxError } from './mini-rx-error'; + +export function componentStoreConfig() { + let componentStoreConfig: ComponentStoreConfig | undefined = undefined; + + function set(config: ComponentStoreConfig) { + if (!componentStoreConfig) { + componentStoreConfig = config; + return; + } + miniRxError('`configureComponentStores` was called multiple times.'); + } + + function get(): ComponentStoreConfig | undefined { + return componentStoreConfig; + } + + return { + set, + get, + }; +} diff --git a/libs/signal-store/src/lib/constants.ts b/libs/common/src/lib/constants.ts similarity index 100% rename from libs/signal-store/src/lib/constants.ts rename to libs/common/src/lib/constants.ts diff --git a/libs/common/src/lib/create-component-store-reducer.spec.ts b/libs/common/src/lib/create-component-store-reducer.spec.ts new file mode 100644 index 00000000..28cc1d43 --- /dev/null +++ b/libs/common/src/lib/create-component-store-reducer.spec.ts @@ -0,0 +1,30 @@ +import { createComponentStoreReducer } from './create-component-store-reducer'; +import { createMiniRxActionType, OperationType } from './create-mini-rx-action-type'; +import { Action, MiniRxAction } from './models'; + +interface CounterState { + counter: number; +} + +describe('createComponentStoreReducer', () => { + const reducer = createComponentStoreReducer({ counter: 1 }); + + it('should update state', () => { + const action: MiniRxAction = { + type: createMiniRxActionType(OperationType.SET_STATE), + stateOrCallback: (state) => ({ ...state, counter: state.counter + 1 }), + }; + + const nextState = reducer({ counter: 1 }, action); + + expect(nextState).toEqual({ counter: 2 }); + }); + + it('should NOT update state', () => { + const notComponentStoreAction: Action = { type: 'abc' }; + const state = { counter: 1 }; + const nextState = reducer(state, notComponentStoreAction); + + expect(nextState).toBe(state); + }); +}); diff --git a/libs/common/src/lib/create-component-store-reducer.ts b/libs/common/src/lib/create-component-store-reducer.ts new file mode 100644 index 00000000..8c28ae54 --- /dev/null +++ b/libs/common/src/lib/create-component-store-reducer.ts @@ -0,0 +1,14 @@ +import { Action, Reducer } from './models'; +import { isMiniRxAction } from './is-mini-rx-action'; +import { calcNextState } from './calc-next-state'; + +export function createComponentStoreReducer( + initialState: StateType +): Reducer { + return (state: StateType = initialState, action: Action) => { + if (isMiniRxAction(action)) { + return calcNextState(state, action.stateOrCallback); + } + return state; + }; +} diff --git a/libs/common/src/lib/create-feature-store-reducer.spec.ts b/libs/common/src/lib/create-feature-store-reducer.spec.ts new file mode 100644 index 00000000..182b3847 --- /dev/null +++ b/libs/common/src/lib/create-feature-store-reducer.spec.ts @@ -0,0 +1,41 @@ +import { createFeatureStoreReducer } from './create-feature-store-reducer'; +import { createMiniRxActionType, OperationType } from './create-mini-rx-action-type'; +import { Action, MiniRxAction } from './models'; + +interface CounterState { + counter: number; +} + +describe('createFeatureStoreReducer', () => { + const featureId = '123'; + const reducer = createFeatureStoreReducer(featureId, { counter: 1 }); + + it('should update state', () => { + const action: MiniRxAction = { + type: createMiniRxActionType(OperationType.SET_STATE), + stateOrCallback: (state) => ({ ...state, counter: state.counter + 1 }), + featureId, + }; + + const nextState = reducer({ counter: 1 }, action); + + expect(nextState).toEqual({ counter: 2 }); + }); + + it('should NOT update state', () => { + const notFeatureStoreAction: Action = { type: 'abc' }; + const state = { counter: 1 }; + let nextState = reducer(state, notFeatureStoreAction); + + expect(nextState).toBe(state); + + const actionWithWrongFeatureId: MiniRxAction = { + type: createMiniRxActionType(OperationType.SET_STATE), + stateOrCallback: (state) => ({ ...state, counter: state.counter + 1 }), + featureId: 'abc', + }; + + nextState = reducer(state, actionWithWrongFeatureId); + expect(nextState).toBe(state); + }); +}); diff --git a/libs/common/src/lib/create-feature-store-reducer.ts b/libs/common/src/lib/create-feature-store-reducer.ts new file mode 100644 index 00000000..fa30adac --- /dev/null +++ b/libs/common/src/lib/create-feature-store-reducer.ts @@ -0,0 +1,15 @@ +import { Action, Reducer } from './models'; +import { isMiniRxAction } from './is-mini-rx-action'; +import { calcNextState } from './calc-next-state'; + +export function createFeatureStoreReducer( + featureId: string, + initialState: StateType +): Reducer { + return (state: StateType = initialState, action: Action): StateType => { + if (isMiniRxAction(action) && action.featureId === featureId) { + return calcNextState(state, action.stateOrCallback); + } + return state; + }; +} diff --git a/libs/common/src/lib/create-mini-rx-action-type.spec.ts b/libs/common/src/lib/create-mini-rx-action-type.spec.ts new file mode 100644 index 00000000..a3d5f99e --- /dev/null +++ b/libs/common/src/lib/create-mini-rx-action-type.spec.ts @@ -0,0 +1,29 @@ +import { createMiniRxActionType, OperationType } from './create-mini-rx-action-type'; + +describe('createMiniRxActionType', () => { + it('should create a MiniRx Action Type', () => { + const featureKey = 'todos'; + + const storeInit = createMiniRxActionType(OperationType.INIT); + expect(storeInit).toBe('@mini-rx/init'); + + const featureInit = createMiniRxActionType(OperationType.INIT, featureKey); + expect(featureInit).toBe('@mini-rx/todos/init'); + + const featureDestroy = createMiniRxActionType(OperationType.DESTROY, featureKey); + expect(featureDestroy).toBe('@mini-rx/todos/destroy'); + + const connection = createMiniRxActionType(OperationType.CONNECTION, featureKey, 'someKey'); + expect(connection).toBe('@mini-rx/todos/connection/someKey'); + + const setState = createMiniRxActionType(OperationType.SET_STATE, featureKey); + expect(setState).toBe('@mini-rx/todos/set-state'); + + const setStateWithName = createMiniRxActionType( + OperationType.SET_STATE, + featureKey, + 'someName' + ); + expect(setStateWithName).toBe('@mini-rx/todos/set-state/someName'); + }); +}); diff --git a/libs/common/src/lib/create-mini-rx-action-type.ts b/libs/common/src/lib/create-mini-rx-action-type.ts new file mode 100644 index 00000000..27b17849 --- /dev/null +++ b/libs/common/src/lib/create-mini-rx-action-type.ts @@ -0,0 +1,22 @@ +import { miniRxNameSpace } from './constants'; + +export const enum OperationType { + INIT = 'init', + DESTROY = 'destroy', + SET_STATE = 'set-state', + CONNECTION = 'connection', +} + +export function createMiniRxActionType( + operationType: OperationType, + featureKey?: string, + name?: string +): string { + return ( + miniRxNameSpace + + (featureKey ? '/' + featureKey : '') + + '/' + + operationType + + (name ? '/' + name : '') + ); +} diff --git a/libs/common/src/lib/create-rx-effect.spec.ts b/libs/common/src/lib/create-rx-effect.spec.ts new file mode 100644 index 00000000..d979bfc2 --- /dev/null +++ b/libs/common/src/lib/create-rx-effect.spec.ts @@ -0,0 +1,39 @@ +import { createRxEffect, hasEffectMetaData } from './create-rx-effect'; +import { Observable, of } from 'rxjs'; +import { Action } from './models'; + +describe('createRxEffect', () => { + it('should dispatch by default', () => { + const actionStream$: Observable = of({ type: 'someAction' }); + const effect = createRxEffect(actionStream$); + + expect(effect['@mini-rx/effectMetaData']).toEqual( + expect.objectContaining({ dispatch: true }) + ); + }), + it('should be possible to create a non-dispatching effect', () => { + const actionStream$: Observable = of({ type: 'someAction' }); + const effect = createRxEffect(actionStream$, { + dispatch: false, + }); + + expect(effect['@mini-rx/effectMetaData']).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); + it('should be possible to create a non-dispatching effect returning a non-action', () => { + const effect = createRxEffect(of('foo'), { + dispatch: false, + }); + + expect(effect['@mini-rx/effectMetaData']).toEqual( + expect.objectContaining({ dispatch: false }) + ); + }); +}); + +describe('hasEffectMetaData', () => { + it('should detect ', () => { + expect(hasEffectMetaData(of({ type: 'someAction' }))).toBe(false); + }); +}); diff --git a/libs/signal-store/src/lib/create-rx-effect.ts b/libs/common/src/lib/create-rx-effect.ts similarity index 75% rename from libs/signal-store/src/lib/create-rx-effect.ts rename to libs/common/src/lib/create-rx-effect.ts index e9b32805..cb304adc 100644 --- a/libs/signal-store/src/lib/create-rx-effect.ts +++ b/libs/common/src/lib/create-rx-effect.ts @@ -24,7 +24,21 @@ // SOFTWARE. import { Observable } from 'rxjs'; -import { Action, EFFECT_METADATA_KEY, EffectConfig, HasEffectMetadata } from './models'; +import { Action } from './models'; + +export const EFFECT_METADATA_KEY = '@mini-rx/effectMetaData'; + +export interface EffectConfig { + /** + * Determines if the action emitted by the effect is dispatched to the store. + * If false, effect does not need to return type `Observable`. + */ + dispatch?: boolean; +} + +export interface HasEffectMetadata { + [EFFECT_METADATA_KEY]: EffectConfig; +} const DEFAULT_EFFECT_CONFIG: Readonly> = { dispatch: true, @@ -42,12 +56,18 @@ export function createRxEffect< OT extends ObservableType, R extends EffectType >(v: R, config?: C): R & HasEffectMetadata { - const value: EffectConfig = { + const metaData: EffectConfig = { ...DEFAULT_EFFECT_CONFIG, ...config, }; Object.defineProperty(v, EFFECT_METADATA_KEY, { - value, + value: metaData, }); return v as typeof v & HasEffectMetadata; } + +export function hasEffectMetaData( + param: Observable +): param is Observable & HasEffectMetadata { + return Object.hasOwn(param, EFFECT_METADATA_KEY); +} diff --git a/libs/common/src/lib/deep-freeze.spec.ts b/libs/common/src/lib/deep-freeze.spec.ts new file mode 100644 index 00000000..db70a605 --- /dev/null +++ b/libs/common/src/lib/deep-freeze.spec.ts @@ -0,0 +1,84 @@ +import { deepFreeze } from './deep-freeze'; + +// Created a cool set of unit tests with ChatGPT: https://chat.openai.com/share/f2a078c9-e996-4d4e-8c4c-725ca2e9cafd + +describe('deepFreeze', () => { + it('should make object immutable', () => { + const obj = { count: 1 }; + deepFreeze(obj); + expect(Object.isFrozen(obj)).toBe(true); + expect(() => (obj.count = 2)).toThrow(); + + const obj2 = { + nestedCounter: { + count: 1, + }, + }; + deepFreeze(obj2); + expect(Object.isFrozen(obj2.nestedCounter)).toBe(true); + expect(() => (obj2.nestedCounter.count = 2)).toThrow(); + }), + it('should freeze a function object', () => { + const fn = (): number => { + return 42; + }; + expect(() => deepFreeze(fn)).not.toThrow(); + // Test that the function object is frozen + expect(Object.isFrozen(fn)).toBe(true); + }), + it('should handle circular references', () => { + const circularObj: { + prop1: number; + circularRef: any; + } = { prop1: 42, circularRef: undefined }; + circularObj.circularRef = circularObj; + expect(() => deepFreeze(circularObj)).not.toThrow(); + // Ensure circular references do not result in infinite loops + expect(Object.isFrozen(circularObj)).toBe(true); + }); + // Arrays + it('should freeze an array and its elements', () => { + const arr = [1, 2, 3]; + expect(() => deepFreeze(arr)).not.toThrow(); + // Test that the array and its elements are frozen + expect(Object.isFrozen(arr)).toBe(true); + expect(Object.isFrozen(arr[0])).toBe(true); + }); + + // Nested Objects and Arrays + it('should freeze nested objects and arrays', () => { + const nestedObj = { arr: [1, 2, { nestedProp: 'value' }] }; + expect(() => deepFreeze(nestedObj)).not.toThrow(); + // Test that nestedObj, its properties, and elements are frozen + expect(Object.isFrozen(nestedObj)).toBe(true); + expect(Object.isFrozen(nestedObj.arr)).toBe(true); + expect(Object.isFrozen(nestedObj.arr[2])).toBe(true); + }); + + // Mixed Types + it('should freeze objects with mixed types', () => { + const mixedObj = { + str: 'immutable', + num: 42, + bool: true, + fn: function () {}, + nested: { + arr: [1, 2, { objProp: 'value' }], + }, + }; + expect(() => deepFreeze(mixedObj)).not.toThrow(); + // Test that mixedObj and all its properties of different types are frozen + expect(Object.isFrozen(mixedObj)).toBe(true); + expect(Object.isFrozen(mixedObj.nested.arr[2])).toBe(true); + }); + + // Arrays with Objects + it('should freeze arrays with objects', () => { + const arrOfObjs = [{ prop: 'value' }, { nested: { prop: 'value' } }]; + expect(() => deepFreeze(arrOfObjs)).not.toThrow(); + // Test that arrOfObjs and its elements are frozen + expect(Object.isFrozen(arrOfObjs)).toBe(true); + expect(Object.isFrozen(arrOfObjs[0])).toBe(true); + expect(Object.isFrozen(arrOfObjs[1].nested)).toBe(true); + }); +}); diff --git a/libs/signal-store/src/lib/deep-freeze.ts b/libs/common/src/lib/deep-freeze.ts similarity index 100% rename from libs/signal-store/src/lib/deep-freeze.ts rename to libs/common/src/lib/deep-freeze.ts diff --git a/libs/common/src/lib/default-effects-error-handler.spec.ts b/libs/common/src/lib/default-effects-error-handler.spec.ts new file mode 100644 index 00000000..279d2398 --- /dev/null +++ b/libs/common/src/lib/default-effects-error-handler.spec.ts @@ -0,0 +1,106 @@ +import { of, Subject, switchMap } from 'rxjs'; +import { defaultEffectsErrorHandler } from './default-effects-error-handler'; + +describe('defaultEffectsErrorHandler', () => { + function getErrorMsg(times: number) { + return `@mini-rx: An error occurred in the Effect. MiniRx resubscribed the Effect automatically and will do so ${times} more times.`; + } + + it('should resubscribe the effect 10 times (if side effect error is not handled)', () => { + const spy = jest.fn(); + console.error = jest.fn(); + + function apiCallWithError() { + spy(); + throw new Error(); + return of('someValue'); + } + + const actions = new Subject(); + const effect = actions.pipe(switchMap(() => apiCallWithError())); + + const effectWithDefaultErrorHandler = defaultEffectsErrorHandler(effect); + effectWithDefaultErrorHandler.subscribe(); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(9)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(8)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(7)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(6)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(5)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(4)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(3)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(2)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(1)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining(getErrorMsg(0)), + expect.any(Error) + ); + + actions.next(); + + expect(console.error).toHaveBeenCalledTimes(10); + expect(spy).toHaveBeenCalledTimes(11); + + actions.next(); // #12 will not trigger the Api call anymore, no error is logged + actions.next(); // #13 will not trigger the Api call anymore, no error is logged + + expect(console.error).toHaveBeenCalledTimes(10); // Re-subscription with error logging stopped after 10 times + expect(spy).toHaveBeenCalledTimes(11); // Api call is performed 11 Times. First time + 10 re-subscriptions + }); +}); diff --git a/libs/signal-store/src/lib/default-effects-error-handler.ts b/libs/common/src/lib/default-effects-error-handler.ts similarity index 93% rename from libs/signal-store/src/lib/default-effects-error-handler.ts rename to libs/common/src/lib/default-effects-error-handler.ts index 5217dc4d..9b92fbe0 100644 --- a/libs/signal-store/src/lib/default-effects-error-handler.ts +++ b/libs/common/src/lib/default-effects-error-handler.ts @@ -24,14 +24,13 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { Observable } from 'rxjs'; -import { catchError } from 'rxjs/operators'; -import { miniRxConsoleError } from './utils'; +import { Observable, catchError } from 'rxjs'; +import { miniRxConsoleError } from './mini-rx-console-error'; // Prevent effect to unsubscribe from the actions stream export function defaultEffectsErrorHandler( observable$: Observable, - retryAttemptLeft: number = 10 + retryAttemptLeft = 10 ): Observable { return observable$.pipe( catchError((error) => { diff --git a/libs/common/src/lib/enums.ts b/libs/common/src/lib/enums.ts new file mode 100644 index 00000000..fd6a726d --- /dev/null +++ b/libs/common/src/lib/enums.ts @@ -0,0 +1,14 @@ +export const enum ExtensionSortOrder { + DEFAULT = 0, + // The Undo Extension Meta Reducer should be the last one to be executed before "normal" reducers (for performance) + // Reason: The Undo Extension Meta Reducers may send many Actions through all following Reducers to undo an Action + // Also, we want to prevent that the replay of Actions shows up e.g. in the LoggerExtension Meta Reducer + UNDO_EXTENSION = 1, +} + +export const enum ExtensionId { + IMMUTABLE_STATE, + UNDO, + LOGGER, + REDUX_DEVTOOLS, +} diff --git a/libs/common/src/lib/extensions/immutable-state/immutable-state-meta-reducer.spec.ts b/libs/common/src/lib/extensions/immutable-state/immutable-state-meta-reducer.spec.ts new file mode 100644 index 00000000..e3eb8fd5 --- /dev/null +++ b/libs/common/src/lib/extensions/immutable-state/immutable-state-meta-reducer.spec.ts @@ -0,0 +1,36 @@ +import { Action, Reducer } from 'mini-rx-store'; +import { immutableStateMetaReducer } from './immutable-state-meta-reducer'; + +describe('immutableStateMetaReducer', () => { + function counterReducerWithMutation( + state: { counter: number } = { counter: 1 }, + action: Action + ) { + switch (action.type) { + case 'counterWithoutMutation': + return { + ...state, + counter: state.counter + 1, + }; + case 'counterWithMutation': + state.counter = 123; // mutate + return { + ...state, + counter: state.counter + 1, + }; + default: + return state; + } + } + + it('should throw when mutating state in the reducer', () => { + const frozenReducer: Reducer = immutableStateMetaReducer(counterReducerWithMutation); + expect(() => frozenReducer({ counter: 1 }, { type: 'counterWithMutation' })).toThrow(); + }); + + it('should throw when mutating state returned by the reducer', () => { + const frozenReducer: Reducer = immutableStateMetaReducer(counterReducerWithMutation); + const state = frozenReducer({ counter: 1 }, { type: 'counterWithoutMutation' }); + expect(() => (state.counter = 123)).toThrow(); + }); +}); diff --git a/libs/common/src/lib/extensions/immutable-state/immutable-state-meta-reducer.ts b/libs/common/src/lib/extensions/immutable-state/immutable-state-meta-reducer.ts new file mode 100644 index 00000000..35479c64 --- /dev/null +++ b/libs/common/src/lib/extensions/immutable-state/immutable-state-meta-reducer.ts @@ -0,0 +1,13 @@ +import { Action, Reducer } from '../../models'; +import { deepFreeze } from '../../deep-freeze'; + +export function immutableStateMetaReducer(reducer: Reducer): Reducer { + return (state, action: Action) => { + if (state) { + deepFreeze(state); + } + const nextState = reducer(state, action); + deepFreeze(nextState); + return nextState; + }; +} diff --git a/libs/common/src/lib/extensions/immutable-state/immutable-state.extension.spec.ts b/libs/common/src/lib/extensions/immutable-state/immutable-state.extension.spec.ts new file mode 100644 index 00000000..a33f6d31 --- /dev/null +++ b/libs/common/src/lib/extensions/immutable-state/immutable-state.extension.spec.ts @@ -0,0 +1,22 @@ +import { ImmutableStateExtension } from './immutable-state.extension'; +import { ExtensionId } from '../../enums'; + +describe('ImmutableStateExtension', () => { + const instance = new ImmutableStateExtension(); + + it('should support ComponentStore', () => { + expect(instance.hasCsSupport).toBe(true); + }); + + it('should have sort order', () => { + expect(instance.sortOrder).toBe(0); + }); + + it('should have id', () => { + expect(instance.id).toBe(ExtensionId.IMMUTABLE_STATE); + }); + + it('should have an init method which returns a function', () => { + expect(typeof instance.init()).toBe('function'); + }); +}); diff --git a/libs/signal-store/src/lib/extensions/immutable-state.extension.ts b/libs/common/src/lib/extensions/immutable-state/immutable-state.extension.ts similarity index 73% rename from libs/signal-store/src/lib/extensions/immutable-state.extension.ts rename to libs/common/src/lib/extensions/immutable-state/immutable-state.extension.ts index f1136b82..75ece832 100644 --- a/libs/signal-store/src/lib/extensions/immutable-state.extension.ts +++ b/libs/common/src/lib/extensions/immutable-state/immutable-state.extension.ts @@ -23,32 +23,15 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { - Action, - ExtensionId, - HasComponentStoreSupport, - MetaReducer, - Reducer, - StoreExtension, -} from '../models'; -import { deepFreeze } from '../deep-freeze'; +import { ComponentStoreExtension, MetaReducer, StoreExtension } from '../../models'; +import { ExtensionId } from '../../enums'; +import { immutableStateMetaReducer } from './immutable-state-meta-reducer'; -export class ImmutableStateExtension extends StoreExtension implements HasComponentStoreSupport { +export class ImmutableStateExtension extends StoreExtension implements ComponentStoreExtension { id = ExtensionId.IMMUTABLE_STATE; hasCsSupport = true as const; init(): MetaReducer { - return storeFreeze; + return immutableStateMetaReducer; } } - -function storeFreeze(reducer: Reducer): Reducer { - return (state, action: Action) => { - if (state) { - deepFreeze(state); - } - const nextState = reducer(state, action); - deepFreeze(nextState); - return nextState; - }; -} diff --git a/libs/common/src/lib/extensions/logger/logger-meta-reducer.spec.ts b/libs/common/src/lib/extensions/logger/logger-meta-reducer.spec.ts new file mode 100644 index 00000000..a947fd93 --- /dev/null +++ b/libs/common/src/lib/extensions/logger/logger-meta-reducer.spec.ts @@ -0,0 +1,33 @@ +import { Reducer } from '../../models'; +import { loggerMetaReducer } from './logger-meta-reducer'; + +describe('loggerMetaReducer', () => { + console.log = jest.fn(); + + it('should log action and state', () => { + const reducer: Reducer<{ counter: number }> = (state, action) => { + if (action.type === 'inc') { + return { + ...state, + counter: state.counter + 1, + }; + } + return state; + }; + + const reducerWithMetaReducer = loggerMetaReducer(reducer); + + const action = { type: 'inc' }; + + reducerWithMetaReducer({ counter: 1 }, action); + + expect(console.log).toHaveBeenCalledWith( + expect.stringContaining('inc'), + expect.stringContaining('color: #25c2a0'), + expect.stringContaining('Action:'), + action, + expect.stringContaining('State: '), + { counter: 2 } + ); + }); +}); diff --git a/libs/common/src/lib/extensions/logger/logger-meta-reducer.ts b/libs/common/src/lib/extensions/logger/logger-meta-reducer.ts new file mode 100644 index 00000000..39cd3713 --- /dev/null +++ b/libs/common/src/lib/extensions/logger/logger-meta-reducer.ts @@ -0,0 +1,21 @@ +import { Action, Reducer } from '../../models'; +import { beautifyAction } from '../../beautify-action'; + +export function loggerMetaReducer(reducer: Reducer): Reducer { + return (state, action) => { + const actionToLog: Action = beautifyAction(action); + + const nextState = reducer(state, action); + + console.log( + '%c' + action.type, + 'color: #25c2a0', + '\nAction:', + actionToLog, + '\nState: ', + nextState + ); + + return nextState; + }; +} diff --git a/libs/common/src/lib/extensions/logger/logger.extension.spec.ts b/libs/common/src/lib/extensions/logger/logger.extension.spec.ts new file mode 100644 index 00000000..e210979c --- /dev/null +++ b/libs/common/src/lib/extensions/logger/logger.extension.spec.ts @@ -0,0 +1,22 @@ +import { LoggerExtension } from './logger.extension'; +import { ExtensionId } from '../../enums'; + +describe('LoggerExtension', () => { + const instance = new LoggerExtension(); + + it('should support ComponentStore', () => { + expect(instance.hasCsSupport).toBe(true); + }); + + it('should have sort order', () => { + expect(instance.sortOrder).toBe(0); + }); + + it('should have id', () => { + expect(instance.id).toBe(ExtensionId.LOGGER); + }); + + it('should have an init method which returns a function', () => { + expect(typeof instance.init()).toBe('function'); + }); +}); diff --git a/libs/common/src/lib/extensions/logger/logger.extension.ts b/libs/common/src/lib/extensions/logger/logger.extension.ts new file mode 100644 index 00000000..e684f22d --- /dev/null +++ b/libs/common/src/lib/extensions/logger/logger.extension.ts @@ -0,0 +1,12 @@ +import { ComponentStoreExtension, MetaReducer, StoreExtension } from '../../models'; +import { ExtensionId } from '../../enums'; +import { loggerMetaReducer } from './logger-meta-reducer'; + +export class LoggerExtension extends StoreExtension implements ComponentStoreExtension { + id = ExtensionId.LOGGER; + hasCsSupport = true as const; + + init(): MetaReducer { + return loggerMetaReducer; + } +} diff --git a/libs/common/src/lib/extensions/redux-devtools/abstract-redux-devtools-extension.spec.ts b/libs/common/src/lib/extensions/redux-devtools/abstract-redux-devtools-extension.spec.ts new file mode 100644 index 00000000..611b93e8 --- /dev/null +++ b/libs/common/src/lib/extensions/redux-devtools/abstract-redux-devtools-extension.spec.ts @@ -0,0 +1,140 @@ +import { + AbstractReduxDevtoolsExtension, + ReduxDevtoolsOptions, +} from './abstract-redux-devtools-extension'; +import { ExtensionId } from '../../enums'; +import { Observable, Subject } from 'rxjs'; +import { Action, AppState } from '../../models'; +import { createMiniRxActionType, OperationType } from '../../create-mini-rx-action-type'; + +const win = window as any; +JSON.parse = jest.fn().mockImplementationOnce((data) => { + return data; +}); + +const action: Action = { type: 'counter' }; +const sendFn = jest.fn(); +const subscribeFn = jest.fn(); +const connectFn = jest.fn().mockImplementation(() => { + return { + subscribe: subscribeFn, + send: sendFn, + }; +}); + +const actions$ = new Subject(); +const initialState = { counter: 1 }; +let appState: AppState = initialState; +const updateState = jest.fn().mockImplementation((state) => { + appState = state; +}); +const resetState = () => (appState = initialState); + +class ReduxDevToolsExtension extends AbstractReduxDevtoolsExtension { + get actions$(): Observable { + return actions$; + } + + readState(): AppState { + return appState; + } + + updateState(state: AppState): void { + updateState(state); + } +} + +describe('AbstractReduxDevtoolsExtension', () => { + win.__REDUX_DEVTOOLS_EXTENSION__ = { + connect: connectFn, + }; + + const options: Partial = { + name: 'test', + maxAge: 50, + latency: 1000, + traceLimit: 25, + }; + const extension = new ReduxDevToolsExtension(options); + + beforeEach(() => { + sendFn.mockReset(); + }); + + it('should support ComponentStore', () => { + expect(extension).not.toHaveProperty('hasCsSupport'); + }); + + it('should have sort order', () => { + expect(extension.sortOrder).toBe(0); + }); + + it('should have id', () => { + expect(extension.id).toBe(ExtensionId.REDUX_DEVTOOLS); + }); + + it('should connect to Store', () => { + extension.init(); + + expect(connectFn).toHaveBeenCalledTimes(1); + expect(connectFn).toHaveBeenCalledWith(options); + expect(subscribeFn).toHaveBeenCalledTimes(1); + }); + + it('should receive state and actions', () => { + actions$.next(action); + + expect(sendFn).toHaveBeenCalledTimes(1); + expect(sendFn).toHaveBeenCalledWith(action, { counter: 1 }); + }); + + it('should update the Store state', () => { + const stateFromReduxDevTools = { + someProp: 'someValue', + }; + + extension['onDevToolsMessage']({ + type: 'DISPATCH', + payload: { + type: 'JUMP_TO_STATE', + }, + state: stateFromReduxDevTools, + }); + + expect(updateState).toHaveBeenCalledTimes(1); + expect(updateState).toHaveBeenCalledWith(stateFromReduxDevTools); + + updateState.mockReset(); + + extension['onDevToolsMessage']({ + type: 'NOT_SUPPORTED_TYPE', + payload: {}, + state: {}, + }); + + expect(updateState).toHaveBeenCalledTimes(0); + }); + + it('should receive state and a SetStateAction with only type and payload', () => { + resetState(); + + const stateOrCallback = () => ({ + firstName: 'Cage', + }); + + actions$.next({ + type: createMiniRxActionType(OperationType.SET_STATE, 'user'), + stateOrCallback, + featureId: 'abc', + }); + + expect(sendFn).toHaveBeenCalledTimes(1); + expect(sendFn).toHaveBeenCalledWith( + { + type: '@mini-rx/user/set-state', + payload: stateOrCallback, + }, + initialState + ); + }); +}); diff --git a/libs/common/src/lib/extensions/redux-devtools/abstract-redux-devtools-extension.ts b/libs/common/src/lib/extensions/redux-devtools/abstract-redux-devtools-extension.ts new file mode 100644 index 00000000..8dc030bb --- /dev/null +++ b/libs/common/src/lib/extensions/redux-devtools/abstract-redux-devtools-extension.ts @@ -0,0 +1,90 @@ +import { Action, AppState, StoreExtension } from '../../models'; +import { beautifyAction } from '../../beautify-action'; +import { miniRxError } from '../../mini-rx-error'; +import { Observable, tap } from 'rxjs'; +import { ExtensionId } from '../../enums'; + +const enum DevToolActions { + DISPATCH = 'DISPATCH', + JUMP_TO_STATE = 'JUMP_TO_STATE', + JUMP_TO_ACTION = 'JUMP_TO_ACTION', +} + +const defaultOptions: Partial = { + name: 'MiniRx - Redux DevTools', + traceLimit: 25, +}; + +export interface ReduxDevtoolsOptions { + name: string; + maxAge: number; + latency: number; + trace: boolean; + traceLimit: number; +} + +export abstract class AbstractReduxDevtoolsExtension extends StoreExtension { + id = ExtensionId.REDUX_DEVTOOLS; + + private readonly devtoolsExtension: any; + private devtoolsConnection: any; + private readonly _optionsForNgExtension: Partial; + + // sounds to much like Angular ;) + // Used only in mini-rx-store-ng + // TODO create a normal getter for options: get options() + get optionsForNgExtension(): Partial { + return this._optionsForNgExtension; + } + + constructor(private readonly options: Partial) { + super(); + + if (!window) { + miniRxError('The Redux DevTools are only supported in browser environments.'); + } + + this._optionsForNgExtension = options; + + this.devtoolsExtension = (window as any).__REDUX_DEVTOOLS_EXTENSION__; + + this.options = { + ...defaultOptions, + ...this.options, + }; + } + + init(): void { + if (this.devtoolsExtension) { + this.devtoolsConnection = this.devtoolsExtension.connect(this.options); + + this.actions$ + .pipe( + tap((action) => { + const appState = this.readState(); + const actionForDevTools: Action = beautifyAction(action); + this.devtoolsConnection.send(actionForDevTools, appState); + }) + ) + .subscribe(); + + this.devtoolsConnection.subscribe(this.onDevToolsMessage.bind(this)); + } + } + + private onDevToolsMessage(message: { type: string; payload: any; state: any }) { + if (message.type === DevToolActions.DISPATCH) { + switch (message.payload.type) { + case DevToolActions.JUMP_TO_STATE: + case DevToolActions.JUMP_TO_ACTION: + this.updateState(JSON.parse(message.state)); + } + } + } + + abstract updateState(state: AppState): void; + + abstract readState(): AppState; + + abstract get actions$(): Observable; +} diff --git a/libs/common/src/lib/extensions/undo/undo-extension.spec.ts b/libs/common/src/lib/extensions/undo/undo-extension.spec.ts new file mode 100644 index 00000000..faf66cff --- /dev/null +++ b/libs/common/src/lib/extensions/undo/undo-extension.spec.ts @@ -0,0 +1,22 @@ +import { UndoExtension } from './undo-extension'; +import { ExtensionId } from '../../enums'; + +describe('UndoExtension', () => { + const instance = new UndoExtension(); + + it('should support ComponentStore', () => { + expect(instance.hasCsSupport).toBe(true); + }); + + it('should have sort order', () => { + expect(instance.sortOrder).toBe(1); + }); + + it('should have id', () => { + expect(instance.id).toBe(ExtensionId.UNDO); + }); + + it('should have an init method which returns a function', () => { + expect(typeof instance.init()).toBe('function'); + }); +}); diff --git a/libs/common/src/lib/extensions/undo/undo-extension.ts b/libs/common/src/lib/extensions/undo/undo-extension.ts new file mode 100644 index 00000000..dbd50e81 --- /dev/null +++ b/libs/common/src/lib/extensions/undo/undo-extension.ts @@ -0,0 +1,45 @@ +// Credits go to Brecht Billiet +// Copied from: https://github.com/brechtbilliet/ngrx-undo/blob/master/src/handleUndo.ts +// Code has been modified to work with MiniRx + +// MIT License +// +// Copyright (c) 2016 Brecht Billiet +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import { ComponentStoreExtension, MetaReducer, StoreExtension } from '../../models'; +import { ExtensionId, ExtensionSortOrder } from '../../enums'; +import { createUndoMetaReducer } from './undo-meta-reducer'; + +const defaultBufferSize = 100; + +export class UndoExtension extends StoreExtension implements ComponentStoreExtension { + id = ExtensionId.UNDO; + override sortOrder = ExtensionSortOrder.UNDO_EXTENSION; + hasCsSupport = true as const; + + constructor(private config: { bufferSize: number } = { bufferSize: defaultBufferSize }) { + super(); + } + + init(): MetaReducer { + return createUndoMetaReducer(this.config.bufferSize); + } +} diff --git a/libs/common/src/lib/extensions/undo/undo-meta-reducer.spec.ts b/libs/common/src/lib/extensions/undo/undo-meta-reducer.spec.ts new file mode 100644 index 00000000..3d37aa28 --- /dev/null +++ b/libs/common/src/lib/extensions/undo/undo-meta-reducer.spec.ts @@ -0,0 +1,80 @@ +import { createUndoMetaReducer } from './undo-meta-reducer'; +import { Reducer, Action } from '../../models'; +import { undo } from './undo'; + +interface ActionWithPayload extends Action { + payload?: any; +} + +describe('createUndoMetaReducer', () => { + const undoMetaReducer = createUndoMetaReducer(100); + + function createAppendAction(payload: string): ActionWithPayload { + return { type: 'append', payload }; + } + + const appendReducer: Reducer<{ counter: string }> = ( + state = { counter: '1' }, + action: ActionWithPayload + ) => { + if (action.type === 'append') { + return { + ...state, + counter: state.counter + action.payload, + }; + } + return state; + }; + + const reducer = undoMetaReducer(appendReducer); + + it('should undo action', () => { + // Initial action is needed here to have at least one action in the `executedActions` Array (for calculating the `newState`) + let state = reducer(undefined, { type: 'init' }); + + const incrementAction = createAppendAction('2'); + state = reducer(state, incrementAction); + expect(state).toEqual({ counter: '12' }); + + state = reducer(state, undo(incrementAction)); + expect(state).toEqual({ counter: '1' }); + }); + + it('should undo action in the middle', () => { + // Initial action is needed here to have at least one action in the `executedActions` Array (for calculating the `newState`) + let state = reducer(undefined, { type: 'init' }); + + const append2Action = createAppendAction('2'); + state = reducer(state, append2Action); + expect(state).toEqual({ counter: '12' }); + + const append3Action = createAppendAction('3'); + state = reducer(state, append3Action); + expect(state).toEqual({ counter: '123' }); + + // Undo action in the middle + state = reducer(state, undo(append2Action)); + expect(state).toEqual({ counter: '13' }); + + const append4Action = createAppendAction('4'); + state = reducer(state, append4Action); + expect(state).toEqual({ counter: '134' }); + }); + + it('should buffer a limited amount of actions', () => { + const undoMetaReducer = createUndoMetaReducer(3); + const reducer = undoMetaReducer(appendReducer); + + let state = reducer(undefined, { type: 'init' }); + const append2Action = createAppendAction('2'); + state = reducer(state, append2Action); + state = reducer(state, createAppendAction('3')); + state = reducer(state, createAppendAction('4')); + state = reducer(state, createAppendAction('5')); + + // append2Action is not in the `executedActions` Array anymore, because of the small buffer-size (3) + // it is not possible anymore to undo append2Action: + state = reducer(state, undo(append2Action)); + expect(state).toEqual({ counter: '12345' }); + }); +}); diff --git a/libs/common/src/lib/extensions/undo/undo-meta-reducer.ts b/libs/common/src/lib/extensions/undo/undo-meta-reducer.ts new file mode 100644 index 00000000..56ae6ad2 --- /dev/null +++ b/libs/common/src/lib/extensions/undo/undo-meta-reducer.ts @@ -0,0 +1,37 @@ +import { Action, MetaReducer, Reducer } from '../../models'; +import { UNDO_ACTION } from './undo'; + +export function createUndoMetaReducer(bufferSize: number): MetaReducer { + let executedActions: Array = []; + let initialState: any; + + return (rootReducer: Reducer): Reducer => { + return (state: any, action: any) => { + if (action.type === UNDO_ACTION) { + // if the action is UNDO_ACTION, + // then call all the actions again on the rootReducer, + // except the one we want to rollback + let newState: any = initialState; + executedActions = executedActions.filter((eAct) => eAct !== action.payload); + // update the state for every action until we get the + // exact same state as before, but without the action we want to rollback + executedActions.forEach((executedAction) => { + newState = rootReducer(newState, executedAction); + }); + return newState; + } else { + // push every action that isn't UNDO_ACTION + executedActions.push(action); + } + const updatedState = rootReducer(state, action); + if (executedActions.length === bufferSize + 1) { + const firstAction = executedActions[0]; + // calculate the state x (bufferSize) actions ago + initialState = rootReducer(initialState, firstAction); + // keep the correct actions + executedActions = executedActions.slice(1, bufferSize + 1); + } + return updatedState; + }; + }; +} diff --git a/libs/common/src/lib/extensions/undo/undo.spec.ts b/libs/common/src/lib/extensions/undo/undo.spec.ts new file mode 100644 index 00000000..57c4769b --- /dev/null +++ b/libs/common/src/lib/extensions/undo/undo.spec.ts @@ -0,0 +1,10 @@ +import { undo } from './undo'; +import { Action } from '../../models'; + +describe('undo', () => { + it('should create an undo action', () => { + const actionToUndo: Action = { type: 'someAction' }; + + expect(undo(actionToUndo)).toEqual({ type: '@mini-rx/undo', payload: actionToUndo }); + }); +}); diff --git a/libs/common/src/lib/extensions/undo/undo.ts b/libs/common/src/lib/extensions/undo/undo.ts new file mode 100644 index 00000000..99c97535 --- /dev/null +++ b/libs/common/src/lib/extensions/undo/undo.ts @@ -0,0 +1,11 @@ +import { miniRxNameSpace } from '../../constants'; +import { Action } from '../../models'; + +export const UNDO_ACTION = miniRxNameSpace + '/undo'; + +export function undo(action: Action) { + return { + type: UNDO_ACTION, + payload: action, + }; +} diff --git a/libs/common/src/lib/generate-id.ts b/libs/common/src/lib/generate-id.ts new file mode 100644 index 00000000..455601c2 --- /dev/null +++ b/libs/common/src/lib/generate-id.ts @@ -0,0 +1,5 @@ +// Simple alpha numeric ID: https://stackoverflow.com/a/12502559/453959 +// This isn't a real GUID! +export function generateId(): string { + return Math.random().toString(36).slice(2); +} diff --git a/libs/common/src/lib/is-mini-rx-action.spec.ts b/libs/common/src/lib/is-mini-rx-action.spec.ts new file mode 100644 index 00000000..57c52218 --- /dev/null +++ b/libs/common/src/lib/is-mini-rx-action.spec.ts @@ -0,0 +1,19 @@ +import { isMiniRxAction } from './is-mini-rx-action'; +import { Action, MiniRxAction } from './models'; + +describe('isMiniRxAction', () => { + it('should detect MiniRx action', () => { + const action: MiniRxAction = { + type: '', + stateOrCallback: {}, + }; + + expect(isMiniRxAction(action)).toBe(true); + + const action2: Action = { + type: 'abc', + }; + + expect(isMiniRxAction(action2)).toBe(false); + }); +}); diff --git a/libs/common/src/lib/is-mini-rx-action.ts b/libs/common/src/lib/is-mini-rx-action.ts new file mode 100644 index 00000000..0f4bee24 --- /dev/null +++ b/libs/common/src/lib/is-mini-rx-action.ts @@ -0,0 +1,8 @@ +import { Action, MiniRxAction } from './models'; + +const stateOrCallbackKey: keyof MiniRxAction = 'stateOrCallback'; + +// Type predicate +export function isMiniRxAction(action: Action): action is MiniRxAction { + return Object.hasOwn(action, stateOrCallbackKey); +} diff --git a/libs/common/src/lib/map-response.spec.ts b/libs/common/src/lib/map-response.spec.ts new file mode 100644 index 00000000..d85ea127 --- /dev/null +++ b/libs/common/src/lib/map-response.spec.ts @@ -0,0 +1,104 @@ +import { concatMap, finalize, noop, Observable, of, throwError } from 'rxjs'; +import { Action } from './models'; +import { mapResponse } from './map-response'; + +describe('mapResponse', () => { + it('should invoke next callback on next', () => { + const nextCallback = jest.fn(); + + of(1, 2, 3).pipe(mapResponse(nextCallback, noop)).subscribe(); + + expect(nextCallback.mock.calls).toEqual([[1], [2], [3]]); + }); + + it('should invoke error callback on error', () => { + const nextCallback = jest.fn(); + const errorCallback = jest.fn(); + const error = { message: 'error' }; + + throwError(() => error) + .pipe(mapResponse(nextCallback, errorCallback)) + .subscribe(); + + expect(errorCallback).toHaveBeenCalledWith(error); + }); + + it('should not unsubscribe from outer observable on inner observable error', () => { + const innerCompleteCallback = jest.fn(); + const outerCompleteCallback = jest.fn(); + + new Observable((subscriber) => subscriber.next(1)) + .pipe( + concatMap(() => + throwError(() => 'error').pipe( + mapResponse(() => ({ type: 'some action' }), noop), + finalize(innerCompleteCallback) + ) + ), + finalize(outerCompleteCallback) + ) + .subscribe(); + + expect(innerCompleteCallback).toHaveBeenCalled(); + expect(outerCompleteCallback).not.toHaveBeenCalled(); + }); + + it('should return one action on next', () => { + const spy = jest.fn(); + + const action: Action = { type: 'action1' }; + + of(1) + .pipe(mapResponse(() => action, noop)) + .subscribe((v) => spy(v)); + + expect(spy.mock.calls).toEqual([[action]]); + }); + + it('should return many actions on next', () => { + const spy = jest.fn(); + + const action1: Action = { type: 'action1' }; + const action2: Action = { type: 'action2' }; + + of(1) + .pipe(mapResponse(() => [action1, action2], noop)) + .subscribe((v) => spy(v)); + + expect(spy.mock.calls).toEqual([[action1], [action2]]); + }); + + it('should (optionally) return one or many action on error', () => { + const nextCallback = jest.fn(); + const error = { message: 'error' }; + const action1: Action = { type: 'action1' }; + const action2: Action = { type: 'action1' }; + + const spy = jest.fn(); + + // One Action + throwError(() => error) + .pipe(mapResponse(nextCallback, () => action1)) + .subscribe(spy); + + expect(spy.mock.calls).toEqual([[action1]]); + + spy.mockReset(); + + // Many Actions + throwError(() => error) + .pipe(mapResponse(nextCallback, () => [action1, action2])) + .subscribe(spy); + + expect(spy.mock.calls).toEqual([[action1], [action2]]); + + spy.mockReset(); + + // No Action + throwError(() => error) + .pipe(mapResponse(nextCallback, noop)) + .subscribe(spy); + + expect(spy).not.toHaveBeenCalled(); + }); +}); diff --git a/libs/signal-store/src/lib/map-response.ts b/libs/common/src/lib/map-response.ts similarity index 83% rename from libs/signal-store/src/lib/map-response.ts rename to libs/common/src/lib/map-response.ts index 8eb1461a..e3f05992 100644 --- a/libs/signal-store/src/lib/map-response.ts +++ b/libs/common/src/lib/map-response.ts @@ -1,6 +1,5 @@ -import { EMPTY, from, Observable, of } from 'rxjs'; -import { catchError, map, mergeMap } from 'rxjs/operators'; -import { Action } from './models'; +import { EMPTY, from, Observable, of, catchError, map, mergeMap } from 'rxjs'; +import { Action } from '../lib/models'; export function mapResponse( mapFn: (next: T) => R1 | R1[], diff --git a/libs/common/src/lib/mini-rx-console-error.ts b/libs/common/src/lib/mini-rx-console-error.ts new file mode 100644 index 00000000..7e492923 --- /dev/null +++ b/libs/common/src/lib/mini-rx-console-error.ts @@ -0,0 +1,5 @@ +import { miniRxNameSpace } from './constants'; + +export function miniRxConsoleError(message: string, err: any): void { + console.error(miniRxNameSpace + ': ' + message + '\nDetails:', err); +} diff --git a/libs/common/src/lib/mini-rx-error.ts b/libs/common/src/lib/mini-rx-error.ts new file mode 100644 index 00000000..50d240ba --- /dev/null +++ b/libs/common/src/lib/mini-rx-error.ts @@ -0,0 +1,5 @@ +import { miniRxNameSpace } from './constants'; + +export function miniRxError(message: string): never { + throw new Error(miniRxNameSpace + ': ' + message); +} diff --git a/libs/common/src/lib/models.ts b/libs/common/src/lib/models.ts new file mode 100644 index 00000000..0ea9fc1e --- /dev/null +++ b/libs/common/src/lib/models.ts @@ -0,0 +1,68 @@ +import { Observable } from 'rxjs'; +import { ExtensionId, ExtensionSortOrder } from './enums'; + +export type AppState = Record; + +export abstract class StoreExtension { + abstract id: ExtensionId; + sortOrder: ExtensionSortOrder = ExtensionSortOrder.DEFAULT; + + abstract init(): MetaReducer | void; +} + +export interface ComponentStoreExtension extends StoreExtension { + init(): MetaReducer; +} + +export interface ComponentStoreConfig { + extensions: ComponentStoreExtension[]; +} + +export interface Action { + type: string; + // Allows any extra properties to be defined in an action. + [x: string]: any; +} + +export interface StoreConfig { + reducers?: ReducerDictionary; + initialState?: T; + metaReducers?: MetaReducer[]; + extensions?: StoreExtension[]; +} + +// Used for the Redux API: Store.feature / StoreModule.forFeature +export interface FeatureConfig { + initialState: StateType; + metaReducers?: MetaReducer[]; +} + +// Used for createFeatureStore, new FeatureStore +export interface FeatureStoreConfig { + multi?: boolean; +} + +export class Actions extends Observable {} + +export type Reducer = (state: StateType, action: Action) => StateType; + +export type MetaReducer = (reducer: Reducer) => Reducer; + +export type ReducerDictionary = { + [p in keyof T]: Reducer; +}; + +export type StateOrCallback = + | Partial + | ((state: StateType) => Partial); + +export type MiniRxAction = { + stateOrCallback: StateOrCallback; // Used in FeatureStore/ComponentStore reducer to calc new state + type: string; // The action type visible in DevTools / Logging Extension + featureId?: string; // Links the feature reducer to its corresponding FeatureStore +}; + +export interface ReducerState { + featureReducers: ReducerDictionary; + metaReducers: MetaReducer[]; +} diff --git a/libs/common/src/lib/of-type.spec.ts b/libs/common/src/lib/of-type.spec.ts new file mode 100644 index 00000000..22a7d3ff --- /dev/null +++ b/libs/common/src/lib/of-type.spec.ts @@ -0,0 +1,42 @@ +import { Action } from './models'; +import { ofType } from './of-type'; +import { Subject } from 'rxjs'; + +const action1: Action = { + type: 'updateUser', +}; + +const action2: Action = { + type: 'updateProduct', +}; + +describe('ofType', () => { + const actionsSubject = new Subject(); + + it('should filter by action type', () => { + const spy = jest.fn(); + actionsSubject.pipe(ofType('someType')).subscribe(spy); + + actionsSubject.next(action1); + + expect(spy).toHaveBeenCalledTimes(0); + + const spy2 = jest.fn(); + actionsSubject.pipe(ofType(action1.type)).subscribe(spy2); + + actionsSubject.next(action1); + + expect(spy2).toHaveBeenCalledWith(action1); + expect(spy2).toHaveBeenCalledTimes(1); + }); + + it('should allow many types', () => { + const spy = jest.fn(); + actionsSubject.pipe(ofType('someType', action1.type, action2.type)).subscribe(spy); + + actionsSubject.next(action1); + actionsSubject.next(action2); + + expect(spy).toHaveBeenCalledTimes(2); + }); +}); diff --git a/libs/common/src/lib/of-type.ts b/libs/common/src/lib/of-type.ts new file mode 100644 index 00000000..dee3ce66 --- /dev/null +++ b/libs/common/src/lib/of-type.ts @@ -0,0 +1,10 @@ +import { filter, OperatorFunction } from 'rxjs'; +import { Action } from './models'; + +export function ofType(...allowedTypes: string[]): OperatorFunction { + return filter((action: Action) => + allowedTypes.some((type) => { + return type === action.type; + }) + ); +} diff --git a/libs/common/src/lib/reducer-manager.spec.ts b/libs/common/src/lib/reducer-manager.spec.ts new file mode 100644 index 00000000..a91fc7c8 --- /dev/null +++ b/libs/common/src/lib/reducer-manager.spec.ts @@ -0,0 +1,197 @@ +import { createReducerManager } from './reducer-manager'; +import { Action, AppState, MetaReducer, Reducer } from './models'; + +type CounterState = { counter: number }; + +type CounterStringState = { counter: string }; + +interface ActionWithPayload extends Action { + payload?: any; +} + +const counterReducer: Reducer = (state = { counter: 1 }, action: Action) => { + switch (action.type) { + case 'inc': + return { + ...state, + counter: state.counter + 1, + }; + default: + return state; + } +}; + +const counterStringReducer: Reducer = ( + state = { counter: '1' }, + action: ActionWithPayload +) => { + switch (action.type) { + case 'inc': + return { + ...state, + counter: state.counter + action.payload, + }; + default: + return state; + } +}; + +describe('createReducerManager', () => { + it('should set feature reducers', () => { + const manager = createReducerManager(); + let nextState: AppState; + + manager.setFeatureReducers({ + feature1: counterReducer, + feature2: counterReducer, + feature3: counterReducer, + }); + + const reducer: Reducer = manager.getReducer(); + + nextState = reducer({}, { type: 'init' }); + expect(nextState).toEqual({ + feature1: { counter: 1 }, + feature2: { counter: 1 }, + feature3: { counter: 1 }, + }); + + nextState = reducer({}, { type: 'inc' }); + expect(nextState).toEqual({ + feature1: { counter: 2 }, + feature2: { counter: 2 }, + feature3: { counter: 2 }, + }); + }); + + it('should add feature reducers', () => { + const manager = createReducerManager(); + let nextState: AppState; + + manager.addFeatureReducer('feature1', counterReducer); + manager.addFeatureReducer('feature2', counterReducer); + + const reducer: Reducer = manager.getReducer(); + + nextState = reducer({}, { type: 'init' }); + expect(nextState).toEqual({ + feature1: { counter: 1 }, + feature2: { counter: 1 }, + }); + + nextState = reducer({}, { type: 'inc' }); + expect(nextState).toEqual({ + feature1: { counter: 2 }, + feature2: { counter: 2 }, + }); + }); + + it('should remove feature reducers', () => { + const manager = createReducerManager(); + let nextState: AppState; + + manager.setFeatureReducers({ + feature1: counterReducer, + feature2: counterReducer, + feature3: counterReducer, + }); + + let reducer: Reducer = manager.getReducer(); + + nextState = reducer({}, { type: 'init' }); + expect(nextState).toEqual({ + feature1: { counter: 1 }, + feature2: { counter: 1 }, + feature3: { counter: 1 }, + }); + + manager.removeFeatureReducer('feature2'); + + reducer = manager.getReducer(); + + nextState = reducer({}, { type: 'abc' }); // Any action triggers the recalculation of state + expect(nextState).toEqual({ + feature1: { counter: 1 }, + feature3: { counter: 1 }, + }); + }); + + it('should add meta reducers', () => { + const metaReducer: MetaReducer = (reducer) => { + return (state, action) => { + if (action.type === 'inc') { + state = { + ...state, + feature1: { + ...state['feature1'], + counter: state['feature1'].counter + '2', + }, + }; + } + return reducer(state, action); + }; + }; + + const metaReducerForFeature: MetaReducer = (reducer) => { + return (state, action) => { + if (action.type === 'inc') { + state = { + ...state, + counter: state.counter + '3', + }; + } + return reducer(state, action); + }; + }; + + const manager = createReducerManager(); + + manager.addFeatureReducer('feature1', counterStringReducer, [metaReducerForFeature]); + manager.addMetaReducers(metaReducer); + + const reducer: Reducer = manager.getReducer(); + let nextState: AppState; + + nextState = reducer({}, { type: 'init' }); + nextState = reducer(nextState, { type: 'inc', payload: '4' }); + + expect(nextState).toEqual({ + feature1: { + counter: '1234', // '1' from initial state, '2' from meta reducer, '3' from feature meta reducer, '4' from feature reducer + }, + }); + }); + + it('should throw if feature already exists', () => { + const manager = createReducerManager(); + + manager.setFeatureReducers({ + feature1: counterReducer, + }); + + expect(() => manager.addFeatureReducer('feature1', (state) => state)).toThrowError( + '@mini-rx: Feature "feature1" already exists.' + ); + }); + + it('should should add initial state to feature reducer', () => { + const manager = createReducerManager(); + + const reducerWithoutInitialState: Reducer = (state) => { + return state; + }; + + manager.addFeatureReducer('feature1', reducerWithoutInitialState, undefined, { + counter: 1, + }); + + const reducer: Reducer = manager.getReducer(); + const nextState = reducer({}, { type: 'init' }); + + expect(nextState).toEqual({ + feature1: { + counter: 1, + }, + }); + }); +}); diff --git a/libs/common/src/lib/reducer-manager.ts b/libs/common/src/lib/reducer-manager.ts new file mode 100644 index 00000000..275dbb0c --- /dev/null +++ b/libs/common/src/lib/reducer-manager.ts @@ -0,0 +1,96 @@ +import { AppState, MetaReducer, Reducer, ReducerDictionary, Action, ReducerState } from './models'; +import { combineMetaReducers } from './combine-meta-reducers'; +import { miniRxError } from './mini-rx-error'; +import { combineReducers } from './combine-reducers'; + +export type ReducerManager = ReturnType; + +function createReducerWithInitialState( + reducer: Reducer, + initialState: StateType +): Reducer { + return (state: StateType = initialState, action: Action): StateType => { + return reducer(state, action); + }; +} + +function omit>(object: T, keyToOmit: keyof T): Partial { + return Object.keys(object) + .filter((key) => key !== keyToOmit) + .reduce>((prevValue, key: keyof T) => { + prevValue[key] = object[key]; + return prevValue; + }, {}); +} + +export function createReducerManager() { + let state: ReducerState = { + featureReducers: {}, + metaReducers: [], + }; + + let reducer: Reducer; + + function _updateStateAndReducer(v: Partial): void { + state = { + ...state, + ...v, + }; + + const combinedMetaReducer: MetaReducer = combineMetaReducers(state.metaReducers); + const combinedReducer: Reducer = combineReducers(state.featureReducers); + reducer = combinedMetaReducer(combinedReducer); + } + + function setFeatureReducers(featureReducers: ReducerDictionary) { + _updateStateAndReducer({ featureReducers }); + } + + function addFeatureReducer( + featureKey: string, + reducer: Reducer, + metaReducers?: MetaReducer[], + initialState?: StateType + ): void { + if (Object.hasOwn(state.featureReducers, featureKey)) { + miniRxError(`Feature "${featureKey}" already exists.`); + } + + reducer = metaReducers?.length + ? combineMetaReducers(metaReducers)(reducer) + : reducer; + + if (initialState) { + reducer = createReducerWithInitialState(reducer, initialState); + } + + _updateStateAndReducer({ + featureReducers: { + ...state.featureReducers, + [featureKey]: reducer, + }, + }); + } + + function removeFeatureReducer(featureKey: string): void { + _updateStateAndReducer({ + featureReducers: omit(state.featureReducers, featureKey) as ReducerDictionary, + }); + } + + function addMetaReducers(...reducers: MetaReducer[]): void { + _updateStateAndReducer({ + metaReducers: [...state.metaReducers, ...reducers], + }); + } + + return { + setFeatureReducers, + addFeatureReducer, + removeFeatureReducer, + addMetaReducers, + getReducer: () => reducer, + // Exported for testing + _updateStateAndReducer, + }; +} diff --git a/libs/common/src/lib/sort-extensions.spec.ts b/libs/common/src/lib/sort-extensions.spec.ts new file mode 100644 index 00000000..8a2883cd --- /dev/null +++ b/libs/common/src/lib/sort-extensions.spec.ts @@ -0,0 +1,39 @@ +import { StoreExtension, MetaReducer } from './models'; +import { sortExtensions } from './sort-extensions'; + +describe('sortExtensions', () => { + class Extension1 implements StoreExtension { + id = 1; + sortOrder = 3; + init(): MetaReducer { + return (v) => v; + } + } + + class Extension2 implements StoreExtension { + id = 2; + sortOrder = 2; + init(): MetaReducer { + return (v) => v; + } + } + + class Extension3 implements StoreExtension { + id = 3; + sortOrder = 1; + init(): MetaReducer { + return (v) => v; + } + } + + it('should sort extensions', () => { + const extensions = [new Extension1(), new Extension2(), new Extension3()]; + expect(sortExtensions(extensions)).toEqual( + expect.objectContaining([ + { id: 3, sortOrder: 1 }, + { id: 2, sortOrder: 2 }, + { id: 1, sortOrder: 3 }, + ]) + ); + }); +}); diff --git a/libs/common/src/lib/sort-extensions.ts b/libs/common/src/lib/sort-extensions.ts new file mode 100644 index 00000000..411fb489 --- /dev/null +++ b/libs/common/src/lib/sort-extensions.ts @@ -0,0 +1,7 @@ +import { StoreExtension } from './models'; + +export function sortExtensions(extensions: T[]): T[] { + return [...extensions].sort((a, b) => { + return a.sortOrder - b.sortOrder; + }); +} diff --git a/libs/common/src/lib/tap-response.spec.ts b/libs/common/src/lib/tap-response.spec.ts new file mode 100644 index 00000000..8265ffa1 --- /dev/null +++ b/libs/common/src/lib/tap-response.spec.ts @@ -0,0 +1,193 @@ +// Credits go to NgRx +// Copied from with small modifications: https://github.com/ngrx/platform/blob/13.2.0/modules/component-store/spec/tap-response.spec.ts + +// The MIT License (MIT) +// +// Copyright (c) 2017 Brandon Roberts, Mike Ryan, Victor Savkin, Rob Wormald +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all +// copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +// SOFTWARE. + +import { concatMap, EMPTY, finalize, noop, Observable, of, throwError } from 'rxjs'; +import { tapResponse } from './tap-response'; + +describe('tapResponse', () => { + it('should invoke next callback on next', () => { + const nextCallback = jest.fn(); + + of(1, 2, 3).pipe(tapResponse(nextCallback, noop)).subscribe(); + + expect(nextCallback.mock.calls).toEqual([[1], [2], [3]]); + + nextCallback.mockReset(); + + // with object parameter + of(1, 2, 3) + .pipe(tapResponse({ next: nextCallback, error: noop })) + .subscribe(); + + expect(nextCallback.mock.calls).toEqual([[1], [2], [3]]); + }); + + it('should invoke error callback on error', () => { + const errorCallback = jest.fn(); + const error = { message: 'error' }; + + throwError(() => error) + .pipe(tapResponse(noop, errorCallback)) + .subscribe(); + + expect(errorCallback).toHaveBeenCalledWith(error); + + errorCallback.mockReset(); + + // with object parameter + throwError(() => error) + .pipe(tapResponse({ error: errorCallback })) + .subscribe(); + + expect(errorCallback).toHaveBeenCalledWith(error); + }); + + it('should invoke finalize callback on complete', () => { + const finalizeCallback = jest.fn(); + + EMPTY.pipe(tapResponse(noop, noop, finalizeCallback)).subscribe(); + + expect(finalizeCallback).toHaveBeenCalledWith(); + + finalizeCallback.mockReset(); + + // with object parameter + EMPTY.pipe( + tapResponse({ next: noop, error: noop, finalize: finalizeCallback }) + ).subscribe(); + + expect(finalizeCallback).toHaveBeenCalledWith(); + }); + + it('should invoke finalize callback on error', () => { + const finalizeCallback = jest.fn(); + const error = { message: 'error' }; + + throwError(() => error) + .pipe(tapResponse(noop, noop, finalizeCallback)) + .subscribe(); + + expect(finalizeCallback).toHaveBeenCalledWith(); + + finalizeCallback.mockReset(); + + // with object parameter + throwError(() => error) + .pipe(tapResponse({ next: noop, error: noop, finalize: finalizeCallback })) + .subscribe(); + + expect(finalizeCallback).toHaveBeenCalledWith(); + }); + + it('should first invoke next callback on next then finalize callback on complete', () => { + const nextCallback = jest.fn(); + const finalizeCallback = jest.fn(); + + of(1).pipe(tapResponse(nextCallback, noop, finalizeCallback)).subscribe(); + + expect(nextCallback.mock.invocationCallOrder[0]).toBeLessThan( + finalizeCallback.mock.invocationCallOrder[0] + ); + }); + + it('should not unsubscribe from outer observable on inner observable error', () => { + const innerCompleteCallback = jest.fn(); + const outerCompleteCallback = jest.fn(); + + new Observable((subscriber) => subscriber.next(1)) + .pipe( + concatMap(() => + throwError(() => 'error').pipe( + tapResponse(noop, noop), + finalize(innerCompleteCallback) + ) + ), + finalize(outerCompleteCallback) + ) + .subscribe(); + + expect(innerCompleteCallback).toHaveBeenCalled(); + expect(outerCompleteCallback).not.toHaveBeenCalled(); + }); + + it('should log an error which occurs in the next callback', () => { + console.error = jest.fn(); + + of(1) + .pipe( + tapResponse({ + next: () => { + throw new Error('next_error'); + }, + error: noop, + }) + ) + .subscribe(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining('An error occurred in the `tapResponse` next callback'), + expect.any(Error) + ); + }); + + it('should log an error which occurs in the error callback', () => { + console.error = jest.fn(); + + throwError(() => 'An error') + .pipe( + tapResponse({ + error: () => { + throw new Error('error_error'); + }, + }) + ) + .subscribe(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining('An error occurred in the `tapResponse` error callback'), + expect.any(Error) + ); + }); + + it('should log an error which occurs in the finalize callback', () => { + console.error = jest.fn(); + + of(1) + .pipe( + tapResponse({ + error: noop, + finalize: () => { + throw new Error('finalize_error'); + }, + }) + ) + .subscribe(); + + expect(console.error).toHaveBeenCalledWith( + expect.stringContaining('An error occurred in the `tapResponse` finalize callback'), + expect.any(Error) + ); + }); +}); diff --git a/libs/signal-store/src/lib/tap-response.ts b/libs/common/src/lib/tap-response.ts similarity index 95% rename from libs/signal-store/src/lib/tap-response.ts rename to libs/common/src/lib/tap-response.ts index 8ca49c44..b4d15abc 100644 --- a/libs/signal-store/src/lib/tap-response.ts +++ b/libs/common/src/lib/tap-response.ts @@ -23,9 +23,8 @@ // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE // SOFTWARE. -import { EMPTY, identity, Observable } from 'rxjs'; -import { catchError, finalize, tap } from 'rxjs/operators'; -import { miniRxConsoleError } from './utils'; +import { EMPTY, identity, Observable, catchError, finalize, tap } from 'rxjs'; +import { miniRxConsoleError } from './mini-rx-console-error'; type TapResponseObj = { next?: (next: T) => void; diff --git a/libs/common/tsconfig.json b/libs/common/tsconfig.json new file mode 100644 index 00000000..aca05935 --- /dev/null +++ b/libs/common/tsconfig.json @@ -0,0 +1,23 @@ +{ + "extends": "../../tsconfig.base.json", + "compilerOptions": { + "lib": ["es2022", "dom"], + "target": "ES2022", + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitOverride": true, + "noPropertyAccessFromIndexSignature": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true + }, + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ] +} diff --git a/libs/common/tsconfig.lib.json b/libs/common/tsconfig.lib.json new file mode 100644 index 00000000..1f35c1fb --- /dev/null +++ b/libs/common/tsconfig.lib.json @@ -0,0 +1,11 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "declaration": true, + "types": [], + "stripInternal": true + }, + "include": ["src/**/*.ts"], + "exclude": ["jest.config.ts", "src/**/*.spec.ts", "src/**/*.test.ts"] +} diff --git a/libs/common/tsconfig.spec.json b/libs/common/tsconfig.spec.json new file mode 100644 index 00000000..c354ed63 --- /dev/null +++ b/libs/common/tsconfig.spec.json @@ -0,0 +1,9 @@ +{ + "extends": "./tsconfig.json", + "compilerOptions": { + "outDir": "../../dist/out-tsc", + "module": "commonjs", + "types": ["jest", "node"] + }, + "include": ["jest.config.ts", "src/**/*.test.ts", "src/**/*.spec.ts", "src/**/*.d.ts"] +} diff --git a/libs/mini-rx-store/tsconfig.json b/libs/mini-rx-store/tsconfig.json index 8040de51..d9c4d40b 100644 --- a/libs/mini-rx-store/tsconfig.json +++ b/libs/mini-rx-store/tsconfig.json @@ -1,21 +1,23 @@ { - "extends": "../../tsconfig.base.json", - "files": [], - "include": [], - "references": [ - { - "path": "./tsconfig.lib.json" - }, - { - "path": "./tsconfig.spec.json" + "extends": "../../tsconfig.base.json", + "files": [], + "include": [], + "references": [ + { + "path": "./tsconfig.lib.json" + }, + { + "path": "./tsconfig.spec.json" + } + ], + "compilerOptions": { + "target": "es2015", + "lib": ["es2017", "dom"], + "forceConsistentCasingInFileNames": true, + "strict": true, + "noImplicitReturns": true, + "noFallthroughCasesInSwitch": true, + "allowSyntheticDefaultImports": true, + "esModuleInterop": true } - ], - "compilerOptions": { - "forceConsistentCasingInFileNames": true, - "strict": true, - "noImplicitReturns": true, - "noFallthroughCasesInSwitch": true, - "allowSyntheticDefaultImports": true, - "esModuleInterop": true - } } diff --git a/libs/signal-store/package.json b/libs/signal-store/package.json index 5ecf6aa5..41c8a4eb 100644 --- a/libs/signal-store/package.json +++ b/libs/signal-store/package.json @@ -1,6 +1,6 @@ { "name": "@mini-rx/signal-store", - "version": "0.0.6", + "version": "0.0.15", "author": "Florian Spier (https://florian-spier.be)", "license": "MIT", "homepage": "https://github.com/spierala/mini-rx-store", @@ -25,6 +25,7 @@ "peerDependencies": { "@angular/common": "^16.0.0", "@angular/core": "^16.0.0", + "@mini-rx/common": "^0.0.2", "rxjs": "^6.4.0 || ^7.0.0" }, "dependencies": { diff --git a/libs/signal-store/src/index.ts b/libs/signal-store/src/index.ts index 9b2c4ca6..44757705 100644 --- a/libs/signal-store/src/index.ts +++ b/libs/signal-store/src/index.ts @@ -10,6 +10,18 @@ export { createFeatureStateSelector, createComponentStateSelector, } from './lib/signal-selector'; +export { ReduxDevtoolsExtension } from './lib/extensions/redux-devtools.extension'; +export { StoreRootModule, StoreModule, StoreFeatureModule } from './lib/modules/store.module'; +export { EffectsModule } from './lib/modules/effects.module'; +export { ComponentStoreModule } from './lib/modules/component-store.module'; +export { + provideStore, + provideFeature, + provideEffects, + provideComponentStoreConfig, +} from './lib/providers'; + +// Re-export from @mini-rx/common export { Action, Reducer, @@ -19,26 +31,12 @@ export { FeatureStoreConfig, ComponentStoreConfig, StoreExtension, -} from './lib/models'; -export { ofType } from './lib/utils'; -export { - ReduxDevtoolsExtension, + undo, + tapResponse, + createRxEffect, + LoggerExtension, + ImmutableStateExtension, + UndoExtension, + mapResponse, ReduxDevtoolsOptions, -} from './lib/extensions/redux-devtools.extension'; -export { LoggerExtension } from './lib/extensions/logger.extension'; -export { ImmutableStateExtension } from './lib/extensions/immutable-state.extension'; -export { UndoExtension } from './lib/extensions/undo.extension'; -export { tapResponse } from './lib/tap-response'; -export { mapResponse } from './lib/map-response'; -export { createRxEffect } from './lib/create-rx-effect'; -export { undo } from './lib/actions'; - -export { StoreRootModule, StoreModule, StoreFeatureModule } from './lib/modules/store.module'; -export { EffectsModule } from './lib/modules/effects.module'; -export { ComponentStoreModule } from './lib/modules/component-store.module'; -export { - provideStore, - provideFeature, - provideEffects, - provideComponentStoreConfig, -} from './lib/providers'; +} from '@mini-rx/common'; diff --git a/libs/signal-store/src/lib/actions-on-queue.ts b/libs/signal-store/src/lib/actions-on-queue.ts deleted file mode 100644 index 235d9f30..00000000 --- a/libs/signal-store/src/lib/actions-on-queue.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { queueScheduler, Subject } from 'rxjs'; -import { observeOn } from 'rxjs/operators'; -import { Action, Actions } from './models'; - -export class ActionsOnQueue { - private actionsSource = new Subject(); - actions$: Actions = this.actionsSource.asObservable().pipe( - observeOn(queueScheduler) // Prevent stack overflow: https://blog.cloudboost.io/so-how-does-rx-js-queuescheduler-actually-work-188c1b46526e - ); - - dispatch(action: Action) { - this.actionsSource.next(action); - } -} diff --git a/libs/signal-store/src/lib/actions.ts b/libs/signal-store/src/lib/actions.ts deleted file mode 100644 index 24842eac..00000000 --- a/libs/signal-store/src/lib/actions.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { Action, StateOrCallback } from './models'; -import { miniRxNameSpace } from './constants'; - -export const enum OperationType { - INIT = 'init', - DESTROY = 'destroy', - SET_STATE = 'set-state', - CONNECTION = 'connection', -} - -export const enum StoreType { - FEATURE_STORE = '@mini-rx/feature-store', - COMPONENT_STORE = '@mini-rx/component-store', -} - -export type MiniRxAction = { - storeType: StoreType; // Used for type predicate `isFeatureStoreSetStateAction` - stateOrCallback: StateOrCallback; // Used in feature reducer to calc new state - type: string; // The action type visible in DevTools / Logging Extension (really only for logging!) - featureId?: string; // Links the feature reducer to its corresponding FeatureStore -}; - -export function createMiniRxActionType( - operationType: OperationType, - featureKey?: string, - name?: string -): string { - return ( - miniRxNameSpace + - (featureKey ? '/' + featureKey : '') + - '/' + - operationType + - (name ? '/' + name : '') - ); -} - -const storeTypeKey: keyof MiniRxAction = 'storeType'; - -// Type predicate -export function isMiniRxAction( - action: Action, - storeType: StoreType -): action is MiniRxAction { - return action[storeTypeKey] === storeType; -} - -export const UNDO_ACTION = miniRxNameSpace + '/undo'; - -export function undo(action: Action) { - return { - type: UNDO_ACTION, - payload: action, - }; -} diff --git a/libs/signal-store/src/lib/base-store.ts b/libs/signal-store/src/lib/base-store.ts deleted file mode 100644 index 273fbb3e..00000000 --- a/libs/signal-store/src/lib/base-store.ts +++ /dev/null @@ -1,95 +0,0 @@ -import { isObservable, Observable, Subject } from 'rxjs'; -import { Action, StateOrCallback } from './models'; -import { defaultEffectsErrorHandler } from './default-effects-error-handler'; -import { DestroyRef, EnvironmentInjector, inject, Injectable, Signal } from '@angular/core'; -import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'; -import { miniRxIsSignal } from './utils'; -import { OperationType, MiniRxAction } from './actions'; - -// BaseStore is extended by ComponentStore/FeatureStore -@Injectable() -export abstract class BaseStore { - private _injector = inject(EnvironmentInjector); - - /** @internal - * Used here and by ComponentStore/FeatureStore - */ - protected _destroyRef = inject(DestroyRef); - - update(stateOrCallback: StateOrCallback, name?: string): Action { - return this._dispatchSetStateAction(stateOrCallback, OperationType.SET_STATE, name); - } - - /** @internal - * Implemented by ComponentStore/FeatureStore - */ - abstract _dispatchSetStateAction( - stateOrCallback: StateOrCallback, - actionType: OperationType, - name?: string - ): MiniRxAction; - - // Implemented by ComponentStore/FeatureStore - abstract undo(action: Action): void; - - rxEffect< - // Credits for the typings go to NgRx (Component Store): https://github.com/ngrx/platform/blob/13.1.0/modules/component-store/src/component-store.ts#L279-L291 - ProvidedType = void, - // The actual origin$ type, which could be unknown, when not specified - OriginType extends Observable | unknown = Observable, - // Unwrapped actual type of the origin$ Observable, after default was applied - ObservableType = OriginType extends Observable ? A : never, - // Return either an empty callback or a function requiring specific types as inputs - ReturnType = ProvidedType | ObservableType extends void - ? () => void - : ( - observableOrValue: - | ObservableType - | Observable - | Signal - ) => void - >(effectFn: (origin$: OriginType) => Observable): ReturnType { - const subject = new Subject(); - const effect$ = effectFn(subject as OriginType); - const effectWithDefaultErrorHandler = defaultEffectsErrorHandler(effect$); - - effectWithDefaultErrorHandler.pipe(takeUntilDestroyed(this._destroyRef)).subscribe(); - - return (( - observableOrValue?: ObservableType | Observable | Signal - ) => { - // If we detect a Signal: convert Signal to Observable - observableOrValue = miniRxIsSignal(observableOrValue) - ? toObservable(observableOrValue) - : observableOrValue; - - isObservable(observableOrValue) - ? observableOrValue - .pipe(takeUntilDestroyed(this._destroyRef)) - .subscribe((v) => subject.next(v)) - : subject.next(observableOrValue as ObservableType); - }) as unknown as ReturnType; - } - - connect( - dict: Record | Signal> - ): void { - const keys: K[] = Object.keys(dict) as K[]; - - keys.forEach((key) => { - const observableOrSignal: Observable | Signal = dict[key]; - const obs$ = miniRxIsSignal(observableOrSignal) - ? toObservable(observableOrSignal, { injector: this._injector }) - : observableOrSignal; - obs$.pipe(takeUntilDestroyed(this._destroyRef)).subscribe((v) => { - this._dispatchSetStateAction( - { - [key]: v, - } as unknown as Partial, - OperationType.CONNECTION, - key as string - ); - }); - }); - } -} diff --git a/libs/signal-store/src/lib/component-store.ts b/libs/signal-store/src/lib/component-store.ts index d5c35a9b..40626749 100644 --- a/libs/signal-store/src/lib/component-store.ts +++ b/libs/signal-store/src/lib/component-store.ts @@ -1,178 +1,94 @@ -import { BaseStore } from './base-store'; +import { DestroyRef, inject, Signal, signal, WritableSignal } from '@angular/core'; +import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; import { Action, + calculateExtensions, + combineMetaReducers, + componentStoreConfig, ComponentStoreConfig, ComponentStoreExtension, - ComponentStoreLike, + createActionsOnQueue, + createComponentStoreReducer, + createMiniRxActionType, ExtensionId, MetaReducer, - Reducer, - StateOrCallback, -} from './models'; -import { calcNewState, combineMetaReducers, miniRxError, sortExtensions } from './utils'; -import { - createMiniRxActionType, - isMiniRxAction, - OperationType, MiniRxAction, - StoreType, + miniRxError, + OperationType, + StateOrCallback, undo, -} from './actions'; -import { ActionsOnQueue } from './actions-on-queue'; -import { SelectableSignalState } from './selectable-signal-state'; -import { Signal, signal, WritableSignal } from '@angular/core'; -import { takeUntilDestroyed } from '@angular/core/rxjs-interop'; - -let componentStoreConfig: ComponentStoreConfig | undefined = undefined; +} from '@mini-rx/common'; +import { createSelectableSignalState } from './selectable-signal-state'; +import { ComponentStoreLike } from './models'; +import { createRxEffectFn } from './rx-effect'; +import { createConnectFn } from './connect'; +import { createUpdateFn } from './update'; -// This function exists for testing purposes only -export function _resetConfig() { - componentStoreConfig = undefined; -} +const csFeatureKey = 'component-store'; +export const globalCsConfig = componentStoreConfig(); -export function configureComponentStores(config: ComponentStoreConfig) { - if (!componentStoreConfig) { - componentStoreConfig = config; - return; - } - miniRxError('`configureComponentStores` was called multiple times.'); -} +export class ComponentStore implements ComponentStoreLike { + private readonly hasUndoExtension: boolean = false; -const csFeatureKey = 'component-store'; + private actionsOnQueue = createActionsOnQueue(); -export class ComponentStore - extends BaseStore - implements ComponentStoreLike -{ - private actionsOnQueue = new ActionsOnQueue(); private _state: WritableSignal = signal(this.initialState); - private selectableState = new SelectableSignalState(this._state); + private selectableState = createSelectableSignalState(this._state); state: Signal = this.selectableState.select(); - private readonly combinedMetaReducer: MetaReducer; - private readonly reducer: Reducer; - private hasUndoExtension = false; - private extensions: ComponentStoreExtension[] = []; // This is a class property just for testing purposes - - constructor(private initialState: StateType, config?: ComponentStoreConfig) { - super(); - - this._destroyRef.onDestroy(() => this.destroy()); - - const metaReducers: MetaReducer[] = []; - - if (config?.extensions) { - if (config.extensions && componentStoreConfig?.extensions) { - this.extensions = mergeExtensions( - componentStoreConfig.extensions, - config.extensions - ); - } else { - this.extensions = config.extensions; - } - } else if (componentStoreConfig?.extensions) { - this.extensions = componentStoreConfig.extensions; - } - - sortExtensions(this.extensions).forEach((ext) => { - if (!ext.hasCsSupport) { - miniRxError( - `Extension "${ext.constructor.name}" is not supported by Component Store.` - ); - } - - metaReducers.push(ext.init()!); // Non-null assertion: Here we know for sure: init will return a MetaReducer - - if (ext.id === ExtensionId.UNDO) { - this.hasUndoExtension = true; - } - }); - - this.combinedMetaReducer = combineMetaReducers(metaReducers); - - this.reducer = this.combinedMetaReducer(createComponentStoreReducer(initialState)); - this.actionsOnQueue.actions$.pipe(takeUntilDestroyed()).subscribe((action) => { - const newState: StateType = this.reducer(this.state(), action); - this._state.set(newState); - }); - - this.dispatch({ type: createMiniRxActionType(OperationType.INIT, csFeatureKey) }); - } - - /** @internal - * Implementation of abstract method from BaseStore - */ - _dispatchSetStateAction( + private dispatcher( stateOrCallback: StateOrCallback, - actionType: OperationType, + operationType: OperationType, name: string | undefined ): MiniRxAction { const action: MiniRxAction = { - storeType: StoreType.COMPONENT_STORE, - type: createMiniRxActionType(actionType, csFeatureKey, name), + type: createMiniRxActionType(operationType, csFeatureKey, name), stateOrCallback, }; - this.dispatch(action); + this.actionsOnQueue.dispatch(action); return action; } - private dispatch(action: Action): void { - this.actionsOnQueue.dispatch(action); + constructor(private initialState: StateType, config?: ComponentStoreConfig) { + const extensions: ComponentStoreExtension[] = calculateExtensions( + config, + globalCsConfig.get() + ); + const metaReducers: MetaReducer[] = extensions.map((ext) => ext.init()); + this.hasUndoExtension = extensions.some((ext) => ext.id === ExtensionId.UNDO); + + const combinedMetaReducer = combineMetaReducers(metaReducers); + const reducer = combinedMetaReducer(createComponentStoreReducer(initialState)); + + this.actionsOnQueue.actions$.pipe(takeUntilDestroyed()).subscribe((action) => { + const newState: StateType = reducer(this.state(), action); + this._state.set(newState); + }); + + this.actionsOnQueue.dispatch({ + type: createMiniRxActionType(OperationType.INIT, csFeatureKey), + }); + + inject(DestroyRef).onDestroy(() => this.destroy()); } - // Implementation of abstract method from BaseStore undo(action: Action): void { this.hasUndoExtension - ? this.dispatch(undo(action)) + ? this.actionsOnQueue.dispatch(undo(action)) : miniRxError(`${this.constructor.name} has no UndoExtension yet.`); } - select = this.selectableState.select.bind(this.selectableState); + setState = createUpdateFn(this.dispatcher.bind(this)); + connect = createConnectFn(this.dispatcher.bind(this)); + rxEffect = createRxEffectFn(); + select = this.selectableState.select; private destroy(): void { // Dispatch an action really just for logging via LoggerExtension - this.dispatch({ type: createMiniRxActionType(OperationType.DESTROY, csFeatureKey) }); - } -} - -function createComponentStoreReducer(initialState: StateType): Reducer { - return (state: StateType = initialState, action: Action) => { - if (isMiniRxAction(action, StoreType.COMPONENT_STORE)) { - return calcNewState(state, action.stateOrCallback); - } - return state; - }; -} - -function mergeExtensions( - global: ComponentStoreExtension[], - local: ComponentStoreExtension[] -): ComponentStoreExtension[] { - // Local extensions overwrite the global extensions - // If extension is global and local => use local - // If extension is only global => use global - // If extension is only local => use local - - const extensions: ComponentStoreExtension[] = []; - let globalCopy = [...global]; - let localCopy = [...local]; - - global.forEach((globalExt) => { - local.forEach((localExt) => { - if (localExt.id === globalExt.id) { - // Found extension which is global and local - extensions.push(localExt); // Use local! - localCopy = localCopy.filter((item) => item.id !== localExt.id); // Remove found extension from local - globalCopy = globalCopy.filter((item) => item.id !== globalExt.id); // Remove found extension from global - } + this.actionsOnQueue.dispatch({ + type: createMiniRxActionType(OperationType.DESTROY, csFeatureKey), }); - }); - - return [ - ...extensions, // Extensions which are global and local, but use local - ...localCopy, // Local only - ...globalCopy, // Global only - ]; + } } export function createComponentStore( diff --git a/libs/signal-store/src/lib/connect.ts b/libs/signal-store/src/lib/connect.ts new file mode 100644 index 00000000..e1e6fdaf --- /dev/null +++ b/libs/signal-store/src/lib/connect.ts @@ -0,0 +1,40 @@ +import { Action, OperationType, StateOrCallback } from '@mini-rx/common'; +import { DestroyRef, EnvironmentInjector, inject, Signal } from '@angular/core'; +import { Observable } from 'rxjs'; +import { miniRxIsSignal } from './utils'; +import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'; + +export function createConnectFn( + dispatch: ( + stateOrCallback: StateOrCallback, + operationType: OperationType, + name: string | undefined + ) => Action +) { + const injector = inject(EnvironmentInjector); + const destroyRef = inject(DestroyRef); + + function connect( + dict: Record | Signal> + ): void { + const keys: K[] = Object.keys(dict) as K[]; + + keys.forEach((key) => { + const observableOrSignal: Observable | Signal = dict[key]; + const obs$ = miniRxIsSignal(observableOrSignal) + ? toObservable(observableOrSignal, { injector }) + : observableOrSignal; + obs$.pipe(takeUntilDestroyed(destroyRef)).subscribe((v) => { + dispatch( + { + [key]: v, + } as unknown as Partial, + OperationType.CONNECTION, + key as string + ); + }); + }); + } + + return connect; +} diff --git a/libs/signal-store/src/lib/modules/effects-mapper.ts b/libs/signal-store/src/lib/effects-mapper.ts similarity index 97% rename from libs/signal-store/src/lib/modules/effects-mapper.ts rename to libs/signal-store/src/lib/effects-mapper.ts index 12204df5..ac805f65 100644 --- a/libs/signal-store/src/lib/modules/effects-mapper.ts +++ b/libs/signal-store/src/lib/effects-mapper.ts @@ -25,7 +25,7 @@ import { ClassProvider, InjectionToken, Type } from '@angular/core'; import { Observable } from 'rxjs'; -import { hasEffectMetaData } from '../utils'; +import { hasEffectMetaData } from '@mini-rx/common'; export const fromClassesWithEffectsToClassProviders = ( injectionToken: InjectionToken, diff --git a/libs/signal-store/src/lib/extensions/logger.extension.ts b/libs/signal-store/src/lib/extensions/logger.extension.ts deleted file mode 100644 index 729693e7..00000000 --- a/libs/signal-store/src/lib/extensions/logger.extension.ts +++ /dev/null @@ -1,37 +0,0 @@ -import { - Action, - ExtensionId, - HasComponentStoreSupport, - MetaReducer, - Reducer, - StoreExtension, -} from '../models'; -import { beautifyActionForLogging } from '../utils'; - -export class LoggerExtension extends StoreExtension implements HasComponentStoreSupport { - id = ExtensionId.LOGGER; - hasCsSupport = true as const; - - init(): MetaReducer { - return loggerMetaReducer; - } -} - -function loggerMetaReducer(reducer: Reducer): Reducer { - return (state, action) => { - const actionToLog: Action = beautifyActionForLogging(action, state); - - const nextState = reducer(state, action); - - console.log( - '%c' + action.type, - 'color: #25c2a0', - '\nAction:', - actionToLog, - '\nState: ', - nextState - ); - - return nextState; - }; -} diff --git a/libs/signal-store/src/lib/extensions/redux-devtools.extension.ts b/libs/signal-store/src/lib/extensions/redux-devtools.extension.ts index 007d3a7d..a5e9b815 100644 --- a/libs/signal-store/src/lib/extensions/redux-devtools.extension.ts +++ b/libs/signal-store/src/lib/extensions/redux-devtools.extension.ts @@ -1,88 +1,18 @@ -import { tap } from 'rxjs/operators'; -import { Action, AppState, ExtensionId, StoreExtension } from '../models'; -import { actions$, selectableAppState, updateAppState } from '../store-core'; -import { beautifyActionForLogging, miniRxError } from '../utils'; +import { Action, AppState, AbstractReduxDevtoolsExtension } from '@mini-rx/common'; +import { Observable } from 'rxjs'; +import { actions$, select, updateAppState } from '../store-core'; -const defaultOptions: Partial = { - name: 'MiniRx - Redux DevTools', - traceLimit: 25, -}; - -export interface ReduxDevtoolsOptions { - name: string; - maxAge: number; - latency: number; - trace: boolean; - traceLimit: number; -} - -export class ReduxDevtoolsExtension extends StoreExtension { - id = ExtensionId.REDUX_DEVTOOLS; - - private readonly devtoolsExtension: any; - private devtoolsConnection: any; - private readonly _optionsForNgExtension: Partial; - - get optionsForNgExtension(): Partial { - return this._optionsForNgExtension; +export class ReduxDevtoolsExtension extends AbstractReduxDevtoolsExtension { + get actions$(): Observable { + return actions$; } - constructor(private readonly options: Partial) { - super(); - - if (!window) { - miniRxError('The Redux DevTools are only supported in browser environments.'); - } - - this._optionsForNgExtension = options; - - this.devtoolsExtension = (window as any).__REDUX_DEVTOOLS_EXTENSION__; - - this.options = { - ...defaultOptions, - ...this.options, - }; + readState(): AppState { + const signalState = select(); + return signalState(); } - init(): void { - if (this.devtoolsExtension) { - this.devtoolsConnection = this.devtoolsExtension.connect(this.options); - - actions$ - .pipe( - tap((action) => { - const signalState = selectableAppState.select(); - const unwrappedState = signalState(); - const actionForDevTools: Action = beautifyActionForLogging( - action, - unwrappedState - ); - this.devtoolsConnection.send(actionForDevTools, unwrappedState); - }) - ) - .subscribe(); - - this.devtoolsConnection.subscribe(this.onDevToolsMessage.bind(this)); - } - } - - private onDevToolsMessage(message: { type: string; payload: any; state: any }) { - if (message.type === DevToolActions.DISPATCH) { - switch (message.payload.type) { - case DevToolActions.JUMP_TO_STATE: - case DevToolActions.JUMP_TO_ACTION: - this.updateState(JSON.parse(message.state)); - } - } - } - - protected updateState(state: AppState) { + updateState(state: AppState): void { updateAppState(state); } } - -const enum DevToolActions { - DISPATCH = 'DISPATCH', - JUMP_TO_STATE = 'JUMP_TO_STATE', - JUMP_TO_ACTION = 'JUMP_TO_ACTION', -} diff --git a/libs/signal-store/src/lib/extensions/undo.extension.ts b/libs/signal-store/src/lib/extensions/undo.extension.ts deleted file mode 100644 index e8afc66c..00000000 --- a/libs/signal-store/src/lib/extensions/undo.extension.ts +++ /dev/null @@ -1,87 +0,0 @@ -// Credits go to Brecht Billiet -// Copied from: https://github.com/brechtbilliet/ngrx-undo/blob/master/src/handleUndo.ts -// Code has been modified to work with MiniRx - -// MIT License -// -// Copyright (c) 2016 Brecht Billiet -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -import { - Action, - ExtensionId, - ExtensionSortOrder, - HasComponentStoreSupport, - MetaReducer, - Reducer, - StoreExtension, -} from '../models'; -import { UNDO_ACTION } from '../actions'; - -const defaultBufferSize = 100; - -export class UndoExtension extends StoreExtension implements HasComponentStoreSupport { - id = ExtensionId.UNDO; - override sortOrder = ExtensionSortOrder.UNDO_EXTENSION; - hasCsSupport = true as const; - - constructor(private config: { bufferSize: number } = { bufferSize: defaultBufferSize }) { - super(); - } - - init(): MetaReducer { - return createUndoMetaReducer(this.config.bufferSize); - } -} - -function createUndoMetaReducer(bufferSize: number): MetaReducer { - let executedActions: Array = []; - let initialState: any; - - return (rootReducer: Reducer): Reducer => { - return (state: any, action: any) => { - if (action.type === UNDO_ACTION) { - // if the action is UNDO_ACTION, - // then call all the actions again on the rootReducer, - // except the one we want to rollback - let newState: any = initialState; - executedActions = executedActions.filter((eAct) => eAct !== action.payload); - // update the state for every action until we get the - // exact same state as before, but without the action we want to rollback - executedActions.forEach((executedAction) => { - newState = rootReducer(newState, executedAction); - }); - return newState; - } else { - // push every action that isn't UNDO_ACTION - executedActions.push(action); - } - const updatedState = rootReducer(state, action); - if (executedActions.length === bufferSize + 1) { - const firstAction = executedActions[0]; - // calculate the state x (bufferSize) actions ago - initialState = rootReducer(initialState, firstAction); - // keep the correct actions - executedActions = executedActions.slice(1, bufferSize + 1); - } - return updatedState; - }; - }; -} diff --git a/libs/signal-store/src/lib/feature-store.ts b/libs/signal-store/src/lib/feature-store.ts index 31bc5b12..2e4c69ea 100644 --- a/libs/signal-store/src/lib/feature-store.ts +++ b/libs/signal-store/src/lib/feature-store.ts @@ -1,106 +1,74 @@ -import { Action, ComponentStoreLike, FeatureStoreConfig, Reducer, StateOrCallback } from './models'; -import { calcNewState, miniRxError } from './utils'; +import { DestroyRef, inject, Signal } from '@angular/core'; import { + Action, + createFeatureStoreReducer, createMiniRxActionType, - isMiniRxAction, - OperationType, + FeatureStoreConfig, + generateId, MiniRxAction, - StoreType, + miniRxError, + OperationType, + StateOrCallback, undo, -} from './actions'; -import { BaseStore } from './base-store'; -import { - addFeature, - dispatch, - hasUndoExtension, - removeFeature, - selectableAppState, -} from './store-core'; -import { Signal } from '@angular/core'; -import { SelectableSignalState } from './selectable-signal-state'; +} from '@mini-rx/common'; +import { addFeature, dispatch, hasUndoExtension, removeFeature, select } from './store-core'; +import { createSelectableSignalState } from './selectable-signal-state'; +import { ComponentStoreLike } from './models'; +import { createRxEffectFn } from './rx-effect'; +import { createConnectFn } from './connect'; +import { createUpdateFn } from './update'; -export class FeatureStore - extends BaseStore - implements ComponentStoreLike -{ +export class FeatureStore implements ComponentStoreLike { + private readonly featureId: string; private readonly _featureKey: string; get featureKey(): string { return this._featureKey; } - state: Signal = selectableAppState.select((state) => state[this.featureKey]); - private selectableState = new SelectableSignalState(this.state); + state: Signal = select((state) => state[this.featureKey]); - private readonly featureId: string; + private dispatcher = ( + stateOrCallback: StateOrCallback, + operationType: OperationType, + name: string | undefined + ): MiniRxAction => { + const action: MiniRxAction = { + type: createMiniRxActionType(operationType, this.featureKey, name), + stateOrCallback, + featureId: this.featureId, + }; + dispatch(action); + return action; + }; constructor(featureKey: string, initialState: StateType, config: FeatureStoreConfig = {}) { - super(); - - this._destroyRef.onDestroy(() => this.destroy()); - this.featureId = generateId(); - this._featureKey = config.multi ? featureKey + '-' + generateId() : featureKey; + this._featureKey = config.multi ? featureKey + '-' + this.featureId : featureKey; addFeature( this._featureKey, createFeatureStoreReducer(this.featureId, initialState) ); - } - /** @internal - * Implementation of abstract method from BaseStore - */ - _dispatchSetStateAction( - stateOrCallback: StateOrCallback, - actionType: OperationType, - name: string | undefined - ): MiniRxAction { - // const action = createSetStateAction(StoreType.FEATURE_STORE, actionType, stateOrCallback, name, this.featureKey, this.featureId ); - const action: MiniRxAction = { - storeType: StoreType.FEATURE_STORE, - type: createMiniRxActionType(actionType, this.featureKey, name), - stateOrCallback, - featureId: this.featureId, - }; - dispatch(action); - return action; + inject(DestroyRef).onDestroy(() => this.destroy()); } - // Implementation of abstract method from BaseStore undo(action: Action): void { hasUndoExtension ? dispatch(undo(action)) : miniRxError('UndoExtension is not initialized.'); } - select = this.selectableState.select.bind(this.selectableState); + setState = createUpdateFn(this.dispatcher); + connect = createConnectFn(this.dispatcher); + rxEffect = createRxEffectFn(); + select = createSelectableSignalState(this.state).select; private destroy(): void { removeFeature(this._featureKey); } } -function createFeatureStoreReducer( - featureId: string, - initialState: StateType -): Reducer { - return (state: StateType = initialState, action: Action): StateType => { - if ( - isMiniRxAction(action, StoreType.FEATURE_STORE) && - action.featureId === featureId - ) { - return calcNewState(state, action.stateOrCallback); - } - return state; - }; -} - -// Simple alpha numeric ID: https://stackoverflow.com/a/12502559/453959 -// This isn't a real GUID! -function generateId(): string { - return Math.random().toString(36).slice(2); -} - export function createFeatureStore( featureKey: string, initialState: T, diff --git a/libs/signal-store/src/lib/memoize-one.ts b/libs/signal-store/src/lib/memoize-one.ts deleted file mode 100644 index a0ee815e..00000000 --- a/libs/signal-store/src/lib/memoize-one.ts +++ /dev/null @@ -1,93 +0,0 @@ -// Credits go to Alexander Reardon -// Copied from with small modifications: https://github.com/alexreardon/memoize-one/tree/v6.0.0/src - -// MIT License -// -// Copyright (c) 2019 Alexander Reardon -// -// Permission is hereby granted, free of charge, to any person obtaining a copy -// of this software and associated documentation files (the "Software"), to deal -// in the Software without restriction, including without limitation the rights -// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -// copies of the Software, and to permit persons to whom the Software is -// furnished to do so, subject to the following conditions: -// -// The above copyright notice and this permission notice shall be included in all -// copies or substantial portions of the Software. -// -// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -// SOFTWARE. - -function isEqual(first: unknown, second: unknown): boolean { - if (first === second) { - return true; - } - - // Special case for NaN (NaN !== NaN) - if (Number.isNaN(first) && Number.isNaN(second)) { - return true; - } - - return false; -} - -function areInputsEqual(newInputs: readonly unknown[], lastInputs: readonly unknown[]): boolean { - // no checks needed if the inputs length has changed - if (newInputs.length !== lastInputs.length) { - return false; - } - // Using for loop for speed. It generally performs better than array.every - // https://github.com/alexreardon/memoize-one/pull/59 - for (let i = 0; i < newInputs.length; i++) { - if (!isEqual(newInputs[i], lastInputs[i])) { - return false; - } - } - return true; -} - -type MemoizedFn any> = { - (this: ThisParameterType, ...args: Parameters): ReturnType; -}; - -// internal type -type Cache any> = { - lastThis: ThisParameterType; - lastArgs: Parameters; - lastResult: ReturnType; -}; - -export function memoizeOne any>( - resultFn: TFunc -): MemoizedFn { - let cache: Cache | null = null; - - // breaking cache when context (this) or arguments change - function memoized( - this: ThisParameterType, - ...newArgs: Parameters - ): ReturnType { - if (cache && cache.lastThis === this && areInputsEqual(newArgs, cache.lastArgs)) { - return cache.lastResult; - } - - // Throwing during an assignment aborts the assignment: https://codepen.io/alexreardon/pen/RYKoaz - // Doing the lastResult assignment first so that if it throws - // the cache will not be overwritten - const lastResult = resultFn.apply(this, newArgs); - cache = { - lastResult, - lastArgs: newArgs, - lastThis: this, - }; - - return lastResult; - } - - return memoized; -} diff --git a/libs/signal-store/src/lib/models.ts b/libs/signal-store/src/lib/models.ts index f4f9a3d9..a3d01efa 100644 --- a/libs/signal-store/src/lib/models.ts +++ b/libs/signal-store/src/lib/models.ts @@ -1,104 +1,12 @@ -import { Observable } from 'rxjs'; import { Signal } from '@angular/core'; - -export const enum ExtensionSortOrder { - DEFAULT = 0, - // The Undo Extension Meta Reducer should be the last one to be executed before "normal" reducers (for performance) - // Reason: The Undo Extension Meta Reducers may send many Actions through all following Reducers to undo an Action - // Also, we want to prevent that the replay of Actions shows up e.g. in the LoggerExtension Meta Reducer - UNDO_EXTENSION = 1, -} - -export type AppState = Record; - -export const enum ExtensionId { - IMMUTABLE_STATE, - UNDO, - LOGGER, - REDUX_DEVTOOLS, -} - -export abstract class StoreExtension { - abstract id: ExtensionId; - sortOrder: ExtensionSortOrder = ExtensionSortOrder.DEFAULT; - - abstract init(): MetaReducer | void; -} - -export interface HasComponentStoreSupport { - hasCsSupport: true; - - init(): MetaReducer; -} - -export type ComponentStoreExtension = StoreExtension & HasComponentStoreSupport; - -export interface ComponentStoreConfig { - extensions: ComponentStoreExtension[]; -} - -export interface Action { - type: string; - // Allows any extra properties to be defined in an action. - [x: string]: any; -} - -export interface ActionWithPayload extends Action { - payload?: any; -} - -export interface StoreConfig { - reducers?: ReducerDictionary; - initialState?: T; - metaReducers?: MetaReducer[]; - extensions?: StoreExtension[]; - combineReducersFn?: CombineReducersFn; -} - -// Used for the Redux API: Store.feature / StoreModule.forFeature -export interface FeatureConfig { - initialState: StateType; - metaReducers?: MetaReducer[]; -} - -// Used for createFeatureStore, new FeatureStore -export interface FeatureStoreConfig { - multi?: boolean; -} - -export class Actions extends Observable {} - -export type Reducer = (state: StateType, action: Action) => StateType; - -export type MetaReducer = (reducer: Reducer) => Reducer; - -export type ReducerDictionary = { - [p in keyof T]: Reducer; -}; - -export type CombineReducersFn = (reducers: ReducerDictionary) => Reducer; - -export type StateOrCallback = - | Partial - | ((state: StateType) => Partial); - -export const EFFECT_METADATA_KEY = '@mini-rx/effectMetaData'; - -export interface EffectConfig { - /** - * Determines if the action emitted by the effect is dispatched to the store. - * If false, effect does not need to return type `Observable`. - */ - dispatch?: boolean; -} - -export interface HasEffectMetadata { - [EFFECT_METADATA_KEY]: EffectConfig; -} +import { Observable } from 'rxjs'; +import { Action, StateOrCallback } from '@mini-rx/common'; export interface ComponentStoreLike { - update(stateOrCallback: StateOrCallback, name?: string): void; state: Signal; + setState(stateOrCallback: StateOrCallback, name?: string): void; + connect(dict: Record | Signal>): void; rxEffect(effectFn: (origin$: Observable) => Observable): () => void; + select(mapFn?: any): Signal; undo(action: Action): void; } diff --git a/libs/signal-store/src/lib/modules/component-store.module.ts b/libs/signal-store/src/lib/modules/component-store.module.ts index feaf069e..a3db0b2c 100644 --- a/libs/signal-store/src/lib/modules/component-store.module.ts +++ b/libs/signal-store/src/lib/modules/component-store.module.ts @@ -1,11 +1,11 @@ import { ModuleWithProviders, NgModule } from '@angular/core'; -import { ComponentStoreConfig } from '../models'; -import { configureComponentStores } from '../component-store'; +import { ComponentStoreConfig } from '@mini-rx/common'; +import { globalCsConfig } from '../component-store'; @NgModule() export class ComponentStoreModule { static forRoot(config: ComponentStoreConfig): ModuleWithProviders { - configureComponentStores(config); + globalCsConfig.set(config); return { ngModule: ComponentStoreModule, diff --git a/libs/signal-store/src/lib/modules/effects.module.ts b/libs/signal-store/src/lib/modules/effects.module.ts index 5a844dbd..8bc13a36 100644 --- a/libs/signal-store/src/lib/modules/effects.module.ts +++ b/libs/signal-store/src/lib/modules/effects.module.ts @@ -35,9 +35,9 @@ import { Observable } from 'rxjs'; import { fromClassesWithEffectsToClassProviders, fromObjectsWithEffectsToEffects, -} from './effects-mapper'; +} from '../effects-mapper'; import { StoreFeatureModule, StoreRootModule } from './store.module'; -import { Action } from '../models'; +import { Action } from '@mini-rx/common'; import { rxEffect } from '../store-core'; const OBJECTS_WITH_EFFECTS = new InjectionToken('@mini-rx/objectsWithEffects'); diff --git a/libs/signal-store/src/lib/modules/store.module.ts b/libs/signal-store/src/lib/modules/store.module.ts index c2de805e..1ef91099 100644 --- a/libs/signal-store/src/lib/modules/store.module.ts +++ b/libs/signal-store/src/lib/modules/store.module.ts @@ -1,5 +1,5 @@ import { Inject, InjectionToken, ModuleWithProviders, NgModule } from '@angular/core'; -import { Actions, AppState, FeatureConfig, Reducer, StoreConfig } from '../models'; +import { Actions, AppState, FeatureConfig, Reducer, StoreConfig } from '@mini-rx/common'; import { Store } from '../store'; import { actions$, addFeature } from '../store-core'; diff --git a/libs/signal-store/src/lib/providers.ts b/libs/signal-store/src/lib/providers.ts index b7e992d7..96ec95ba 100644 --- a/libs/signal-store/src/lib/providers.ts +++ b/libs/signal-store/src/lib/providers.ts @@ -6,9 +6,8 @@ import { FeatureConfig, Reducer, StoreConfig, -} from './models'; +} from '@mini-rx/common'; import { - ClassProvider, ENVIRONMENT_INITIALIZER, EnvironmentProviders, inject, @@ -19,8 +18,11 @@ import { import { actions$, addFeature, rxEffect } from './store-core'; import { Store } from './store'; import { Observable } from 'rxjs'; -import { hasEffectMetaData } from './utils'; -import { configureComponentStores } from './component-store'; +import { globalCsConfig } from './component-store'; +import { + fromClassesWithEffectsToClassProviders, + fromObjectsWithEffectsToEffects, +} from './effects-mapper'; const STORE_PROVIDER = new InjectionToken('@mini-rx/store-provider'); const STORE_CONFIG = new InjectionToken>('@mini-rx/store-config'); @@ -127,38 +129,12 @@ export function provideEffects(...classesWithEffects: any[]): EnvironmentProvide ]); } -// Todo: move to @mini-rx/common lib -const fromClassesWithEffectsToClassProviders = ( - injectionToken: InjectionToken, - classesWithEffects: Type[] -): ClassProvider[] => - classesWithEffects.map((classWithEffects) => ({ - provide: injectionToken, - useClass: classWithEffects, - multi: true, - })); - -// Todo: move to @mini-rx/common lib -const fromObjectsWithEffectsToEffects = (objectsWithEffects: any[]): Observable[] => - objectsWithEffects.reduce((acc, objectWithEffects) => { - const effectsFromCurrentObject = Object.getOwnPropertyNames(objectWithEffects).reduce< - Array> - >((acc, prop) => { - const effect = objectWithEffects[prop]; - if (hasEffectMetaData(effect)) { - acc.push(effect); - } - return acc; - }, []); - return [...acc, ...effectsFromCurrentObject]; - }, []); - // Component Store config export function provideComponentStoreConfig(config: ComponentStoreConfig) { return makeEnvironmentProviders([ { provide: COMPONENT_STORE_CONFIG_PROVIDER, - useFactory: () => configureComponentStores(config), + useFactory: () => globalCsConfig.set(config), }, { provide: ENVIRONMENT_INITIALIZER, diff --git a/libs/signal-store/src/lib/rx-effect.ts b/libs/signal-store/src/lib/rx-effect.ts new file mode 100644 index 00000000..8401c53c --- /dev/null +++ b/libs/signal-store/src/lib/rx-effect.ts @@ -0,0 +1,48 @@ +import { isObservable, Observable, Subject } from 'rxjs'; +import { DestroyRef, inject, Signal } from '@angular/core'; +import { defaultEffectsErrorHandler } from '@mini-rx/common'; +import { takeUntilDestroyed, toObservable } from '@angular/core/rxjs-interop'; +import { miniRxIsSignal } from './utils'; + +export function createRxEffectFn() { + const destroyRef = inject(DestroyRef); + + function rxEffect< + // Credits for the typings go to NgRx (Component Store): https://github.com/ngrx/platform/blob/13.1.0/modules/component-store/src/component-store.ts#L279-L291 + ProvidedType = void, + // The actual origin$ type, which could be unknown, when not specified + OriginType extends Observable | unknown = Observable, + // Unwrapped actual type of the origin$ Observable, after default was applied + ObservableType = OriginType extends Observable ? A : never, + // Return either an empty callback or a function requiring specific types as inputs + ReturnType = ProvidedType | ObservableType extends void + ? () => void + : ( + observableOrValue: + | ObservableType + | Observable + | Signal + ) => void + >(effectFn: (origin$: OriginType) => Observable): ReturnType { + const subject = new Subject(); + const effect$ = effectFn(subject as OriginType); + effect$.pipe(defaultEffectsErrorHandler, takeUntilDestroyed(destroyRef)).subscribe(); + + return (( + observableOrValue?: ObservableType | Observable | Signal + ) => { + // If we detect a Signal: convert Signal to Observable + observableOrValue = miniRxIsSignal(observableOrValue) + ? toObservable(observableOrValue) + : observableOrValue; + + isObservable(observableOrValue) + ? observableOrValue + .pipe(takeUntilDestroyed(destroyRef)) + .subscribe((v) => subject.next(v)) + : subject.next(observableOrValue as ObservableType); + }) as unknown as ReturnType; + } + + return rxEffect; +} diff --git a/libs/signal-store/src/lib/selectable-signal-state.ts b/libs/signal-store/src/lib/selectable-signal-state.ts index 9c59fd4e..a250d6b6 100644 --- a/libs/signal-store/src/lib/selectable-signal-state.ts +++ b/libs/signal-store/src/lib/selectable-signal-state.ts @@ -4,26 +4,28 @@ import { defaultSignalEquality } from './utils'; type StateSelector = (state: T) => R; -export class SelectableSignalState { - constructor(private state: Signal) {} - - select(): Signal; - select(mapFn: SignalSelector): Signal; - select(mapFn: StateSelector): Signal; - select(mapFn?: any): Signal { +export function createSelectableSignalState(state: Signal) { + function select(): Signal; + function select(mapFn: SignalSelector): Signal; + function select(mapFn: StateSelector): Signal; + function select(mapFn?: any): Signal { if (!mapFn) { - return this.state; + return state; } if (isSignalSelector(mapFn)) { - return mapFn(this.state); + return mapFn(state); } return computed( () => { - return mapFn(this.state()); + return mapFn(state()); }, { equal: defaultSignalEquality } ); } + + return { + select, + }; } diff --git a/libs/signal-store/src/lib/signal-selector.ts b/libs/signal-store/src/lib/signal-selector.ts index 3d3fd0ce..5bb788f7 100644 --- a/libs/signal-store/src/lib/signal-selector.ts +++ b/libs/signal-store/src/lib/signal-selector.ts @@ -25,7 +25,7 @@ // SOFTWARE. import { computed, Signal } from '@angular/core'; -import { AppState } from './models'; +import { AppState } from '@mini-rx/common'; import { defaultSignalEquality } from './utils'; export const SIGNAL_SELECTOR_KEY = '@mini-rx/signalSelector'; diff --git a/libs/signal-store/src/lib/spec/_spec-helpers.ts b/libs/signal-store/src/lib/spec/_spec-helpers.ts index 754cd14b..cc61bf8f 100644 --- a/libs/signal-store/src/lib/spec/_spec-helpers.ts +++ b/libs/signal-store/src/lib/spec/_spec-helpers.ts @@ -1,13 +1,8 @@ -import { Action, ActionWithPayload, ComponentStoreExtension, ExtensionId, MetaReducer, Reducer } from '../models'; -import { v4 as uuid } from 'uuid'; -import { dispatch, reducerState } from '../store-core'; +import { Action, ComponentStoreExtension, ExtensionId, MetaReducer } from '@mini-rx/common'; +import { dispatch, getReducerManager } from '../store-core'; export function resetStoreConfig() { - reducerState.set({ - metaReducers: [], - featureReducers: {}, - }); - + getReducerManager()._updateStateAndReducer({ featureReducers: {}, metaReducers: [] }); dispatch({ type: 'resetStoreConfig' }); // Trigger action to recalculate state } @@ -51,45 +46,6 @@ export function counterReducer( } } -export function createUniqueCounterReducerWithAction(): [Reducer, Action] { - const incrementCase = uuid(); - const reducer = (state: CounterState = counterInitialState, action: Action) => { - switch (action.type) { - case incrementCase: - return { - ...state, - counter: state.counter + 1, - }; - default: - return state; - } - }; - return [reducer, { type: incrementCase }]; -} - -export interface CounterStringState { - counter: string; -} - -export const counterStringInitialState: CounterStringState = { - counter: '1', -}; - -export function counterStringReducer( - state: CounterStringState = counterStringInitialState, - action: ActionWithPayload -) { - switch (action.type) { - case 'counterString': - return { - ...state, - counter: state.counter + action.payload, - }; - default: - return state; - } -} - export class MockLoggerExtension implements ComponentStoreExtension { id = ExtensionId.LOGGER; sortOrder = 1; diff --git a/libs/signal-store/src/lib/spec/component-store.spec.ts b/libs/signal-store/src/lib/spec/component-store.spec.ts index 7310e2c9..1ac5bc43 100644 --- a/libs/signal-store/src/lib/spec/component-store.spec.ts +++ b/libs/signal-store/src/lib/spec/component-store.spec.ts @@ -1,27 +1,9 @@ -import { - _resetConfig, - ComponentStore, - configureComponentStores, - createComponentStore, -} from '../component-store'; -import { - counterInitialState, - CounterState, - MockImmutableStateExtension, - MockLoggerExtension, - MockUndoExtension, - userState, -} from './_spec-helpers'; +import { ComponentStore, createComponentStore, globalCsConfig } from '../component-store'; +import { counterInitialState, CounterState, userState } from './_spec-helpers'; import { Observable, of, pipe, Subject } from 'rxjs'; -import { map, tap } from 'rxjs/operators'; +import { tap } from 'rxjs/operators'; import { createComponentStateSelector, createSelector } from '../signal-selector'; -import { - ComponentStoreConfig, - ComponentStoreExtension, - ExtensionId, - MetaReducer, - StoreExtension, -} from '../models'; +import { ComponentStoreConfig } from '@mini-rx/common'; import { TestBed } from '@angular/core/testing'; import { Component, Injectable, signal } from '@angular/core'; @@ -48,7 +30,7 @@ describe('ComponentStore', () => { const selectedState = cs.select(); expect(selectedState()).toBe(counterInitialState); - cs.update((state) => ({ counter: state.counter + 1 })); + cs.setState((state) => ({ counter: state.counter + 1 })); expect(selectedState()).toEqual({ counter: 2 }); }); @@ -58,7 +40,7 @@ describe('ComponentStore', () => { const selectedState = cs.select(); expect(selectedState()).toBe(userState); - cs.update(() => ({ firstName: 'Nicolas' })); + cs.setState(() => ({ firstName: 'Nicolas' })); expect(selectedState()).toEqual({ ...userState, firstName: 'Nicolas' }); }); @@ -77,10 +59,10 @@ describe('ComponentStore', () => { expect(selectedState()).toBe(5); // "normal" setState - cs.update((state) => ({ counter: state.counter + 1 })); + cs.setState((state) => ({ counter: state.counter + 1 })); expect(selectedState()).toBe(6); - cs.update((state) => ({ counter: state.counter + 1 })); + cs.setState((state) => ({ counter: state.counter + 1 })); expect(selectedState()).toBe(7); }); @@ -149,15 +131,15 @@ describe('ComponentStore', () => { const selectedState = cs.select(getSquareCounter); selectedState(); - cs.update({ counter: 2 }); + cs.setState({ counter: 2 }); selectedState(); - cs.update({ counter: 2 }); + cs.setState({ counter: 2 }); selectedState(); - cs.update({ counter: 3 }); + cs.setState({ counter: 3 }); selectedState(); - cs.update({ counter: 3 }); + cs.setState({ counter: 3 }); selectedState(); - cs.update({ counter: 4 }); + cs.setState({ counter: 4 }); selectedState(); expect(getCounterSpy.mock.calls).toEqual([[1], [2], [2], [3], [3], [4]]); // No memoization: because a new state object is created for every call of `update` @@ -171,9 +153,8 @@ describe('ComponentStore', () => { cs['actionsOnQueue'].actions$.subscribe(spy); const setStateCallback = (state: CounterState) => ({ counter: state.counter + 1 }); - cs.update(setStateCallback); + cs.setState(setStateCallback); expect(spy).toHaveBeenCalledWith({ - storeType: '@mini-rx/component-store', type: '@mini-rx/component-store/set-state', stateOrCallback: setStateCallback, }); @@ -182,9 +163,8 @@ describe('ComponentStore', () => { spy.mockReset(); // With setState name - cs.update(setStateCallback, 'increment'); + cs.setState(setStateCallback, 'increment'); expect(spy).toHaveBeenCalledWith({ - storeType: '@mini-rx/component-store', type: '@mini-rx/component-store/set-state/increment', stateOrCallback: setStateCallback, }); @@ -197,7 +177,6 @@ describe('ComponentStore', () => { expect(spy.mock.calls).toEqual([ [ { - storeType: '@mini-rx/component-store', type: '@mini-rx/component-store/connection/counter', stateOrCallback: { counter: 1, @@ -206,7 +185,6 @@ describe('ComponentStore', () => { ], [ { - storeType: '@mini-rx/component-store', type: '@mini-rx/component-store/connection/counter', stateOrCallback: { counter: 2, @@ -326,8 +304,8 @@ describe('ComponentStore', () => { }); it('should throw when calling `configureComponentStores` more than once', () => { - configureComponentStores({ extensions: [] }); - expect(() => configureComponentStores({ extensions: [] })).toThrowError( + globalCsConfig.set({ extensions: [] }); + expect(() => globalCsConfig.set({ extensions: [] })).toThrowError( '@mini-rx: `configureComponentStores` was called multiple times.' ); }); @@ -339,67 +317,4 @@ describe('ComponentStore', () => { '@mini-rx: ComponentStore has no UndoExtension yet.' ); }); - - it('should throw when a not supported extension is used', () => { - class MyExtension extends StoreExtension { - id: ExtensionId = ExtensionId.LOGGER; - - // eslint-disable-next-line @typescript-eslint/no-empty-function - init(): void {} - } - - expect(() => - setup( - {}, - { - extensions: [new MyExtension() as ComponentStoreExtension], - } - ) - ).toThrowError('@mini-rx: Extension "MyExtension" is not supported by Component Store.'); - }); - - describe('Extensions', () => { - beforeEach(() => { - _resetConfig(); - }); - - it('should be local', () => { - const extensions = [new MockLoggerExtension(), new MockUndoExtension()]; - const cs = setup({}, { extensions }); - - expect(cs['extensions']).toBe(extensions); - }); - - it('should be global', () => { - const extensions = [new MockLoggerExtension(), new MockUndoExtension()]; - - configureComponentStores({ extensions }); - const cs = setup({}); - - expect(cs['extensions']).toBe(extensions); - }); - - it('should be merged', () => { - const globalExtensions = [new MockLoggerExtension(), new MockImmutableStateExtension()]; - const localExtensions = [new MockUndoExtension()]; - - configureComponentStores({ extensions: globalExtensions }); - const cs = setup({}, { extensions: localExtensions }); - - expect(cs['extensions'][0]).toBe(localExtensions[0]); - expect(cs['extensions'][1]).toBe(globalExtensions[0]); - expect(cs['extensions'][2]).toBe(globalExtensions[1]); - }); - - it('should be merged (use local if extension is used globally and locally)', () => { - const globalExtensions = [new MockLoggerExtension(), new MockImmutableStateExtension()]; - const localExtensions = [new MockLoggerExtension()]; - - configureComponentStores({ extensions: globalExtensions }); - const cs = setup({}, { extensions: localExtensions }); - - expect(cs['extensions'][0]).toBe(localExtensions[0]); - expect(cs['extensions'][1]).toBe(globalExtensions[1]); - }); - }); }); diff --git a/libs/signal-store/src/lib/spec/feature-store.spec.ts b/libs/signal-store/src/lib/spec/feature-store.spec.ts index 4865bd4d..11cdaa91 100644 --- a/libs/signal-store/src/lib/spec/feature-store.spec.ts +++ b/libs/signal-store/src/lib/spec/feature-store.spec.ts @@ -11,14 +11,13 @@ import { userState, UserState, } from './_spec-helpers'; -import { Action, Actions, FeatureConfig, Reducer, StoreConfig } from '../models'; -import { tapResponse } from '../tap-response'; -import { addMetaReducers } from '../store-core'; +import { Action, Actions, FeatureConfig, Reducer, StoreConfig, tapResponse } from '@mini-rx/common'; import { ComponentFixture, TestBed } from '@angular/core/testing'; import { StoreModule } from '../modules/store.module'; import { Store } from '../store'; import { Component, EnvironmentInjector, inject, Signal } from '@angular/core'; import { toObservable } from '@angular/core/rxjs-interop'; +import { getReducerManager } from '../store-core'; let store: Store; let actions: Actions; @@ -92,7 +91,7 @@ class UserFeatureStore extends FeatureStore { someFeatureState = store.select(getSomeFeatureSelector); loadFn = this.rxEffect((payload$) => - payload$.pipe(mergeMap(() => fakeApiGet().pipe(tap((user) => this.update(user))))) + payload$.pipe(mergeMap(() => fakeApiGet().pipe(tap((user) => this.setState(user))))) ); loadFnWithError = this.rxEffect((payload$) => @@ -100,9 +99,9 @@ class UserFeatureStore extends FeatureStore { mergeMap(() => fakeApiWithError().pipe( tapResponse( - (user) => this.update(user), + (user) => this.setState(user), (err) => { - this.update({ err: 'error' }); + this.setState({ err: 'error' }); } ) ) @@ -115,26 +114,26 @@ class UserFeatureStore extends FeatureStore { } updateFirstName(firstName: string) { - this.update({ firstName }); + this.setState({ firstName }); } updateLastName(lastName: string) { - this.update({ lastName }); + this.setState({ lastName }); } updateCity(city: string) { - this.update({ city }, 'updateCity'); + this.setState({ city }, 'updateCity'); } updateCountry(country: string) { - this.update({ + this.setState({ ...this.state, // Test updating state using `this.state` country, }); } resetState() { - this.update(initialState); + this.setState(initialState); } } @@ -147,7 +146,7 @@ class CounterFeatureStore extends FeatureStore { increment() { // Update state using callback - this.update((state) => ({ counter: state.counter + 1 })); + this.setState((state) => ({ counter: state.counter + 1 })); } } @@ -294,7 +293,7 @@ describe('FeatureStore', () => { ); const load = fs.rxEffect( - mergeMap(() => apiCallWithError().pipe(tap(() => fs.update({})))) + mergeMap(() => apiCallWithError().pipe(tap(() => fs.setState({})))) ); load(); @@ -371,7 +370,6 @@ describe('FeatureStore', () => { userFeature.updateCity('NY'); expect(spy).toHaveBeenCalledWith( expect.objectContaining({ - storeType: '@mini-rx/feature-store', type: '@mini-rx/user2/set-state/updateCity', stateOrCallback: { city: 'NY' }, featureId: expect.any(String), @@ -393,7 +391,7 @@ describe('FeatureStore', () => { }; } - addMetaReducers(metaReducer); + getReducerManager().addMetaReducers(metaReducer); userFeature.updateCity('NY'); counterFeature.increment(); @@ -412,7 +410,7 @@ describe('FeatureStore', () => { const counter$: Signal = fs.select(getCounter); function inc() { - fs.update((state) => ({ + fs.setState((state) => ({ counter: state.counter + 1, })); } @@ -469,7 +467,7 @@ describe('FeatureStore', () => { } increment(): Action { - return this.update((state) => ({ + return this.setState((state) => ({ counter: state.counter + 1, })); } @@ -482,7 +480,7 @@ describe('FeatureStore', () => { ); function incrementFs3(): void { - fs3.update((state) => ({ counter: state.counter + 1 })); + fs3.setState((state) => ({ counter: state.counter + 1 })); } const fs1FeatureKey = fs1.featureKey; diff --git a/libs/signal-store/src/lib/spec/modules.spec.ts b/libs/signal-store/src/lib/spec/modules.spec.ts index 0c3c1a22..d8656216 100644 --- a/libs/signal-store/src/lib/spec/modules.spec.ts +++ b/libs/signal-store/src/lib/spec/modules.spec.ts @@ -5,12 +5,11 @@ import { of } from 'rxjs'; import { StoreModule } from '../modules/store.module'; import { EffectsModule } from '../modules/effects.module'; import { ComponentStoreModule } from '../modules/component-store.module'; -import { Action, Actions, Reducer, StoreExtension } from '../models'; -import { ofType } from '../utils'; -import { createRxEffect } from '../create-rx-effect'; +import { Action, Actions, ofType, Reducer, StoreExtension } from '@mini-rx/common'; +import { createRxEffect } from '@mini-rx/common'; import { FeatureStore } from '../feature-store'; import { Store } from '../store'; -import { createComponentStore } from '../component-store'; +import { createComponentStore, globalCsConfig } from '../component-store'; import { MockImmutableStateExtension, MockLoggerExtension, @@ -127,7 +126,7 @@ class CounterFeatureStore extends FeatureStore { } inc() { - this.update((state) => ({ + this.setState((state) => ({ counter: state.counter + 1, })); } @@ -272,17 +271,12 @@ describe(`Ng Modules`, () => { describe(`ComponentStore`, () => { // Just make sure that the global config is set via the ComponentStoreModule.forRoot static method - // For the other aspects of the config we can rely on the ComponentStore tests - it('should merge global config with local config', () => { - const localCsExtensions = [new MockUndoExtension()]; - const cs = TestBed.runInInjectionContext(() => { - return createComponentStore({}, { extensions: localCsExtensions }); - }); + it('should set global component store config', () => { + const globalExtensions = globalCsConfig.get()?.extensions ?? []; - expect(cs['extensions'][0]).toBe(localCsExtensions[0]); - expect(cs['extensions'][1]).toBe(globalCsExtensions[0]); - expect(cs['extensions'][2]).toBe(globalCsExtensions[1]); + expect(globalExtensions[0]).toBe(globalCsExtensions[0]); + expect(globalExtensions[1]).toBe(globalCsExtensions[1]); }); }); }); diff --git a/libs/signal-store/src/lib/spec/providers.spec.ts b/libs/signal-store/src/lib/spec/providers.spec.ts index 5817119f..19651580 100644 --- a/libs/signal-store/src/lib/spec/providers.spec.ts +++ b/libs/signal-store/src/lib/spec/providers.spec.ts @@ -2,12 +2,11 @@ import { TestBed } from '@angular/core/testing'; import { Injectable } from '@angular/core'; import { catchError, map, mergeMap } from 'rxjs/operators'; import { of } from 'rxjs'; -import { Action, Actions, Reducer, StoreExtension } from '../models'; -import { ofType } from '../utils'; -import { createRxEffect } from '../create-rx-effect'; +import { Action, Actions, Reducer, StoreExtension } from '@mini-rx/common'; +import { createRxEffect, ofType } from '@mini-rx/common'; import { FeatureStore } from '../feature-store'; import { Store } from '../store'; -import { createComponentStore } from '../component-store'; +import { createComponentStore, globalCsConfig } from '../component-store'; import { MockImmutableStateExtension, MockLoggerExtension, @@ -113,7 +112,7 @@ class CounterFeatureStore extends FeatureStore { } inc() { - this.update((state) => ({ + this.setState((state) => ({ counter: state.counter + 1, })); } @@ -263,17 +262,12 @@ describe(`Providers`, () => { describe(`ComponentStore`, () => { // Just make sure that the global config is set via provideComponentStoreConfig - // For the other aspects of the config we can rely on the ComponentStore tests - it('should merge global config with local config', () => { - const localCsExtensions = [new MockUndoExtension()]; - const cs = TestBed.runInInjectionContext(() => { - return createComponentStore({}, { extensions: localCsExtensions }); - }); + it('should set global component store config', () => { + const globalExtensions = globalCsConfig.get()?.extensions ?? []; - expect(cs['extensions'][0]).toBe(localCsExtensions[0]); - expect(cs['extensions'][1]).toBe(globalCsExtensions[0]); - expect(cs['extensions'][2]).toBe(globalCsExtensions[1]); + expect(globalExtensions[0]).toBe(globalCsExtensions[0]); + expect(globalExtensions[1]).toBe(globalCsExtensions[1]); }); }); }); diff --git a/libs/signal-store/src/lib/spec/store.spec.ts b/libs/signal-store/src/lib/spec/store.spec.ts index 373a182d..708cd621 100644 --- a/libs/signal-store/src/lib/spec/store.spec.ts +++ b/libs/signal-store/src/lib/spec/store.spec.ts @@ -2,18 +2,18 @@ import { Store } from '../store'; import { Action, Actions, - ActionWithPayload, ExtensionId, FeatureConfig, MetaReducer, + ofType, Reducer, StoreConfig, StoreExtension, -} from '../models'; +} from '@mini-rx/common'; import { createFeatureStateSelector, createSelector } from '../signal-selector'; import { mapTo, Observable, of, take } from 'rxjs'; import { cold, hot } from 'jest-marbles'; -import { createFeatureStore, FeatureStore } from '../feature-store'; +import { FeatureStore } from '../feature-store'; import { counterInitialState, counterReducer, @@ -22,10 +22,13 @@ import { } from './_spec-helpers'; import { TestBed } from '@angular/core/testing'; import { StoreModule } from '../modules/store.module'; -import { addFeature, configureStore, removeFeature, rxEffect } from '../store-core'; -import { ofType } from '../utils'; +import { addFeature, removeFeature, rxEffect } from '../store-core'; import { catchError, map, mergeMap, tap } from 'rxjs/operators'; -import { createRxEffect } from '../create-rx-effect'; +import { createRxEffect } from '@mini-rx/common'; + +interface ActionWithPayload extends Action { + payload?: any; +} const asyncUser: Partial = { firstName: 'Steven', @@ -101,7 +104,7 @@ class CounterFeatureState extends FeatureStore { } increment() { - this.update((state) => ({ counter: state.counter + 1 })); + this.setState((state) => ({ counter: state.counter + 1 })); } } diff --git a/libs/signal-store/src/lib/store-core.ts b/libs/signal-store/src/lib/store-core.ts index d879409d..d2a87030 100644 --- a/libs/signal-store/src/lib/store-core.ts +++ b/libs/signal-store/src/lib/store-core.ts @@ -1,95 +1,59 @@ +import { signal, WritableSignal } from '@angular/core'; import { Observable } from 'rxjs'; import { Action, - Actions, AppState, + createActionsOnQueue, + createMiniRxActionType, + createReducerManager, + defaultEffectsErrorHandler, EFFECT_METADATA_KEY, EffectConfig, ExtensionId, HasEffectMetadata, + hasEffectMetaData, MetaReducer, + OperationType, Reducer, - ReducerDictionary, + ReducerManager, + sortExtensions, StoreConfig, StoreExtension, -} from './models'; -import { combineMetaReducers, hasEffectMetaData, miniRxError, sortExtensions } from './utils'; -import { defaultEffectsErrorHandler } from './default-effects-error-handler'; -import { combineReducers } from './combine-reducers'; -import { createMiniRxActionType, OperationType } from './actions'; -import { ActionsOnQueue } from './actions-on-queue'; -import { computed, Signal, signal, WritableSignal } from '@angular/core'; -import { SelectableSignalState } from './selectable-signal-state'; +} from '@mini-rx/common'; +import { createSelectableSignalState } from './selectable-signal-state'; export let hasUndoExtension = false; let isStoreInitialized = false; -// REDUCER STATE -// exported for testing purposes -export const reducerState: WritableSignal<{ - featureReducers: ReducerDictionary; - metaReducers: MetaReducer[]; -}> = signal({ - featureReducers: {}, - metaReducers: [], -}); - -function checkFeatureExists(featureKey: string): void { - if (Object.hasOwn(reducerState().featureReducers, featureKey)) { - miniRxError(`Feature "${featureKey}" already exists.`); - } -} - -function addReducer(featureKey: string, reducer: Reducer): void { - initStore(); - checkFeatureExists(featureKey); - reducerState.mutate((state) => (state.featureReducers[featureKey] = reducer)); -} - -function removeReducer(featureKey: string): void { - reducerState.mutate( - (state) => - (state.featureReducers = omit( - state.featureReducers, - featureKey - ) as ReducerDictionary) - ); -} +// REDUCER MANAGER +let reducerManager: ReducerManager | undefined; // exported for testing purposes -export function addMetaReducers(...reducers: MetaReducer[]): void { - reducerState.mutate((state) => (state.metaReducers = [...state.metaReducers, ...reducers])); +export function getReducerManager(): ReducerManager { + if (!reducerManager) { + reducerManager = createReducerManager(); + } + return reducerManager; } // ACTIONS -const actionsOnQueue = new ActionsOnQueue(); -export const actions$: Actions = actionsOnQueue.actions$; +export const { actions$, dispatch } = createActionsOnQueue(); // APP STATE const appState: WritableSignal = signal({}); -export const selectableAppState: SelectableSignalState = new SelectableSignalState( - appState -); +export const { select } = createSelectableSignalState(appState); -// Wire up the Redux Store: Init reducer state, subscribe to the actions and reducer Observable +// Wire up the Redux Store: subscribe to the actions stream, calc next state for every action // Called by `configureStore` and `addReducer` function initStore(): void { if (isStoreInitialized) { return; } - const reducer: Signal> = computed(() => { - const combinedMetaReducer: MetaReducer = combineMetaReducers( - reducerState().metaReducers - ); - const combinedReducer: Reducer = combineReducers(reducerState().featureReducers); - return combinedMetaReducer(combinedReducer); - }); - - // Listen to the Actions stream and update state accordingly - actionsOnQueue.actions$.subscribe((action) => { - const newState: AppState = reducer()(appState(), action); - appState.set(newState); + // Listen to the Actions stream and update state + actions$.subscribe((action) => { + const nextState: AppState = getReducerManager().getReducer()(appState(), action); + appState.set(nextState); }); isStoreInitialized = true; @@ -98,19 +62,16 @@ function initStore(): void { export function configureStore(config: StoreConfig = {}): void { initStore(); - if (config.metaReducers?.length) { - addMetaReducers(...config.metaReducers); + if (config.metaReducers) { + getReducerManager().addMetaReducers(...config.metaReducers); } - if (config.extensions?.length) { - const sortedExtensions: StoreExtension[] = sortExtensions(config.extensions); - sortedExtensions.forEach((extension) => addExtension(extension)); + if (config.extensions) { + sortExtensions(config.extensions).forEach((extension) => addExtension(extension)); } if (config.reducers) { - for (const [featureKey, value] of Object.entries(config.reducers)) { - addReducer(featureKey, value); - } + getReducerManager().setFeatureReducers(config.reducers); } if (config.initialState) { @@ -128,27 +89,25 @@ export function addFeature( initialState?: StateType; } = {} ): void { - reducer = config.metaReducers?.length - ? combineMetaReducers(config.metaReducers)(reducer) - : reducer; - - if (config.initialState) { - reducer = createReducerWithInitialState(reducer, config.initialState); - } - - addReducer(featureKey, reducer); + initStore(); + getReducerManager().addFeatureReducer( + featureKey, + reducer, + config.metaReducers, + config.initialState + ); dispatch({ type: createMiniRxActionType(OperationType.INIT, featureKey) }); } export function removeFeature(featureKey: string): void { - removeReducer(featureKey); + getReducerManager().removeFeatureReducer(featureKey); dispatch({ type: createMiniRxActionType(OperationType.DESTROY, featureKey) }); } export function rxEffect(effect$: Observable & HasEffectMetadata): void; export function rxEffect(effect$: Observable): void; export function rxEffect(effect$: any): void { - const effectWithErrorHandler$: Observable = defaultEffectsErrorHandler(effect$); + const effectWithErrorHandler$: Observable = defaultEffectsErrorHandler(effect$); effectWithErrorHandler$.subscribe((action) => { let shouldDispatch = true; if (hasEffectMetaData(effect$)) { @@ -167,7 +126,7 @@ export function addExtension(extension: StoreExtension): void { const metaReducer: MetaReducer | void = extension.init(); if (metaReducer) { - addMetaReducers(metaReducer); + getReducerManager().addMetaReducers(metaReducer); } if (extension.id === ExtensionId.UNDO) { @@ -175,28 +134,6 @@ export function addExtension(extension: StoreExtension): void { } } -export function dispatch(action: Action): void { - actionsOnQueue.dispatch(action); -} - export function updateAppState(state: AppState): void { appState.set(state); } - -function createReducerWithInitialState( - reducer: Reducer, - initialState: StateType -): Reducer { - return (state: StateType = initialState, action: Action): StateType => { - return reducer(state, action); - }; -} - -function omit>(object: T, keyToOmit: keyof T): Partial { - return Object.keys(object) - .filter((key) => key !== keyToOmit) - .reduce>((prevValue, key: keyof T) => { - prevValue[key] = object[key]; - return prevValue; - }, {}); -} diff --git a/libs/signal-store/src/lib/store.ts b/libs/signal-store/src/lib/store.ts index 5873e837..cde45f84 100644 --- a/libs/signal-store/src/lib/store.ts +++ b/libs/signal-store/src/lib/store.ts @@ -1,9 +1,9 @@ -import { AppState, StoreConfig } from './models'; -import { configureStore, dispatch, selectableAppState } from './store-core'; +import { AppState, StoreConfig } from '@mini-rx/common'; +import { configureStore, dispatch, select } from './store-core'; export class Store { dispatch = dispatch; - select = selectableAppState.select.bind(selectableAppState); + select = select; constructor(config: StoreConfig) { configureStore(config); diff --git a/libs/signal-store/src/lib/update.ts b/libs/signal-store/src/lib/update.ts new file mode 100644 index 00000000..04a6c413 --- /dev/null +++ b/libs/signal-store/src/lib/update.ts @@ -0,0 +1,15 @@ +import { Action, OperationType, StateOrCallback } from '@mini-rx/common'; + +export function createUpdateFn( + dispatch: ( + stateOrCallback: StateOrCallback, + operationType: OperationType, + name: string | undefined + ) => Action +) { + function update(stateOrCallback: StateOrCallback, name?: string): Action { + return dispatch(stateOrCallback, OperationType.SET_STATE, name); + } + + return update; +} diff --git a/libs/signal-store/src/lib/utils.ts b/libs/signal-store/src/lib/utils.ts index a0dd42bd..018008a2 100644 --- a/libs/signal-store/src/lib/utils.ts +++ b/libs/signal-store/src/lib/utils.ts @@ -1,84 +1,9 @@ -import { Observable, OperatorFunction } from 'rxjs'; -import { filter } from 'rxjs/operators'; -import { - Action, - EFFECT_METADATA_KEY, - HasEffectMetadata, - MetaReducer, - Reducer, - StateOrCallback, - StoreExtension, -} from './models'; -import { isMiniRxAction, MiniRxAction, StoreType } from './actions'; -import { miniRxNameSpace } from './constants'; import { isSignal, Signal } from '@angular/core'; -export function ofType(...allowedTypes: string[]): OperatorFunction { - return filter((action: Action) => - allowedTypes.some((type) => { - return type === action.type; - }) - ); -} - -export function miniRxError(message: string): never { - throw new Error(miniRxNameSpace + ': ' + message); -} - -export function miniRxConsoleError(message: string, err: any): void { - console.error(miniRxNameSpace + ': ' + message + '\nDetails:', err); -} - -export function hasEffectMetaData( - param: Observable -): param is Observable & HasEffectMetadata { - return Object.hasOwn(param, EFFECT_METADATA_KEY); -} - -// Only display type and payload in the LoggingExtension and Redux DevTools -export function beautifyActionForLogging(action: Action | MiniRxAction): Action { - if ( - isMiniRxAction(action, StoreType.FEATURE_STORE) || - isMiniRxAction(action, StoreType.COMPONENT_STORE) - ) { - return { - type: action.type, - payload: action.stateOrCallback, - }; - } - return action; -} - -export function calcNewState(state: T, stateOrCallback: StateOrCallback): T { - const newPartialState = - typeof stateOrCallback === 'function' ? stateOrCallback(state) : stateOrCallback; - return { - ...state, - ...newPartialState, - }; -} - -export function combineMetaReducers(metaReducers: MetaReducer[]): MetaReducer { - return (reducer: Reducer): Reducer => { - return metaReducers.reduceRight( - (previousValue: Reducer, currentValue: MetaReducer) => { - return currentValue(previousValue); - }, - reducer - ); - }; -} - -export function sortExtensions(extensions: T[]): T[] { - return [...extensions].sort((a, b) => { - return a.sortOrder - b.sortOrder; - }); +export function defaultSignalEquality(a: any, b: any) { + return a === b; } export function miniRxIsSignal(v: any): v is Signal { return v?.constructor === Function && isSignal(v); } - -export function defaultSignalEquality(a: any, b: any) { - return a === b; -} diff --git a/package-lock.json b/package-lock.json index 69b2ae66..a53d1219 100644 --- a/package-lock.json +++ b/package-lock.json @@ -19,6 +19,7 @@ "@angular/platform-browser-dynamic": "16.1.2", "@angular/router": "16.1.2", "@nx/angular": "16.4.0", + "@swc/helpers": "~0.5.0", "angular-in-memory-web-api": "^0.16.0", "bootstrap": "^4.4.1", "bootstrap-icons": "^1.4.0", @@ -52,6 +53,9 @@ "@nx/web": "16.4.0", "@nx/workspace": "16.4.0", "@schematics/angular": "16.1.1", + "@swc/cli": "~0.1.62", + "@swc/core": "~1.3.51", + "@swc/jest": "0.2.20", "@types/jest": "29.4.4", "@types/lodash-es": "^4.17.6", "@types/node": "18.7.1", @@ -65,6 +69,7 @@ "husky": "^7.0.4", "jest": "29.4.3", "jest-environment-jsdom": "29.4.3", + "jest-environment-node": "^29.4.1", "jest-jasmine2": "29.4.3", "jest-marbles": "^3.0.2", "jest-preset-angular": "13.1.1", @@ -80,7 +85,8 @@ "source-map-explorer": "^2.5.2", "ts-jest": "29.1.0", "ts-node": "10.9.1", - "typescript": "5.1.3" + "typescript": "5.1.3", + "verdaccio": "^5.0.4" } }, "node_modules/@adobe/css-tools": { @@ -5442,6 +5448,43 @@ "dev": true, "license": "MIT" }, + "node_modules/@jest/create-cache-key-function": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz", + "integrity": "sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ==", + "dev": true, + "dependencies": { + "@jest/types": "^27.5.1" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/@jest/types": { + "version": "27.5.1", + "resolved": "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz", + "integrity": "sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==", + "dev": true, + "dependencies": { + "@types/istanbul-lib-coverage": "^2.0.0", + "@types/istanbul-reports": "^3.0.0", + "@types/node": "*", + "@types/yargs": "^16.0.0", + "chalk": "^4.0.0" + }, + "engines": { + "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" + } + }, + "node_modules/@jest/create-cache-key-function/node_modules/@types/yargs": { + "version": "16.0.5", + "resolved": "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz", + "integrity": "sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ==", + "dev": true, + "dependencies": { + "@types/yargs-parser": "*" + } + }, "node_modules/@jest/environment": { "version": "29.5.0", "resolved": "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz", @@ -5814,6 +5857,25 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "license": "MIT" }, + "node_modules/@mole-inc/bin-wrapper": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/@mole-inc/bin-wrapper/-/bin-wrapper-8.0.1.tgz", + "integrity": "sha512-sTGoeZnjI8N4KS+sW2AN95gDBErhAguvkw/tWdCjeM8bvxpz5lqrnd0vOJABA1A+Ic3zED7PYoLP/RANLgVotA==", + "dev": true, + "dependencies": { + "bin-check": "^4.1.0", + "bin-version-check": "^5.0.0", + "content-disposition": "^0.5.4", + "ext-name": "^5.0.0", + "file-type": "^17.1.6", + "filenamify": "^5.0.2", + "got": "^11.8.5", + "os-filter-obj": "^2.0.0" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + } + }, "node_modules/@nodelib/fs.scandir": { "version": "2.1.5", "resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz", @@ -7028,6 +7090,18 @@ "integrity": "sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ==", "license": "MIT" }, + "node_modules/@sindresorhus/is": { + "version": "4.6.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz", + "integrity": "sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/is?sponsor=1" + } + }, "node_modules/@sinonjs/commons": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz", @@ -7046,6 +7120,306 @@ "@sinonjs/commons": "^2.0.0" } }, + "node_modules/@swc/cli": { + "version": "0.1.62", + "resolved": "https://registry.npmjs.org/@swc/cli/-/cli-0.1.62.tgz", + "integrity": "sha512-kOFLjKY3XH1DWLfXL1/B5MizeNorHR8wHKEi92S/Zi9Md/AK17KSqR8MgyRJ6C1fhKHvbBCl8wboyKAFXStkYw==", + "dev": true, + "dependencies": { + "@mole-inc/bin-wrapper": "^8.0.1", + "commander": "^7.1.0", + "fast-glob": "^3.2.5", + "semver": "^7.3.8", + "slash": "3.0.0", + "source-map": "^0.7.3" + }, + "bin": { + "spack": "bin/spack.js", + "swc": "bin/swc.js", + "swcx": "bin/swcx.js" + }, + "engines": { + "node": ">= 12.13" + }, + "peerDependencies": { + "@swc/core": "^1.2.66", + "chokidar": "^3.5.1" + }, + "peerDependenciesMeta": { + "chokidar": { + "optional": true + } + } + }, + "node_modules/@swc/cli/node_modules/commander": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz", + "integrity": "sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw==", + "dev": true, + "engines": { + "node": ">= 10" + } + }, + "node_modules/@swc/cli/node_modules/source-map": { + "version": "0.7.4", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.7.4.tgz", + "integrity": "sha512-l3BikUxvPOcn5E74dZiq5BGsTb5yEwhaTSzccU6t4sDOH8NWJCstKO5QT2CvtFoK6F0saL7p9xHAqHOlCPJygA==", + "dev": true, + "engines": { + "node": ">= 8" + } + }, + "node_modules/@swc/core": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core/-/core-1.3.88.tgz", + "integrity": "sha512-kaJ5t6Fg/DmJPNeI+jdtCEt7NVKxhUYToq7PF2fMRPFPLKSJzJCZajcp6/gZNcEUCVWaK6pWi/XL79Tzz1FqzQ==", + "dev": true, + "hasInstallScript": true, + "dependencies": { + "@swc/counter": "^0.1.1", + "@swc/types": "^0.1.5" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/swc" + }, + "optionalDependencies": { + "@swc/core-darwin-arm64": "1.3.88", + "@swc/core-darwin-x64": "1.3.88", + "@swc/core-linux-arm-gnueabihf": "1.3.88", + "@swc/core-linux-arm64-gnu": "1.3.88", + "@swc/core-linux-arm64-musl": "1.3.88", + "@swc/core-linux-x64-gnu": "1.3.88", + "@swc/core-linux-x64-musl": "1.3.88", + "@swc/core-win32-arm64-msvc": "1.3.88", + "@swc/core-win32-ia32-msvc": "1.3.88", + "@swc/core-win32-x64-msvc": "1.3.88" + }, + "peerDependencies": { + "@swc/helpers": "^0.5.0" + }, + "peerDependenciesMeta": { + "@swc/helpers": { + "optional": true + } + } + }, + "node_modules/@swc/core-darwin-arm64": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.88.tgz", + "integrity": "sha512-Nb7kKydSQK3FE90pw/GPRFmAkquDQcTixLijNcki2xFBXh/DcGdFUPE/GShQjk8gtQelj2vqZrsGs/GZPGA1mA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-darwin-x64": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-darwin-x64/-/core-darwin-x64-1.3.88.tgz", + "integrity": "sha512-RcCrnjkmLXL1izSHPYLaJKVaxwd64LYiYLqjX2jXG4U50D6LOlmuLeqTJ8aAnENZP19gNpsY9ggY9jD5UQqHAw==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "darwin" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm-gnueabihf": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm-gnueabihf/-/core-linux-arm-gnueabihf-1.3.88.tgz", + "integrity": "sha512-/H7QhpgbWX4xe6jbkgPrhjY543oCCmbPRvBMvZ3iuLb81bEtOFiEp9LYe/95ZW/BTz2z9a6fQtQMqkhAjcrV5w==", + "cpu": [ + "arm" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-gnu": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-gnu/-/core-linux-arm64-gnu-1.3.88.tgz", + "integrity": "sha512-ar/oQJxisjn/Su9rsg+XcBqA54Ylh1SyrZiLslv37OnGr785Xw+C//rw+JGoFmCZSjhGAU5hriOiHJd2S8mtqA==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-arm64-musl": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-linux-arm64-musl/-/core-linux-arm64-musl-1.3.88.tgz", + "integrity": "sha512-ZyUtCk1Y4GpOajbHcnm2JwkFm/m8M/wP3I8iaAm/0yAPIYwQInVdD0Hn++eig2Y+nLJ7gT0QI82fFUDPEIP6Jw==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-gnu": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-gnu/-/core-linux-x64-gnu-1.3.88.tgz", + "integrity": "sha512-VrwGCzKLwimL0Js1yWRQNpcJCLGYkETku9mEI9sM4yF6kzT/jwfOe94udBe9O4GGUv24QkzHXRk+EnGR2LFSOQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-linux-x64-musl": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-linux-x64-musl/-/core-linux-x64-musl-1.3.88.tgz", + "integrity": "sha512-cur5h0JmNfF4ZHb+FBPLePX86lu3FUjxltObWUhqO4QiXzHxWfde6g+pgdqfUAer0cd9VEEjEKGA5OQncXqyCQ==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "linux" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-arm64-msvc": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-win32-arm64-msvc/-/core-win32-arm64-msvc-1.3.88.tgz", + "integrity": "sha512-f9OVuWrey7X0gjCZlVD4d5/9/d0yyxu8KFUOEjyjJ2Kd+pvzRys1U3E0FE1PiiDOng3qrfdOt4HQxyAy2jts9Q==", + "cpu": [ + "arm64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-ia32-msvc": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-win32-ia32-msvc/-/core-win32-ia32-msvc-1.3.88.tgz", + "integrity": "sha512-7KCeTVe8wWRbuiuAwXoHKBkr9nugCAHQe/JGxoevHXxn2h+WwBuWHog1AbS6PvRWSKK8dVhKAAPDNWwdEltA5A==", + "cpu": [ + "ia32" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/core-win32-x64-msvc": { + "version": "1.3.88", + "resolved": "https://registry.npmjs.org/@swc/core-win32-x64-msvc/-/core-win32-x64-msvc-1.3.88.tgz", + "integrity": "sha512-x0wr9kCS2Hmpx7H6gvJHA17G0DnvwToqWDSO1VmePt5hQZZfLzxiHHDHKFv4YYsVPbAU283q4Wa39QSPZeJbTA==", + "cpu": [ + "x64" + ], + "dev": true, + "optional": true, + "os": [ + "win32" + ], + "engines": { + "node": ">=10" + } + }, + "node_modules/@swc/counter": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/@swc/counter/-/counter-0.1.1.tgz", + "integrity": "sha512-xVRaR4u9hcYjFvcSg71Lz5Bo4//CyjAAfMxa7UsaDSYxAshflUkVJWiyVWrfxC59z2kP1IzI4/1BEpnhI9o3Mw==", + "dev": true + }, + "node_modules/@swc/helpers": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz", + "integrity": "sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg==", + "dependencies": { + "tslib": "^2.4.0" + } + }, + "node_modules/@swc/jest": { + "version": "0.2.20", + "resolved": "https://registry.npmjs.org/@swc/jest/-/jest-0.2.20.tgz", + "integrity": "sha512-5qSUBYY1wyIMn7p0Vl9qqV4hMI69oJwZCIPUpBsTFWN2wlwn6RDugzdgCn+bLXVYh+Cxi8bJcZ1uumDgsoL+FA==", + "dev": true, + "dependencies": { + "@jest/create-cache-key-function": "^27.4.2" + }, + "engines": { + "npm": ">= 7.0.0" + }, + "peerDependencies": { + "@swc/core": "*" + } + }, + "node_modules/@swc/types": { + "version": "0.1.5", + "resolved": "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz", + "integrity": "sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw==", + "dev": true + }, + "node_modules/@szmarczak/http-timer": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz", + "integrity": "sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w==", + "dev": true, + "dependencies": { + "defer-to-connect": "^2.0.0" + }, + "engines": { + "node": ">=10" + } + }, + "node_modules/@tokenizer/token": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz", + "integrity": "sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A==", + "dev": true + }, "node_modules/@tootallnate/once": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz", @@ -7207,6 +7581,18 @@ "integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A==", "license": "MIT" }, + "node_modules/@types/cacheable-request": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz", + "integrity": "sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw==", + "dev": true, + "dependencies": { + "@types/http-cache-semantics": "*", + "@types/keyv": "^3.1.4", + "@types/node": "*", + "@types/responselike": "^1.0.0" + } + }, "node_modules/@types/connect": { "version": "3.4.35", "resolved": "https://registry.npmjs.org/@types/connect/-/connect-3.4.35.tgz", @@ -7344,6 +7730,12 @@ "integrity": "sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A==", "license": "MIT" }, + "node_modules/@types/http-cache-semantics": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.2.tgz", + "integrity": "sha512-FD+nQWA2zJjh4L9+pFXqWOi0Hs1ryBCfI+985NjluQ1p8EYtoLvjLOKidXBtZ4/IcxDX4o8/E8qDS3540tNliw==", + "dev": true + }, "node_modules/@types/http-proxy": { "version": "1.17.11", "resolved": "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz", @@ -7419,6 +7811,15 @@ "integrity": "sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ==", "license": "MIT" }, + "node_modules/@types/keyv": { + "version": "3.1.4", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz", + "integrity": "sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/lodash": { "version": "4.14.194", "resolved": "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.194.tgz", @@ -7511,6 +7912,15 @@ "dev": true, "license": "MIT" }, + "node_modules/@types/responselike": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz", + "integrity": "sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA==", + "dev": true, + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/retry": { "version": "0.12.0", "resolved": "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz", @@ -7878,14 +8288,341 @@ "url": "https://opencollective.com/typescript-eslint" } }, - "node_modules/@vitejs/plugin-basic-ssl": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz", - "integrity": "sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A==", + "node_modules/@verdaccio/commons-api": { + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/@verdaccio/commons-api/-/commons-api-10.2.0.tgz", + "integrity": "sha512-F/YZANu4DmpcEV0jronzI7v2fGVWkQ5Mwi+bVmV+ACJ+EzR0c9Jbhtbe5QyLUuzR97t8R5E/Xe53O0cc2LukdQ==", "dev": true, - "license": "MIT", - "engines": { - "node": ">=14.6.0" + "dependencies": { + "http-errors": "2.0.0", + "http-status-codes": "2.2.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/config": { + "version": "7.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/config/-/config-7.0.0-next.1.tgz", + "integrity": "sha512-taFxO0KDajD71unzuQfiRDohW6PM/HeXodM4BcOzdx/k6zpYYzotll2f++0/zkfC2Lhy7KOd//CR8kk0VI628A==", + "dev": true, + "dependencies": { + "@verdaccio/core": "7.0.0-next.1", + "@verdaccio/utils": "7.0.0-next.1", + "debug": "4.3.4", + "js-yaml": "4.1.0", + "lodash": "4.17.21", + "minimatch": "3.1.2", + "yup": "0.32.11" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/core": { + "version": "7.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/core/-/core-7.0.0-next.1.tgz", + "integrity": "sha512-0cHibUcA7EFjMzBq06WEQ4CQxnds+OZX5jVY6MEpQMtWbSiH40pIi9lDiQFKs6lbXXqidNjvY4J19T1zevQLlw==", + "dev": true, + "dependencies": { + "ajv": "8.12.0", + "core-js": "3.30.2", + "http-errors": "2.0.0", + "http-status-codes": "2.2.0", + "process-warning": "1.0.0", + "semver": "7.5.4" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/file-locking": { + "version": "10.3.1", + "resolved": "https://registry.npmjs.org/@verdaccio/file-locking/-/file-locking-10.3.1.tgz", + "integrity": "sha512-oqYLfv3Yg3mAgw9qhASBpjD50osj2AX4IwbkUtyuhhKGyoFU9eZdrbeW6tpnqUnj6yBMtAPm2eGD4BwQuX400g==", + "dev": true, + "dependencies": { + "lockfile": "1.0.4" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/local-storage": { + "version": "10.3.3", + "resolved": "https://registry.npmjs.org/@verdaccio/local-storage/-/local-storage-10.3.3.tgz", + "integrity": "sha512-/n0FH+1hxVg80YhYBfJuW7F2AuvLY2fra8/DTCilWDll9Y5yZDxwntZfcKHJLerCA4atrbJtvaqpWkoV3Q9x8w==", + "dev": true, + "dependencies": { + "@verdaccio/commons-api": "10.2.0", + "@verdaccio/file-locking": "10.3.1", + "@verdaccio/streams": "10.2.1", + "async": "3.2.4", + "debug": "4.3.4", + "lodash": "4.17.21", + "lowdb": "1.0.0", + "mkdirp": "1.0.4" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/logger-7": { + "version": "7.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/logger-7/-/logger-7-7.0.0-next.1.tgz", + "integrity": "sha512-gGAK8af/mgbVlJOqiFQtjQOOkG6PVhgMa44i3ghq+WAc76Szs/n6lzOoQaFNYGg+dWCYRooGWJLTdOlkkL/A+A==", + "dev": true, + "dependencies": { + "@verdaccio/logger-commons": "7.0.0-next.1", + "pino": "7.11.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/logger-commons": { + "version": "7.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/logger-commons/-/logger-commons-7.0.0-next.1.tgz", + "integrity": "sha512-Prjl9A/1jWDM78H6MuW5ZLx2S+JfZY3Bn0G51qiUG0xZUQqgTvcDJni3m9myCVoGw+0dTS+NhkED/jyjodjKcw==", + "dev": true, + "dependencies": { + "@verdaccio/core": "7.0.0-next.1", + "@verdaccio/logger-prettify": "7.0.0-next.0", + "colorette": "2.0.20", + "debug": "4.3.4" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/logger-prettify": { + "version": "7.0.0-next.0", + "resolved": "https://registry.npmjs.org/@verdaccio/logger-prettify/-/logger-prettify-7.0.0-next.0.tgz", + "integrity": "sha512-6akvpkzt6ipkk7v3Non0M9KZq7xYF51QMhJPTFA7JU+hW5AqrAnoMsNAWOzoUMvRr/2Ri33U3VWAOwhmf109Pw==", + "dev": true, + "dependencies": { + "colorette": "2.0.20", + "dayjs": "1.11.7", + "lodash": "4.17.21", + "pino-abstract-transport": "1.0.0", + "sonic-boom": "3.3.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/middleware": { + "version": "7.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/middleware/-/middleware-7.0.0-next.1.tgz", + "integrity": "sha512-ccuMQGfvZjX6gI0+tSDVueB6qMZjzBUZxAI9tDgHaawlqcXrI4RK5QPDsWI9XeeClJJriGmdhVdommZnGYZmuw==", + "dev": true, + "dependencies": { + "@verdaccio/config": "7.0.0-next.1", + "@verdaccio/core": "7.0.0-next.1", + "@verdaccio/url": "12.0.0-next.1", + "@verdaccio/utils": "7.0.0-next.1", + "debug": "4.3.4", + "express": "4.18.2", + "express-rate-limit": "5.5.1", + "lodash": "4.17.21", + "lru-cache": "7.18.3", + "mime": "2.6.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/middleware/node_modules/mime": { + "version": "2.6.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz", + "integrity": "sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=4.0.0" + } + }, + "node_modules/@verdaccio/search": { + "version": "7.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/search/-/search-7.0.0-next.1.tgz", + "integrity": "sha512-LoWi4YVTFTbjEtyAPOfLKZy+neR5ldBzcVWgQJvg9e8fXS+UhQglvu6YWDr2j1yrQqbzzDVfV7YlXf4a3GG6mw==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/signature": { + "version": "7.0.0-next.0", + "resolved": "https://registry.npmjs.org/@verdaccio/signature/-/signature-7.0.0-next.0.tgz", + "integrity": "sha512-9e28xxd/eH1qRd+I+U0QO0af7F+MEFMtcrRapcqYIayk8yGq03cEGoj18LIf+LXyAosu18Y5dTporPz/R6geHg==", + "dev": true, + "dependencies": { + "debug": "4.3.4", + "jsonwebtoken": "9.0.0", + "lodash": "4.17.21" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/signature/node_modules/jsonwebtoken": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz", + "integrity": "sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw==", + "dev": true, + "dependencies": { + "jws": "^3.2.2", + "lodash": "^4.17.21", + "ms": "^2.1.1", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, + "node_modules/@verdaccio/streams": { + "version": "10.2.1", + "resolved": "https://registry.npmjs.org/@verdaccio/streams/-/streams-10.2.1.tgz", + "integrity": "sha512-OojIG/f7UYKxC4dYX8x5ax8QhRx1b8OYUAMz82rUottCuzrssX/4nn5QE7Ank0DUSX3C9l/HPthc4d9uKRJqJQ==", + "dev": true, + "engines": { + "node": ">=12", + "npm": ">=5" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/tarball": { + "version": "12.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/tarball/-/tarball-12.0.0-next.1.tgz", + "integrity": "sha512-uEgeVUa434H2dg+a35Hm+fxxBRU97RblkIYmvvdb+FHMRmsQmlGTJkPqCQd5YM+hkVCWITr4YyAleaysl7cErQ==", + "dev": true, + "dependencies": { + "@verdaccio/core": "7.0.0-next.1", + "@verdaccio/url": "12.0.0-next.1", + "@verdaccio/utils": "7.0.0-next.1", + "debug": "4.3.4", + "lodash": "4.17.21" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/ui-theme": { + "version": "7.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/ui-theme/-/ui-theme-7.0.0-next.1.tgz", + "integrity": "sha512-0Bp2M5oejxjXNzzMBB4qsXIES74hFecHw+QhGswcpViNYi1nM2Yl4nENHE+h2BFOE0Lk4m8NKOijyRM8yKDneg==", + "dev": true + }, + "node_modules/@verdaccio/url": { + "version": "12.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/url/-/url-12.0.0-next.1.tgz", + "integrity": "sha512-8XL0ZGSMLnquKv/xizjbClf3xGXWWnEyjhP5GZEgtjMdkvMhzzV5B9FdNOpTdxP7rcDnRqf78hO8urCz3+4E7g==", + "dev": true, + "dependencies": { + "@verdaccio/core": "7.0.0-next.1", + "debug": "4.3.4", + "lodash": "4.17.21", + "validator": "13.9.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@verdaccio/url/node_modules/validator": { + "version": "13.9.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz", + "integrity": "sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, + "node_modules/@verdaccio/utils": { + "version": "7.0.0-next.1", + "resolved": "https://registry.npmjs.org/@verdaccio/utils/-/utils-7.0.0-next.1.tgz", + "integrity": "sha512-cgDYNNjD0lWFMf06SRhizFb9qULVcE5Wq7Qm9HRbxqsLdSBWShvf4p9jvlk3PSzoSi/tRHym1VMq/DhoZfFATw==", + "dev": true, + "dependencies": { + "@verdaccio/core": "7.0.0-next.1", + "lodash": "4.17.21", + "minimatch": "3.1.2", + "semver": "7.5.4" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/@vitejs/plugin-basic-ssl": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz", + "integrity": "sha512-pcub+YbFtFhaGRTo1832FQHQSHvMrlb43974e2eS8EKleR3p1cDdkJFPci1UhwkEf1J9Bz+wKBSzqpKp7nNj2A==", + "dev": true, + "license": "MIT", + "engines": { + "node": ">=14.6.0" }, "peerDependencies": { "vite": "^3.0.0 || ^4.0.0" @@ -8114,6 +8851,18 @@ "integrity": "sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q==", "dev": true }, + "node_modules/abort-controller": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz", + "integrity": "sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg==", + "dev": true, + "dependencies": { + "event-target-shim": "^5.0.0" + }, + "engines": { + "node": ">=6.5" + } + }, "node_modules/accepts": { "version": "1.3.8", "resolved": "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz", @@ -8393,6 +9142,15 @@ "node": ">= 8" } }, + "node_modules/apache-md5": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.8.tgz", + "integrity": "sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/aproba": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz", @@ -8553,6 +9311,15 @@ "node": ">= 4.0.0" } }, + "node_modules/atomic-sleep": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz", + "integrity": "sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/autoprefixer": { "version": "10.4.14", "resolved": "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz", @@ -8772,6 +9539,12 @@ "tweetnacl": "^0.14.3" } }, + "node_modules/bcryptjs": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz", + "integrity": "sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ==", + "dev": true + }, "node_modules/big.js": { "version": "5.2.2", "resolved": "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz", @@ -8781,6 +9554,169 @@ "node": "*" } }, + "node_modules/bin-check": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz", + "integrity": "sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA==", + "dev": true, + "dependencies": { + "execa": "^0.7.0", + "executable": "^4.1.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-check/node_modules/cross-spawn": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz", + "integrity": "sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A==", + "dev": true, + "dependencies": { + "lru-cache": "^4.0.1", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "node_modules/bin-check/node_modules/execa": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz", + "integrity": "sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw==", + "dev": true, + "dependencies": { + "cross-spawn": "^5.0.1", + "get-stream": "^3.0.0", + "is-stream": "^1.1.0", + "npm-run-path": "^2.0.0", + "p-finally": "^1.0.0", + "signal-exit": "^3.0.0", + "strip-eof": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-check/node_modules/get-stream": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz", + "integrity": "sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-check/node_modules/is-stream": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz", + "integrity": "sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bin-check/node_modules/lru-cache": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz", + "integrity": "sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g==", + "dev": true, + "dependencies": { + "pseudomap": "^1.0.2", + "yallist": "^2.1.2" + } + }, + "node_modules/bin-check/node_modules/npm-run-path": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz", + "integrity": "sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw==", + "dev": true, + "dependencies": { + "path-key": "^2.0.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-check/node_modules/path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/bin-check/node_modules/shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg==", + "dev": true, + "dependencies": { + "shebang-regex": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bin-check/node_modules/shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/bin-check/node_modules/which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "dependencies": { + "isexe": "^2.0.0" + }, + "bin": { + "which": "bin/which" + } + }, + "node_modules/bin-check/node_modules/yallist": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz", + "integrity": "sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A==", + "dev": true + }, + "node_modules/bin-version": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/bin-version/-/bin-version-6.0.0.tgz", + "integrity": "sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw==", + "dev": true, + "dependencies": { + "execa": "^5.0.0", + "find-versions": "^5.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/bin-version-check": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/bin-version-check/-/bin-version-check-5.1.0.tgz", + "integrity": "sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g==", + "dev": true, + "dependencies": { + "bin-version": "^6.0.0", + "semver": "^7.5.3", + "semver-truncate": "^3.0.0" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -9045,6 +9981,12 @@ "node": "*" } }, + "node_modules/buffer-equal-constant-time": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz", + "integrity": "sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA==", + "dev": true + }, "node_modules/buffer-from": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", @@ -9178,6 +10120,33 @@ "node": ">=8" } }, + "node_modules/cacheable-lookup": { + "version": "5.0.4", + "resolved": "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz", + "integrity": "sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA==", + "dev": true, + "engines": { + "node": ">=10.6.0" + } + }, + "node_modules/cacheable-request": { + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz", + "integrity": "sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg==", + "dev": true, + "dependencies": { + "clone-response": "^1.0.2", + "get-stream": "^5.1.0", + "http-cache-semantics": "^4.0.0", + "keyv": "^4.0.0", + "lowercase-keys": "^2.0.0", + "normalize-url": "^6.0.1", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/cachedir": { "version": "2.3.0", "resolved": "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz", @@ -9487,6 +10456,18 @@ "node": ">= 10" } }, + "node_modules/clipanion": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/clipanion/-/clipanion-3.2.1.tgz", + "integrity": "sha512-dYFdjLb7y1ajfxQopN05mylEpK9ZX0sO1/RfMXdfmwjlIsPkbh4p7A682x++zFPLDCo1x3p82dtljHf5cW2LKA==", + "dev": true, + "dependencies": { + "typanion": "^3.8.0" + }, + "peerDependencies": { + "typanion": "*" + } + }, "node_modules/cliui": { "version": "7.0.4", "resolved": "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz", @@ -9534,6 +10515,18 @@ "node": ">=0.10.0" } }, + "node_modules/clone-response": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz", + "integrity": "sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA==", + "dev": true, + "dependencies": { + "mimic-response": "^1.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/co": { "version": "4.6.0", "resolved": "https://registry.npmjs.org/co/-/co-4.6.0.tgz", @@ -10078,6 +11071,19 @@ "integrity": "sha512-QADzlaHc8icV8I7vbaJXJwod9HWYp8uCqf1xa4OfNu1T7JVxQIrUgOWtHdNDtPiywmFbiS12VjotIXLrKM3orQ==", "license": "MIT" }, + "node_modules/cookies": { + "version": "0.8.0", + "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz", + "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==", + "dev": true, + "dependencies": { + "depd": "~2.0.0", + "keygrip": "~1.1.0" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/copy-anything": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz", @@ -10170,6 +11176,17 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/core-js": { + "version": "3.30.2", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz", + "integrity": "sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg==", + "dev": true, + "hasInstallScript": true, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/core-js" + } + }, "node_modules/core-util-is": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", @@ -10177,6 +11194,19 @@ "dev": true, "license": "MIT" }, + "node_modules/cors": { + "version": "2.8.5", + "resolved": "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz", + "integrity": "sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g==", + "dev": true, + "dependencies": { + "object-assign": "^4", + "vary": "^1" + }, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/corser": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", @@ -11496,6 +12526,33 @@ "dev": true, "license": "MIT" }, + "node_modules/decompress-response": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz", + "integrity": "sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ==", + "dev": true, + "dependencies": { + "mimic-response": "^3.1.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/decompress-response/node_modules/mimic-response": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz", + "integrity": "sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/dedent": { "version": "0.7.0", "resolved": "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz", @@ -11573,6 +12630,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/defer-to-connect": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz", + "integrity": "sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/define-lazy-prop": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz", @@ -11839,6 +12905,18 @@ "integrity": "sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg==", "license": "MIT" }, + "node_modules/duplexify": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz", + "integrity": "sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw==", + "dev": true, + "dependencies": { + "end-of-stream": "^1.4.1", + "inherits": "^2.0.3", + "readable-stream": "^3.1.1", + "stream-shift": "^1.0.0" + } + }, "node_modules/eastasianwidth": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz", @@ -11857,6 +12935,15 @@ "safer-buffer": "^2.1.0" } }, + "node_modules/ecdsa-sig-formatter": { + "version": "1.0.11", + "resolved": "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz", + "integrity": "sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ==", + "dev": true, + "dependencies": { + "safe-buffer": "^5.0.1" + } + }, "node_modules/ee-first": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz", @@ -11985,6 +13072,18 @@ "node": ">=6" } }, + "node_modules/envinfo": { + "version": "7.10.0", + "resolved": "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz", + "integrity": "sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw==", + "dev": true, + "bin": { + "envinfo": "dist/cli.js" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/err-code": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz", @@ -12484,6 +13583,15 @@ "node": ">= 0.6" } }, + "node_modules/event-target-shim": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz", + "integrity": "sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/eventemitter-asyncresource": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz", @@ -12633,6 +13741,12 @@ "node": ">= 0.10.0" } }, + "node_modules/express-rate-limit": { + "version": "5.5.1", + "resolved": "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.5.1.tgz", + "integrity": "sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg==", + "dev": true + }, "node_modules/express/node_modules/debug": { "version": "2.6.9", "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", @@ -12648,6 +13762,31 @@ "integrity": "sha512-Tpp60P6IUJDTuOq/5Z8cdskzJujfwqfOTkrwIwj7IRISpnkJnT6SyJ4PCPnGMoFjC9ddhal5KVIYtAt97ix05A==", "license": "MIT" }, + "node_modules/ext-list": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz", + "integrity": "sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA==", + "dev": true, + "dependencies": { + "mime-db": "^1.28.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/ext-name": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz", + "integrity": "sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ==", + "dev": true, + "dependencies": { + "ext-list": "^2.0.0", + "sort-keys-length": "^1.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/extend": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz", @@ -12762,6 +13901,21 @@ "dev": true, "license": "MIT" }, + "node_modules/fast-redact": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", + "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/fast-safe-stringify": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz", + "integrity": "sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA==", + "dev": true + }, "node_modules/fastq": { "version": "1.15.0", "resolved": "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz", @@ -12899,6 +14053,23 @@ "url": "https://opencollective.com/webpack" } }, + "node_modules/file-type": { + "version": "17.1.6", + "resolved": "https://registry.npmjs.org/file-type/-/file-type-17.1.6.tgz", + "integrity": "sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw==", + "dev": true, + "dependencies": { + "readable-web-to-node-stream": "^3.0.2", + "strtok3": "^7.0.0-alpha.9", + "token-types": "^5.0.0-alpha.2" + }, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/file-type?sponsor=1" + } + }, "node_modules/filelist": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz", @@ -12929,6 +14100,35 @@ "node": ">=10" } }, + "node_modules/filename-reserved-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz", + "integrity": "sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/filenamify": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/filenamify/-/filenamify-5.1.1.tgz", + "integrity": "sha512-M45CbrJLGACfrPOkrTp3j2EcO9OBkKUYME0eiqOCa7i2poaklU0jhlIaMlr8ijLorT0uLAzrn3qXOp5684CkfA==", + "dev": true, + "dependencies": { + "filename-reserved-regex": "^3.0.0", + "strip-outer": "^2.0.0", + "trim-repeated": "^2.0.0" + }, + "engines": { + "node": ">=12.20" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/fill-range": { "version": "7.0.1", "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz", @@ -13004,6 +14204,21 @@ "node": ">=8" } }, + "node_modules/find-versions": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz", + "integrity": "sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg==", + "dev": true, + "dependencies": { + "semver-regex": "^4.0.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/flat": { "version": "5.0.2", "resolved": "https://registry.npmjs.org/flat/-/flat-5.0.2.tgz", @@ -13699,6 +14914,31 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/got": { + "version": "11.8.6", + "resolved": "https://registry.npmjs.org/got/-/got-11.8.6.tgz", + "integrity": "sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g==", + "dev": true, + "dependencies": { + "@sindresorhus/is": "^4.0.0", + "@szmarczak/http-timer": "^4.0.5", + "@types/cacheable-request": "^6.0.1", + "@types/responselike": "^1.0.0", + "cacheable-lookup": "^5.0.3", + "cacheable-request": "^7.0.2", + "decompress-response": "^6.0.0", + "http2-wrapper": "^1.0.0-beta.5.2", + "lowercase-keys": "^2.0.0", + "p-cancelable": "^2.0.0", + "responselike": "^2.0.0" + }, + "engines": { + "node": ">=10.19.0" + }, + "funding": { + "url": "https://github.com/sindresorhus/got?sponsor=1" + } + }, "node_modules/graceful-fs": { "version": "4.2.11", "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", @@ -13756,6 +14996,51 @@ "uglify-js": "^3.1.4" } }, + "node_modules/har-schema": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz", + "integrity": "sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/har-validator": { + "version": "5.1.5", + "resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz", + "integrity": "sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w==", + "deprecated": "this library is no longer supported", + "dev": true, + "dependencies": { + "ajv": "^6.12.3", + "har-schema": "^2.0.0" + }, + "engines": { + "node": ">=6" + } + }, + "node_modules/har-validator/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/har-validator/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, "node_modules/hard-rejection": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz", @@ -14131,6 +15416,37 @@ "node": ">=0.10" } }, + "node_modules/http-status-codes": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz", + "integrity": "sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng==", + "dev": true + }, + "node_modules/http2-wrapper": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz", + "integrity": "sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg==", + "dev": true, + "dependencies": { + "quick-lru": "^5.1.1", + "resolve-alpn": "^1.0.0" + }, + "engines": { + "node": ">=10.19.0" + } + }, + "node_modules/http2-wrapper/node_modules/quick-lru": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz", + "integrity": "sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/https-proxy-agent": { "version": "5.0.1", "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz", @@ -14850,6 +16166,12 @@ "dev": true, "license": "MIT" }, + "node_modules/is-promise": { + "version": "2.2.2", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz", + "integrity": "sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ==", + "dev": true + }, "node_modules/is-reference": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz", @@ -16199,6 +17521,12 @@ "node": ">=4" } }, + "node_modules/json-buffer": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz", + "integrity": "sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ==", + "dev": true + }, "node_modules/json-parse-better-errors": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz", @@ -16315,6 +17643,22 @@ "node": "*" } }, + "node_modules/jsonwebtoken": { + "version": "9.0.1", + "resolved": "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz", + "integrity": "sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg==", + "dev": true, + "dependencies": { + "jws": "^3.2.2", + "lodash": "^4.17.21", + "ms": "^2.1.1", + "semver": "^7.3.8" + }, + "engines": { + "node": ">=12", + "npm": ">=6" + } + }, "node_modules/jsprim": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz", @@ -16331,6 +17675,27 @@ "verror": "1.10.0" } }, + "node_modules/jwa": { + "version": "1.4.1", + "resolved": "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz", + "integrity": "sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA==", + "dev": true, + "dependencies": { + "buffer-equal-constant-time": "1.0.1", + "ecdsa-sig-formatter": "1.0.11", + "safe-buffer": "^5.0.1" + } + }, + "node_modules/jws": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz", + "integrity": "sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA==", + "dev": true, + "dependencies": { + "jwa": "^1.4.1", + "safe-buffer": "^5.0.1" + } + }, "node_modules/karma-source-map-support": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz", @@ -16341,6 +17706,27 @@ "source-map-support": "^0.5.5" } }, + "node_modules/keygrip": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz", + "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==", + "dev": true, + "dependencies": { + "tsscmp": "1.0.6" + }, + "engines": { + "node": ">= 0.6" + } + }, + "node_modules/keyv": { + "version": "4.5.3", + "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz", + "integrity": "sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug==", + "dev": true, + "dependencies": { + "json-buffer": "3.0.1" + } + }, "node_modules/kind-of": { "version": "6.0.3", "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz", @@ -16980,6 +18366,15 @@ "node": ">=8" } }, + "node_modules/lockfile": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz", + "integrity": "sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA==", + "dev": true, + "dependencies": { + "signal-exit": "^3.0.2" + } + }, "node_modules/lodash": { "version": "4.17.21", "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", @@ -17107,6 +18502,40 @@ "node": ">=8" } }, + "node_modules/lowdb": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz", + "integrity": "sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.3", + "is-promise": "^2.1.0", + "lodash": "4", + "pify": "^3.0.0", + "steno": "^0.4.1" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/lowdb/node_modules/pify": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-3.0.0.tgz", + "integrity": "sha512-C3FsVNH1udSEX48gGX1xfvwTWfsYWj5U+8/uK15BGzIGrKoUpghX8hWZwa/OFnakBiiVNmBvemTJR5mcy7iPcg==", + "dev": true, + "engines": { + "node": ">=4" + } + }, + "node_modules/lowercase-keys": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz", + "integrity": "sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/lru-cache": { "version": "7.18.3", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz", @@ -17476,6 +18905,15 @@ "node": ">=6" } }, + "node_modules/mimic-response": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz", + "integrity": "sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/min-indent": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz", @@ -17740,6 +19178,66 @@ "dev": true, "license": "ISC" }, + "node_modules/mv": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz", + "integrity": "sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg==", + "dev": true, + "dependencies": { + "mkdirp": "~0.5.1", + "ncp": "~2.0.0", + "rimraf": "~2.4.0" + }, + "engines": { + "node": ">=0.8.0" + } + }, + "node_modules/mv/node_modules/glob": { + "version": "6.0.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz", + "integrity": "sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A==", + "dev": true, + "dependencies": { + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "2 || 3", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + }, + "engines": { + "node": "*" + } + }, + "node_modules/mv/node_modules/mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "dependencies": { + "minimist": "^1.2.6" + }, + "bin": { + "mkdirp": "bin/cmd.js" + } + }, + "node_modules/mv/node_modules/rimraf": { + "version": "2.4.5", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz", + "integrity": "sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ==", + "dev": true, + "dependencies": { + "glob": "^6.0.1" + }, + "bin": { + "rimraf": "bin.js" + } + }, + "node_modules/nanoclone": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz", + "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==", + "dev": true + }, "node_modules/nanoid": { "version": "3.3.6", "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz", @@ -17771,6 +19269,15 @@ "dev": true, "license": "MIT" }, + "node_modules/ncp": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz", + "integrity": "sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA==", + "dev": true, + "bin": { + "ncp": "bin/ncp" + } + }, "node_modules/needle": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz", @@ -18030,6 +19537,48 @@ "integrity": "sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A==", "license": "MIT" }, + "node_modules/node-fetch": { + "version": "2.6.7", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", + "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "dev": true, + "dependencies": { + "whatwg-url": "^5.0.0" + }, + "engines": { + "node": "4.x || >=6.0.0" + }, + "peerDependencies": { + "encoding": "^0.1.0" + }, + "peerDependenciesMeta": { + "encoding": { + "optional": true + } + } + }, + "node_modules/node-fetch/node_modules/tr46": { + "version": "0.0.3", + "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", + "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==", + "dev": true + }, + "node_modules/node-fetch/node_modules/webidl-conversions": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", + "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==", + "dev": true + }, + "node_modules/node-fetch/node_modules/whatwg-url": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", + "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", + "dev": true, + "dependencies": { + "tr46": "~0.0.3", + "webidl-conversions": "^3.0.0" + } + }, "node_modules/node-forge": { "version": "1.3.1", "resolved": "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz", @@ -18588,6 +20137,24 @@ "node": ">=10" } }, + "node_modules/oauth-sign": { + "version": "0.9.0", + "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", + "integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==", + "dev": true, + "engines": { + "node": "*" + } + }, + "node_modules/object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/object-inspect": { "version": "1.12.3", "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz", @@ -18649,6 +20216,12 @@ "integrity": "sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==", "license": "MIT" }, + "node_modules/on-exit-leak-free": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz", + "integrity": "sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg==", + "dev": true + }, "node_modules/on-finished": { "version": "2.4.1", "resolved": "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz", @@ -18798,6 +20371,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/os-filter-obj": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz", + "integrity": "sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg==", + "dev": true, + "dependencies": { + "arch": "^2.1.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/os-tmpdir": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", @@ -18815,6 +20400,15 @@ "dev": true, "license": "MIT" }, + "node_modules/p-cancelable": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz", + "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/p-finally": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz", @@ -19178,6 +20772,19 @@ "node": ">=8" } }, + "node_modules/peek-readable": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz", + "integrity": "sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A==", + "dev": true, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -19232,6 +20839,121 @@ "node": ">=0.10.0" } }, + "node_modules/pino": { + "version": "7.11.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-7.11.0.tgz", + "integrity": "sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0", + "fast-redact": "^3.0.0", + "on-exit-leak-free": "^0.2.0", + "pino-abstract-transport": "v0.5.0", + "pino-std-serializers": "^4.0.0", + "process-warning": "^1.0.0", + "quick-format-unescaped": "^4.0.3", + "real-require": "^0.1.0", + "safe-stable-stringify": "^2.1.0", + "sonic-boom": "^2.2.1", + "thread-stream": "^0.15.1" + }, + "bin": { + "pino": "bin.js" + } + }, + "node_modules/pino-abstract-transport": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz", + "integrity": "sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA==", + "dev": true, + "dependencies": { + "readable-stream": "^4.0.0", + "split2": "^4.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/buffer": { + "version": "6.0.3", + "resolved": "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz", + "integrity": "sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA==", + "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/feross" + }, + { + "type": "patreon", + "url": "https://www.patreon.com/feross" + }, + { + "type": "consulting", + "url": "https://feross.org/support" + } + ], + "dependencies": { + "base64-js": "^1.3.1", + "ieee754": "^1.2.1" + } + }, + "node_modules/pino-abstract-transport/node_modules/readable-stream": { + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", + "dev": true, + "dependencies": { + "abort-controller": "^3.0.0", + "buffer": "^6.0.3", + "events": "^3.3.0", + "process": "^0.11.10", + "string_decoder": "^1.3.0" + }, + "engines": { + "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + } + }, + "node_modules/pino-abstract-transport/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, + "node_modules/pino-std-serializers": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz", + "integrity": "sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q==", + "dev": true + }, + "node_modules/pino/node_modules/pino-abstract-transport": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz", + "integrity": "sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ==", + "dev": true, + "dependencies": { + "duplexify": "^4.1.2", + "split2": "^4.0.0" + } + }, + "node_modules/pino/node_modules/sonic-boom": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz", + "integrity": "sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/pino/node_modules/split2": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz", + "integrity": "sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg==", + "dev": true, + "engines": { + "node": ">= 10.x" + } + }, "node_modules/pirates": { "version": "4.0.5", "resolved": "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz", @@ -19268,6 +20990,15 @@ "node": ">=8" } }, + "node_modules/pkginfo": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz", + "integrity": "sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ==", + "dev": true, + "engines": { + "node": ">= 0.4.0" + } + }, "node_modules/portfinder": { "version": "1.0.32", "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", @@ -20607,12 +22338,27 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/process": { + "version": "0.11.10", + "resolved": "https://registry.npmjs.org/process/-/process-0.11.10.tgz", + "integrity": "sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==", + "dev": true, + "engines": { + "node": ">= 0.6.0" + } + }, "node_modules/process-nextick-args": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz", "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==", "license": "MIT" }, + "node_modules/process-warning": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz", + "integrity": "sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q==", + "dev": true + }, "node_modules/promise-inflight": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz", @@ -20656,6 +22402,12 @@ "node": ">= 6" } }, + "node_modules/property-expr": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz", + "integrity": "sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA==", + "dev": true + }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -20691,6 +22443,12 @@ "license": "MIT", "optional": true }, + "node_modules/pseudomap": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz", + "integrity": "sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==", + "dev": true + }, "node_modules/psl": { "version": "1.9.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz", @@ -20787,6 +22545,12 @@ ], "license": "MIT" }, + "node_modules/quick-format-unescaped": { + "version": "4.0.4", + "resolved": "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz", + "integrity": "sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg==", + "dev": true + }, "node_modules/quick-lru": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz", @@ -21124,6 +22888,22 @@ "node": ">= 6" } }, + "node_modules/readable-web-to-node-stream": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz", + "integrity": "sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw==", + "dev": true, + "dependencies": { + "readable-stream": "^3.6.0" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/readdirp": { "version": "3.6.0", "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz", @@ -21136,6 +22916,15 @@ "node": ">=8.10.0" } }, + "node_modules/real-require": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/real-require/-/real-require-0.1.0.tgz", + "integrity": "sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg==", + "dev": true, + "engines": { + "node": ">= 12.13.0" + } + }, "node_modules/redent": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz", @@ -21242,37 +23031,145 @@ "unicode-match-property-value-ecmascript": "^2.1.0" }, "engines": { - "node": ">=4" + "node": ">=4" + } + }, + "node_modules/regjsparser": { + "version": "0.9.1", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", + "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", + "license": "BSD-2-Clause", + "dependencies": { + "jsesc": "~0.5.0" + }, + "bin": { + "regjsparser": "bin/parser" + } + }, + "node_modules/regjsparser/node_modules/jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", + "bin": { + "jsesc": "bin/jsesc" + } + }, + "node_modules/request": { + "version": "2.88.2", + "resolved": "https://registry.npmjs.org/request/-/request-2.88.2.tgz", + "integrity": "sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw==", + "deprecated": "request has been deprecated, see https://github.com/request/request/issues/3142", + "dev": true, + "dependencies": { + "aws-sign2": "~0.7.0", + "aws4": "^1.8.0", + "caseless": "~0.12.0", + "combined-stream": "~1.0.6", + "extend": "~3.0.2", + "forever-agent": "~0.6.1", + "form-data": "~2.3.2", + "har-validator": "~5.1.3", + "http-signature": "~1.2.0", + "is-typedarray": "~1.0.0", + "isstream": "~0.1.2", + "json-stringify-safe": "~5.0.1", + "mime-types": "~2.1.19", + "oauth-sign": "~0.9.0", + "performance-now": "^2.1.0", + "qs": "~6.5.2", + "safe-buffer": "^5.1.2", + "tough-cookie": "~2.5.0", + "tunnel-agent": "^0.6.0", + "uuid": "^3.3.2" + }, + "engines": { + "node": ">= 6" + } + }, + "node_modules/request-progress": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", + "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "dev": true, + "license": "MIT", + "dependencies": { + "throttleit": "^1.0.0" + } + }, + "node_modules/request/node_modules/form-data": { + "version": "2.3.3", + "resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz", + "integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==", + "dev": true, + "dependencies": { + "asynckit": "^0.4.0", + "combined-stream": "^1.0.6", + "mime-types": "^2.1.12" + }, + "engines": { + "node": ">= 0.12" + } + }, + "node_modules/request/node_modules/http-signature": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz", + "integrity": "sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ==", + "dev": true, + "dependencies": { + "assert-plus": "^1.0.0", + "jsprim": "^1.2.2", + "sshpk": "^1.7.0" + }, + "engines": { + "node": ">=0.8", + "npm": ">=1.3.7" + } + }, + "node_modules/request/node_modules/jsprim": { + "version": "1.4.2", + "resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz", + "integrity": "sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw==", + "dev": true, + "dependencies": { + "assert-plus": "1.0.0", + "extsprintf": "1.3.0", + "json-schema": "0.4.0", + "verror": "1.10.0" + }, + "engines": { + "node": ">=0.6.0" } }, - "node_modules/regjsparser": { - "version": "0.9.1", - "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.9.1.tgz", - "integrity": "sha512-dQUtn90WanSNl+7mQKcXAgZxvUe7Z0SqXlgzv0za4LwiUhyzBC58yQO3liFoUgu8GiJVInAhJjkj1N0EtQ5nkQ==", - "license": "BSD-2-Clause", - "dependencies": { - "jsesc": "~0.5.0" - }, - "bin": { - "regjsparser": "bin/parser" + "node_modules/request/node_modules/qs": { + "version": "6.5.3", + "resolved": "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz", + "integrity": "sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA==", + "dev": true, + "engines": { + "node": ">=0.6" } }, - "node_modules/regjsparser/node_modules/jsesc": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", - "integrity": "sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA==", - "bin": { - "jsesc": "bin/jsesc" + "node_modules/request/node_modules/tough-cookie": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.5.0.tgz", + "integrity": "sha512-nlLsUzgm1kfLXSXfRZMc1KLAugd4hqJHDTvc2hDIwS3mZAfMEuMbc03SujMF+GEcpaX/qboeycw6iO8JwVv2+g==", + "dev": true, + "dependencies": { + "psl": "^1.1.28", + "punycode": "^2.1.1" + }, + "engines": { + "node": ">=0.8" } }, - "node_modules/request-progress": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/request-progress/-/request-progress-3.0.0.tgz", - "integrity": "sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==", + "node_modules/request/node_modules/uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "deprecated": "Please upgrade to version 7 or higher. Older versions may use Math.random() in certain circumstances, which is known to be problematic. See https://v8.dev/blog/math-random for details.", "dev": true, - "license": "MIT", - "dependencies": { - "throttleit": "^1.0.0" + "bin": { + "uuid": "bin/uuid" } }, "node_modules/require-directory": { @@ -21316,6 +23213,12 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/resolve-alpn": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", + "dev": true + }, "node_modules/resolve-cwd": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz", @@ -21377,6 +23280,18 @@ "node": ">=10" } }, + "node_modules/responselike": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz", + "integrity": "sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw==", + "dev": true, + "dependencies": { + "lowercase-keys": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/restore-cursor": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", @@ -21675,6 +23590,15 @@ "dev": true, "license": "ISC" }, + "node_modules/safe-stable-stringify": { + "version": "2.4.3", + "resolved": "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz", + "integrity": "sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g==", + "dev": true, + "engines": { + "node": ">=10" + } + }, "node_modules/safer-buffer": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", @@ -21799,10 +23723,9 @@ } }, "node_modules/semver": { - "version": "7.5.0", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz", - "integrity": "sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA==", - "license": "ISC", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dependencies": { "lru-cache": "^6.0.0" }, @@ -21813,6 +23736,33 @@ "node": ">=10" } }, + "node_modules/semver-regex": { + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz", + "integrity": "sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/semver-truncate": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/semver-truncate/-/semver-truncate-3.0.0.tgz", + "integrity": "sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg==", + "dev": true, + "dependencies": { + "semver": "^7.3.5" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/semver/node_modules/lru-cache": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-6.0.0.tgz", @@ -22138,6 +24088,48 @@ "node": ">= 10" } }, + "node_modules/sonic-boom": { + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", + "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", + "dev": true, + "dependencies": { + "atomic-sleep": "^1.0.0" + } + }, + "node_modules/sort-keys": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz", + "integrity": "sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg==", + "dev": true, + "dependencies": { + "is-plain-obj": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys-length": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz", + "integrity": "sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw==", + "dev": true, + "dependencies": { + "sort-keys": "^1.0.0" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/sort-keys/node_modules/is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/source-map": { "version": "0.6.1", "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz", @@ -22458,6 +24450,15 @@ "node": ">= 0.8" } }, + "node_modules/steno": { + "version": "0.4.4", + "resolved": "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz", + "integrity": "sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.1.3" + } + }, "node_modules/stop-iteration-iterator": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz", @@ -22471,6 +24472,12 @@ "node": ">= 0.4" } }, + "node_modules/stream-shift": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz", + "integrity": "sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ==", + "dev": true + }, "node_modules/string_decoder": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz", @@ -22575,6 +24582,15 @@ "node": ">=4" } }, + "node_modules/strip-eof": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz", + "integrity": "sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q==", + "dev": true, + "engines": { + "node": ">=0.10.0" + } + }, "node_modules/strip-final-newline": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", @@ -22609,6 +24625,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/strip-outer": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-outer/-/strip-outer-2.0.0.tgz", + "integrity": "sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg==", + "dev": true, + "engines": { + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/strong-log-transformer": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz", @@ -22626,6 +24654,23 @@ "node": ">=4" } }, + "node_modules/strtok3": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz", + "integrity": "sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ==", + "dev": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "peek-readable": "^5.0.0" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, "node_modules/style-inject": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/style-inject/-/style-inject-0.3.0.tgz", @@ -23125,6 +25170,15 @@ "dev": true, "license": "MIT" }, + "node_modules/thread-stream": { + "version": "0.15.2", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-0.15.2.tgz", + "integrity": "sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA==", + "dev": true, + "dependencies": { + "real-require": "^0.1.0" + } + }, "node_modules/throttleit": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz", @@ -23202,6 +25256,29 @@ "node": ">=0.6" } }, + "node_modules/token-types": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz", + "integrity": "sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg==", + "dev": true, + "dependencies": { + "@tokenizer/token": "^0.3.0", + "ieee754": "^1.2.1" + }, + "engines": { + "node": ">=14.16" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/Borewit" + } + }, + "node_modules/toposort": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz", + "integrity": "sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg==", + "dev": true + }, "node_modules/tough-cookie": { "version": "4.1.2", "resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz", @@ -23261,6 +25338,30 @@ "node": ">=8" } }, + "node_modules/trim-repeated": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/trim-repeated/-/trim-repeated-2.0.0.tgz", + "integrity": "sha512-QUHBFTJGdOwmp0tbOG505xAgOp/YliZP/6UgafFXYZ26WT1bvQmSMJUvkeVSASuJJHbqsFbynTvkd5W8RBTipg==", + "dev": true, + "dependencies": { + "escape-string-regexp": "^5.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/trim-repeated/node_modules/escape-string-regexp": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz", + "integrity": "sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/ts-action": { "version": "11.0.0", "resolved": "https://registry.npmjs.org/ts-action/-/ts-action-11.0.0.tgz", @@ -23417,6 +25518,15 @@ "integrity": "sha512-336iVw3rtn2BUK7ORdIAHTyxHGRIHVReokCR3XjbckJMK7ms8FysBfhLR8IXnAgy7T0PTPNBWKiH514FOW/WSg==", "license": "0BSD" }, + "node_modules/tsscmp": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz", + "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA==", + "dev": true, + "engines": { + "node": ">=0.6.x" + } + }, "node_modules/tsutils": { "version": "3.21.0", "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz", @@ -23472,6 +25582,12 @@ "dev": true, "license": "Unlicense" }, + "node_modules/typanion": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz", + "integrity": "sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug==", + "dev": true + }, "node_modules/type-check": { "version": "0.3.2", "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", @@ -23662,6 +25778,12 @@ "node": ">= 10.0.0" } }, + "node_modules/unix-crypt-td-js": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz", + "integrity": "sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw==", + "dev": true + }, "node_modules/unpipe": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz", @@ -23810,6 +25932,15 @@ "node": "^14.17.0 || ^16.13.0 || >=18.0.0" } }, + "node_modules/validator": { + "version": "13.11.0", + "resolved": "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz", + "integrity": "sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ==", + "dev": true, + "engines": { + "node": ">= 0.10" + } + }, "node_modules/vary": { "version": "1.1.2", "resolved": "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz", @@ -23819,6 +25950,143 @@ "node": ">= 0.8" } }, + "node_modules/verdaccio": { + "version": "5.26.2", + "resolved": "https://registry.npmjs.org/verdaccio/-/verdaccio-5.26.2.tgz", + "integrity": "sha512-JWkjJn+m7WmIA8rEcJw3r/MVg6uFgOZKt6lX8/zveyHCjth+NCLMS7Zjt16dEWMKeSkTVRakifzBGv2IXipt5g==", + "dev": true, + "dependencies": { + "@verdaccio/config": "7.0.0-next.1", + "@verdaccio/core": "7.0.0-next.1", + "@verdaccio/local-storage": "10.3.3", + "@verdaccio/logger-7": "7.0.0-next.1", + "@verdaccio/middleware": "7.0.0-next.1", + "@verdaccio/search": "7.0.0-next.1", + "@verdaccio/signature": "7.0.0-next.0", + "@verdaccio/streams": "10.2.1", + "@verdaccio/tarball": "12.0.0-next.1", + "@verdaccio/ui-theme": "7.0.0-next.1", + "@verdaccio/url": "12.0.0-next.1", + "@verdaccio/utils": "7.0.0-next.1", + "async": "3.2.4", + "clipanion": "3.2.1", + "compression": "1.7.4", + "cookies": "0.8.0", + "cors": "2.8.5", + "debug": "^4.3.4", + "envinfo": "7.10.0", + "express": "4.18.2", + "express-rate-limit": "5.5.1", + "fast-safe-stringify": "2.1.1", + "handlebars": "4.7.7", + "js-yaml": "4.1.0", + "JSONStream": "1.3.5", + "jsonwebtoken": "9.0.1", + "kleur": "4.1.5", + "lodash": "4.17.21", + "lru-cache": "7.18.3", + "mime": "3.0.0", + "mkdirp": "1.0.4", + "mv": "2.1.1", + "pkginfo": "0.4.1", + "request": "2.88.2", + "semver": "7.5.4", + "validator": "13.11.0", + "verdaccio-audit": "12.0.0-next.1", + "verdaccio-htpasswd": "12.0.0-next.1" + }, + "bin": { + "verdaccio": "bin/verdaccio" + }, + "engines": { + "node": ">=12.18" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/verdaccio-audit": { + "version": "12.0.0-next.1", + "resolved": "https://registry.npmjs.org/verdaccio-audit/-/verdaccio-audit-12.0.0-next.1.tgz", + "integrity": "sha512-5TJflIvZNZ10Dx5oD/RETjK6xVV/Shm9JbtpFmIqOhwnwhfHBVw/vI+BM1zvGkXuXmgbXa9qrsG30DI/58sIfQ==", + "dev": true, + "dependencies": { + "@verdaccio/config": "7.0.0-next.1", + "@verdaccio/core": "7.0.0-next.1", + "express": "4.18.2", + "https-proxy-agent": "5.0.1", + "node-fetch": "cjs" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/verdaccio-htpasswd": { + "version": "12.0.0-next.1", + "resolved": "https://registry.npmjs.org/verdaccio-htpasswd/-/verdaccio-htpasswd-12.0.0-next.1.tgz", + "integrity": "sha512-NNjltevHBJnZo6pKyZqe2THXM3RAFRbrCcTimlVSNL23MbSlcBXvbM4w8MCLzyC5kVixE+i4+ha5diPQLGVN2A==", + "dev": true, + "dependencies": { + "@verdaccio/core": "7.0.0-next.1", + "@verdaccio/file-locking": "12.0.0-next.0", + "apache-md5": "1.1.8", + "bcryptjs": "2.4.3", + "core-js": "3.30.2", + "debug": "4.3.4", + "http-errors": "2.0.0", + "unix-crypt-td-js": "1.1.4" + }, + "engines": { + "node": ">=14", + "npm": ">=6" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/verdaccio-htpasswd/node_modules/@verdaccio/file-locking": { + "version": "12.0.0-next.0", + "resolved": "https://registry.npmjs.org/@verdaccio/file-locking/-/file-locking-12.0.0-next.0.tgz", + "integrity": "sha512-SsjciD/2UpMsUJsEAB4se6gWLnx7JCopdSVGXLvvlKDzHi+y/zQOz0gq2QVirzJ4C+gSRdYd8ts19MOuL1yHgA==", + "dev": true, + "dependencies": { + "lockfile": "1.0.4" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "type": "opencollective", + "url": "https://opencollective.com/verdaccio" + } + }, + "node_modules/verdaccio/node_modules/kleur": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz", + "integrity": "sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/verdaccio/node_modules/mime": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz", + "integrity": "sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A==", + "dev": true, + "bin": { + "mime": "cli.js" + }, + "engines": { + "node": ">=10.0.0" + } + }, "node_modules/verror": { "version": "1.10.0", "resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz", @@ -24572,6 +26840,24 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/yup": { + "version": "0.32.11", + "resolved": "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz", + "integrity": "sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg==", + "dev": true, + "dependencies": { + "@babel/runtime": "^7.15.4", + "@types/lodash": "^4.14.175", + "lodash": "^4.17.21", + "lodash-es": "^4.17.21", + "nanoclone": "^0.2.1", + "property-expr": "^2.0.4", + "toposort": "^2.0.2" + }, + "engines": { + "node": ">=10" + } + }, "node_modules/zone.js": { "version": "0.13.0", "resolved": "https://registry.npmjs.org/zone.js/-/zone.js-0.13.0.tgz", diff --git a/package.json b/package.json index 544a4d81..c8812c7a 100644 --- a/package.json +++ b/package.json @@ -13,7 +13,8 @@ "build:mini-rx-store": "nx build mini-rx-store", "build:mini-rx-store-ng": "nx build mini-rx-store-ng", "build:signal-store": "nx build signal-store", - "build:all": "nx build mini-rx-store && nx build mini-rx-store-ng && nx build mini-rx-angular-demo && nx build signal-store", + "build:common": "nx build common", + "build:all": "nx build mini-rx-store && nx build mini-rx-store-ng && nx build mini-rx-angular-demo && nx build signal-store && nx build common", "test:mini-rx-store": "nx test mini-rx-store", "test:mini-rx-store:watch": "nx test mini-rx-store --watch", "test:mini-rx-store:coverage": "nx test mini-rx-store --codeCoverage", @@ -22,7 +23,10 @@ "test:mini-rx-store-ng:coverage": "nx test mini-rx-store-ng --codeCoverage", "test:signal-store": "nx test signal-store", "test:signal-store:watch": "nx test signal-store --watch", - "test:all": "nx test mini-rx-store && nx test mini-rx-store-ng && nx test signal-store", + "test:common": "nx test common", + "test:common:watch": "nx test common --watch", + "test:common:coverage": "nx test common --codeCoverage", + "test:all": "nx test mini-rx-store && nx test mini-rx-store-ng && nx test signal-store && nx test common", "deploy:docs": "npm run deploy --prefix docs", "build:mini-rx-angular-demo:sourcemap": "nx build mini-rx-angular-demo --source-map", "build:mini-rx-angular-demo:sourcemap:stats": "npm run build:mini-rx-angular-demo:sourcemap && source-map-explorer dist/apps/mini-rx-angular-demo/**/*.js", diff --git a/tools/scripts/publish.mjs b/tools/scripts/publish.mjs new file mode 100644 index 00000000..433c7815 --- /dev/null +++ b/tools/scripts/publish.mjs @@ -0,0 +1,60 @@ +/** + * This is a minimal script to publish your package to "npm". + * This is meant to be used as-is or customize as you see fit. + * + * This script is executed on "dist/path/to/library" as "cwd" by default. + * + * You might need to authenticate with NPM before running this script. + */ + +import { execSync } from 'child_process'; +import { readFileSync, writeFileSync } from 'fs'; + +import devkit from '@nx/devkit'; +const { readCachedProjectGraph } = devkit; + +function invariant(condition, message) { + if (!condition) { + console.error(message); + process.exit(1); + } +} + +// Executing publish script: node path/to/publish.mjs {name} --version {version} --tag {tag} +// Default "tag" to "next" so we won't publish the "latest" tag by accident. +const [, , name, version, tag = 'next'] = process.argv; + +// A simple SemVer validation to validate the version +const validVersion = /^\d+\.\d+\.\d+(-\w+\.\d+)?/; +invariant( + version && validVersion.test(version), + `No version provided or version did not match Semantic Versioning, expected: #.#.#-tag.# or #.#.#, got ${version}.` +); + +const graph = readCachedProjectGraph(); +const project = graph.nodes[name]; + +invariant( + project, + `Could not find project "${name}" in the workspace. Is the project.json configured correctly?` +); + +const outputPath = project.data?.targets?.build?.options?.outputPath; +invariant( + outputPath, + `Could not find "build.options.outputPath" of project "${name}". Is project.json configured correctly?` +); + +process.chdir(outputPath); + +// Updating the version in "package.json" before publishing +try { + const json = JSON.parse(readFileSync(`package.json`).toString()); + json.version = version; + writeFileSync(`package.json`, JSON.stringify(json, null, 2)); +} catch (e) { + console.error(`Error reading package.json file from library build output.`); +} + +// Execute "npm publish" to publish +execSync(`npm publish --access public --tag ${tag}`); diff --git a/tsconfig.base.json b/tsconfig.base.json index 689fce81..258eabff 100644 --- a/tsconfig.base.json +++ b/tsconfig.base.json @@ -8,13 +8,14 @@ "emitDecoratorMetadata": true, "experimentalDecorators": true, "importHelpers": true, - "target": "es2015", + "target": "ES2022", "module": "esnext", - "lib": ["es2017", "dom"], + "lib": ["es2022", "dom"], "skipLibCheck": true, "skipDefaultLibCheck": true, "baseUrl": ".", "paths": { + "@mini-rx/common": ["libs/common/src/index.ts"], "@mini-rx/signal-store": ["libs/signal-store/src/index.ts"], "mini-rx-store": ["libs/mini-rx-store/src/index.ts"], "mini-rx-store-ng": ["libs/mini-rx-store-ng/src/index.ts"] diff --git a/yarn.lock b/yarn.lock index 504d87cf..7d044202 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1347,7 +1347,7 @@ resolved "https://registry.npmjs.org/@babel/regjsgen/-/regjsgen-0.8.0.tgz" integrity sha512-x/rqGMdzj+fWZvCOYForTghzbtqPDZ5gPwaoNGHdgDfF2QA/XZbCBp4Moo5scrkAMPhB7z26XM/AaHuIJdgauA== -"@babel/runtime@^7.14.8", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": +"@babel/runtime@^7.14.8", "@babel/runtime@^7.15.4", "@babel/runtime@^7.7.2", "@babel/runtime@^7.8.4": version "7.21.5" resolved "https://registry.npmjs.org/@babel/runtime/-/runtime-7.21.5.tgz" integrity sha512-8jI69toZqqcsnqGGqwGS4Qb1VwLOEp4hz+CXPywcvjs60u3B4Pom/U/7rm4W8tMOYEB+E9wgD0mW1l3r8qlI9Q== @@ -1808,6 +1808,13 @@ slash "^3.0.0" strip-ansi "^6.0.0" +"@jest/create-cache-key-function@^27.4.2": + version "27.5.1" + resolved "https://registry.npmjs.org/@jest/create-cache-key-function/-/create-cache-key-function-27.5.1.tgz" + integrity sha512-dmH1yW+makpTSURTy8VzdUwFnfQh1G8R+DxO2Ho2FFmBbKFEVm+3jWdvFhE2VqB/LATCTokkP0dotjyQyw5/AQ== + dependencies: + "@jest/types" "^27.5.1" + "@jest/environment@^29.4.3", "@jest/environment@^29.5.0": version "29.5.0" resolved "https://registry.npmjs.org/@jest/environment/-/environment-29.5.0.tgz" @@ -1942,6 +1949,17 @@ slash "^3.0.0" write-file-atomic "^4.0.2" +"@jest/types@^27.5.1": + version "27.5.1" + resolved "https://registry.npmjs.org/@jest/types/-/types-27.5.1.tgz" + integrity sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw== + dependencies: + "@types/istanbul-lib-coverage" "^2.0.0" + "@types/istanbul-reports" "^3.0.0" + "@types/node" "*" + "@types/yargs" "^16.0.0" + chalk "^4.0.0" + "@jest/types@^29.4.3", "@jest/types@^29.5.0": version "29.5.0" resolved "https://registry.npmjs.org/@jest/types/-/types-29.5.0.tgz" @@ -2029,6 +2047,20 @@ resolved "https://registry.npmjs.org/@leichtgewicht/ip-codec/-/ip-codec-2.0.4.tgz" integrity sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A== +"@mole-inc/bin-wrapper@^8.0.1": + version "8.0.1" + resolved "https://registry.npmjs.org/@mole-inc/bin-wrapper/-/bin-wrapper-8.0.1.tgz" + integrity sha512-sTGoeZnjI8N4KS+sW2AN95gDBErhAguvkw/tWdCjeM8bvxpz5lqrnd0vOJABA1A+Ic3zED7PYoLP/RANLgVotA== + dependencies: + bin-check "^4.1.0" + bin-version-check "^5.0.0" + content-disposition "^0.5.4" + ext-name "^5.0.0" + file-type "^17.1.6" + filenamify "^5.0.2" + got "^11.8.5" + os-filter-obj "^2.0.0" + "@ngtools/webpack@16.1.1": version "16.1.1" resolved "https://registry.npmjs.org/@ngtools/webpack/-/webpack-16.1.1.tgz" @@ -2592,6 +2624,11 @@ resolved "https://registry.npmjs.org/@sinclair/typebox/-/typebox-0.25.24.tgz" integrity sha512-XJfwUVUKDHF5ugKwIcxEgc9k8b7HbznCp6eUfWgu710hMPNIO4aw4/zB5RogDQz8nd6gyCDpU9O/m6qYEWY6yQ== +"@sindresorhus/is@^4.0.0": + version "4.6.0" + resolved "https://registry.npmjs.org/@sindresorhus/is/-/is-4.6.0.tgz" + integrity sha512-t09vSN3MdfsyCHoFcTRCH/iUtG7OJ0CsjzB8cjAmKc/va/kIgeDI/TxsigdncE/4be734m0cvIYwNaV4i2XqAw== + "@sinonjs/commons@^2.0.0": version "2.0.0" resolved "https://registry.npmjs.org/@sinonjs/commons/-/commons-2.0.0.tgz" @@ -2606,6 +2643,78 @@ dependencies: "@sinonjs/commons" "^2.0.0" +"@swc/cli@~0.1.62": + version "0.1.62" + resolved "https://registry.npmjs.org/@swc/cli/-/cli-0.1.62.tgz" + integrity sha512-kOFLjKY3XH1DWLfXL1/B5MizeNorHR8wHKEi92S/Zi9Md/AK17KSqR8MgyRJ6C1fhKHvbBCl8wboyKAFXStkYw== + dependencies: + "@mole-inc/bin-wrapper" "^8.0.1" + commander "^7.1.0" + fast-glob "^3.2.5" + semver "^7.3.8" + slash "3.0.0" + source-map "^0.7.3" + +"@swc/core-darwin-arm64@1.3.88": + version "1.3.88" + resolved "https://registry.npmjs.org/@swc/core-darwin-arm64/-/core-darwin-arm64-1.3.88.tgz" + integrity sha512-Nb7kKydSQK3FE90pw/GPRFmAkquDQcTixLijNcki2xFBXh/DcGdFUPE/GShQjk8gtQelj2vqZrsGs/GZPGA1mA== + +"@swc/core@~1.3.51": + version "1.3.88" + resolved "https://registry.npmjs.org/@swc/core/-/core-1.3.88.tgz" + integrity sha512-kaJ5t6Fg/DmJPNeI+jdtCEt7NVKxhUYToq7PF2fMRPFPLKSJzJCZajcp6/gZNcEUCVWaK6pWi/XL79Tzz1FqzQ== + dependencies: + "@swc/counter" "^0.1.1" + "@swc/types" "^0.1.5" + optionalDependencies: + "@swc/core-darwin-arm64" "1.3.88" + "@swc/core-darwin-x64" "1.3.88" + "@swc/core-linux-arm-gnueabihf" "1.3.88" + "@swc/core-linux-arm64-gnu" "1.3.88" + "@swc/core-linux-arm64-musl" "1.3.88" + "@swc/core-linux-x64-gnu" "1.3.88" + "@swc/core-linux-x64-musl" "1.3.88" + "@swc/core-win32-arm64-msvc" "1.3.88" + "@swc/core-win32-ia32-msvc" "1.3.88" + "@swc/core-win32-x64-msvc" "1.3.88" + +"@swc/counter@^0.1.1": + version "0.1.1" + resolved "https://registry.npmjs.org/@swc/counter/-/counter-0.1.1.tgz" + integrity sha512-xVRaR4u9hcYjFvcSg71Lz5Bo4//CyjAAfMxa7UsaDSYxAshflUkVJWiyVWrfxC59z2kP1IzI4/1BEpnhI9o3Mw== + +"@swc/helpers@~0.5.0": + version "0.5.1" + resolved "https://registry.npmjs.org/@swc/helpers/-/helpers-0.5.1.tgz" + integrity sha512-sJ902EfIzn1Fa+qYmjdQqh8tPsoxyBz+8yBKC2HKUxyezKJFwPGOn7pv4WY6QuQW//ySQi5lJjA/ZT9sNWWNTg== + dependencies: + tslib "^2.4.0" + +"@swc/jest@0.2.20": + version "0.2.20" + resolved "https://registry.npmjs.org/@swc/jest/-/jest-0.2.20.tgz" + integrity sha512-5qSUBYY1wyIMn7p0Vl9qqV4hMI69oJwZCIPUpBsTFWN2wlwn6RDugzdgCn+bLXVYh+Cxi8bJcZ1uumDgsoL+FA== + dependencies: + "@jest/create-cache-key-function" "^27.4.2" + +"@swc/types@^0.1.5": + version "0.1.5" + resolved "https://registry.npmjs.org/@swc/types/-/types-0.1.5.tgz" + integrity sha512-myfUej5naTBWnqOCc/MdVOLVjXUXtIA+NpDrDBKJtLLg2shUjBu3cZmB/85RyitKc55+lUUyl7oRfLOvkr2hsw== + +"@szmarczak/http-timer@^4.0.5": + version "4.0.6" + resolved "https://registry.npmjs.org/@szmarczak/http-timer/-/http-timer-4.0.6.tgz" + integrity sha512-4BAffykYOgO+5nzBWYwE3W90sBgLJoUPRWWcL8wlyiM8IB8ipJz3UMJ9KXQd1RKQXpKp8Tutn80HZtWsu2u76w== + dependencies: + defer-to-connect "^2.0.0" + +"@tokenizer/token@^0.3.0": + version "0.3.0" + resolved "https://registry.npmjs.org/@tokenizer/token/-/token-0.3.0.tgz" + integrity sha512-OvjF+z51L3ov0OyAU0duzsYuvO01PH7x4t6DJx+guahgTnBHkhJdG7soQeTSFLWN3efnHyibZ4Z8l2EuWwJN3A== + "@tootallnate/once@2": version "2.0.0" resolved "https://registry.npmjs.org/@tootallnate/once/-/once-2.0.0.tgz" @@ -2697,6 +2806,16 @@ dependencies: "@types/node" "*" +"@types/cacheable-request@^6.0.1": + version "6.0.3" + resolved "https://registry.npmjs.org/@types/cacheable-request/-/cacheable-request-6.0.3.tgz" + integrity sha512-IQ3EbTzGxIigb1I3qPZc1rWJnH0BmSKv5QYTalEwweFvyBDLSAe24zP0le/hyi7ecGfZVlIVAg4BZqb8WBwKqw== + dependencies: + "@types/http-cache-semantics" "*" + "@types/keyv" "^3.1.4" + "@types/node" "*" + "@types/responselike" "^1.0.0" + "@types/connect-history-api-fallback@^1.3.5": version "1.5.0" resolved "https://registry.npmjs.org/@types/connect-history-api-fallback/-/connect-history-api-fallback-1.5.0.tgz" @@ -2780,6 +2899,11 @@ dependencies: "@types/node" "*" +"@types/http-cache-semantics@*": + version "4.0.2" + resolved "https://registry.npmjs.org/@types/http-cache-semantics/-/http-cache-semantics-4.0.2.tgz" + integrity sha512-FD+nQWA2zJjh4L9+pFXqWOi0Hs1ryBCfI+985NjluQ1p8EYtoLvjLOKidXBtZ4/IcxDX4o8/E8qDS3540tNliw== + "@types/http-proxy@^1.17.8": version "1.17.11" resolved "https://registry.npmjs.org/@types/http-proxy/-/http-proxy-1.17.11.tgz" @@ -2828,6 +2952,13 @@ resolved "https://registry.npmjs.org/@types/json-schema/-/json-schema-7.0.11.tgz" integrity sha512-wOuvG1SN4Us4rez+tylwwwCV1psiNVOkJeM3AUWUNWg/jDQY2+HE/444y5gc+jBmRqASOm2Oeh5c1axHobwRKQ== +"@types/keyv@^3.1.4": + version "3.1.4" + resolved "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.4.tgz" + integrity sha512-BQ5aZNSCpj7D6K2ksrRCTmKRLEpnPvWDiLPfoGyhZ++8YtiK9d/3DBKPJgry359X/P1PfruyYwvnvwFjuEiEIg== + dependencies: + "@types/node" "*" + "@types/lodash-es@^4.17.6": version "4.17.7" resolved "https://registry.npmjs.org/@types/lodash-es/-/lodash-es-4.17.7.tgz" @@ -2835,7 +2966,7 @@ dependencies: "@types/lodash" "*" -"@types/lodash@*": +"@types/lodash@*", "@types/lodash@^4.14.175": version "4.14.194" resolved "https://registry.npmjs.org/@types/lodash/-/lodash-4.14.194.tgz" integrity sha512-r22s9tAS7imvBt2lyHC9B8AGwWnXaYb1tY09oyLkXDs4vArpYJzw09nj8MLx5VfciBPGIb+ZwG0ssYnEPJxn/g== @@ -2860,10 +2991,10 @@ resolved "https://registry.npmjs.org/@types/minimist/-/minimist-1.2.2.tgz" integrity sha512-jhuKLIRrhvCPLqwPcx6INqmKeiA5EWrsCOPhrlFSrbrmU4ZMPjj5Ul/oLCMDO98XRUIwVm78xICz4EPCektzeQ== -"@types/node@*": - version "20.1.0" - resolved "https://registry.npmjs.org/@types/node/-/node-20.1.0.tgz" - integrity sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A== +"@types/node@*", "@types/node@18.7.1": + version "18.7.1" + resolved "https://registry.npmjs.org/@types/node/-/node-18.7.1.tgz" + integrity sha512-GKX1Qnqxo4S+Z/+Z8KKPLpH282LD7jLHWJcVryOflnsnH+BtSDfieR6ObwBMwpnNws0bUK8GI7z0unQf9bARNQ== "@types/node@^14.14.31": version "14.18.45" @@ -2875,11 +3006,6 @@ resolved "https://registry.npmjs.org/@types/node/-/node-20.1.0.tgz" integrity sha512-O+z53uwx64xY7D6roOi4+jApDGFg0qn6WHcxe5QeqjMaTezBO/mxdfFXIVAVVyNWKx84OmPB3L8kbVYOTeN34A== -"@types/node@18.7.1": - version "18.7.1" - resolved "https://registry.npmjs.org/@types/node/-/node-18.7.1.tgz" - integrity sha512-GKX1Qnqxo4S+Z/+Z8KKPLpH282LD7jLHWJcVryOflnsnH+BtSDfieR6ObwBMwpnNws0bUK8GI7z0unQf9bARNQ== - "@types/normalize-package-data@^2.4.0": version "2.4.1" resolved "https://registry.npmjs.org/@types/normalize-package-data/-/normalize-package-data-2.4.1.tgz" @@ -2917,6 +3043,13 @@ resolved "https://registry.npmjs.org/@types/resolve/-/resolve-1.20.2.tgz" integrity sha512-60BCwRFOZCQhDncwQdxxeOEEkbc5dIMccYLwbxsS4TUNeVECQ/pBJ0j09mrHOl/JJvpRPGwO9SvE4nR2Nb/a4Q== +"@types/responselike@^1.0.0": + version "1.0.0" + resolved "https://registry.npmjs.org/@types/responselike/-/responselike-1.0.0.tgz" + integrity sha512-85Y2BjiufFzaMIlvJDvTTB8Fxl2xfLo4HgmHzVBz08w4wDePCTjYw66PdrolO0kzli3yam/YCgRufyo1DdQVTA== + dependencies: + "@types/node" "*" + "@types/retry@0.12.0": version "0.12.0" resolved "https://registry.npmjs.org/@types/retry/-/retry-0.12.0.tgz" @@ -2994,6 +3127,13 @@ resolved "https://registry.npmjs.org/@types/yargs-parser/-/yargs-parser-21.0.0.tgz" integrity sha512-iO9ZQHkZxHn4mSakYV0vFHAVDyEOIJQrV2uZ06HxEPcx+mt8swXoZHIbaaJ2crJYFfErySgktuTZ3BeLz+XmFA== +"@types/yargs@^16.0.0": + version "16.0.5" + resolved "https://registry.npmjs.org/@types/yargs/-/yargs-16.0.5.tgz" + integrity sha512-AxO/ADJOBFJScHbWhq2xAhlWP24rY4aCEG/NFaMvbT3X2MgRsLjhjQwsn0Zi5zn0LG9jUhCCZMeX9Dkuw6k+vQ== + dependencies: + "@types/yargs-parser" "*" + "@types/yargs@^17.0.8": version "17.0.24" resolved "https://registry.npmjs.org/@types/yargs/-/yargs-17.0.24.tgz" @@ -3092,6 +3232,167 @@ "@typescript-eslint/types" "5.59.2" eslint-visitor-keys "^3.3.0" +"@verdaccio/commons-api@10.2.0": + version "10.2.0" + resolved "https://registry.npmjs.org/@verdaccio/commons-api/-/commons-api-10.2.0.tgz" + integrity sha512-F/YZANu4DmpcEV0jronzI7v2fGVWkQ5Mwi+bVmV+ACJ+EzR0c9Jbhtbe5QyLUuzR97t8R5E/Xe53O0cc2LukdQ== + dependencies: + http-errors "2.0.0" + http-status-codes "2.2.0" + +"@verdaccio/config@7.0.0-next.1": + version "7.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/config/-/config-7.0.0-next.1.tgz" + integrity sha512-taFxO0KDajD71unzuQfiRDohW6PM/HeXodM4BcOzdx/k6zpYYzotll2f++0/zkfC2Lhy7KOd//CR8kk0VI628A== + dependencies: + "@verdaccio/core" "7.0.0-next.1" + "@verdaccio/utils" "7.0.0-next.1" + debug "4.3.4" + js-yaml "4.1.0" + lodash "4.17.21" + minimatch "3.1.2" + yup "0.32.11" + +"@verdaccio/core@7.0.0-next.1": + version "7.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/core/-/core-7.0.0-next.1.tgz" + integrity sha512-0cHibUcA7EFjMzBq06WEQ4CQxnds+OZX5jVY6MEpQMtWbSiH40pIi9lDiQFKs6lbXXqidNjvY4J19T1zevQLlw== + dependencies: + ajv "8.12.0" + core-js "3.30.2" + http-errors "2.0.0" + http-status-codes "2.2.0" + process-warning "1.0.0" + semver "7.5.4" + +"@verdaccio/file-locking@10.3.1": + version "10.3.1" + resolved "https://registry.npmjs.org/@verdaccio/file-locking/-/file-locking-10.3.1.tgz" + integrity sha512-oqYLfv3Yg3mAgw9qhASBpjD50osj2AX4IwbkUtyuhhKGyoFU9eZdrbeW6tpnqUnj6yBMtAPm2eGD4BwQuX400g== + dependencies: + lockfile "1.0.4" + +"@verdaccio/file-locking@12.0.0-next.0": + version "12.0.0-next.0" + resolved "https://registry.npmjs.org/@verdaccio/file-locking/-/file-locking-12.0.0-next.0.tgz" + integrity sha512-SsjciD/2UpMsUJsEAB4se6gWLnx7JCopdSVGXLvvlKDzHi+y/zQOz0gq2QVirzJ4C+gSRdYd8ts19MOuL1yHgA== + dependencies: + lockfile "1.0.4" + +"@verdaccio/local-storage@10.3.3": + version "10.3.3" + resolved "https://registry.npmjs.org/@verdaccio/local-storage/-/local-storage-10.3.3.tgz" + integrity sha512-/n0FH+1hxVg80YhYBfJuW7F2AuvLY2fra8/DTCilWDll9Y5yZDxwntZfcKHJLerCA4atrbJtvaqpWkoV3Q9x8w== + dependencies: + "@verdaccio/commons-api" "10.2.0" + "@verdaccio/file-locking" "10.3.1" + "@verdaccio/streams" "10.2.1" + async "3.2.4" + debug "4.3.4" + lodash "4.17.21" + lowdb "1.0.0" + mkdirp "1.0.4" + +"@verdaccio/logger-7@7.0.0-next.1": + version "7.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/logger-7/-/logger-7-7.0.0-next.1.tgz" + integrity sha512-gGAK8af/mgbVlJOqiFQtjQOOkG6PVhgMa44i3ghq+WAc76Szs/n6lzOoQaFNYGg+dWCYRooGWJLTdOlkkL/A+A== + dependencies: + "@verdaccio/logger-commons" "7.0.0-next.1" + pino "7.11.0" + +"@verdaccio/logger-commons@7.0.0-next.1": + version "7.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/logger-commons/-/logger-commons-7.0.0-next.1.tgz" + integrity sha512-Prjl9A/1jWDM78H6MuW5ZLx2S+JfZY3Bn0G51qiUG0xZUQqgTvcDJni3m9myCVoGw+0dTS+NhkED/jyjodjKcw== + dependencies: + "@verdaccio/core" "7.0.0-next.1" + "@verdaccio/logger-prettify" "7.0.0-next.0" + colorette "2.0.20" + debug "4.3.4" + +"@verdaccio/logger-prettify@7.0.0-next.0": + version "7.0.0-next.0" + resolved "https://registry.npmjs.org/@verdaccio/logger-prettify/-/logger-prettify-7.0.0-next.0.tgz" + integrity sha512-6akvpkzt6ipkk7v3Non0M9KZq7xYF51QMhJPTFA7JU+hW5AqrAnoMsNAWOzoUMvRr/2Ri33U3VWAOwhmf109Pw== + dependencies: + colorette "2.0.20" + dayjs "1.11.7" + lodash "4.17.21" + pino-abstract-transport "1.0.0" + sonic-boom "3.3.0" + +"@verdaccio/middleware@7.0.0-next.1": + version "7.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/middleware/-/middleware-7.0.0-next.1.tgz" + integrity sha512-ccuMQGfvZjX6gI0+tSDVueB6qMZjzBUZxAI9tDgHaawlqcXrI4RK5QPDsWI9XeeClJJriGmdhVdommZnGYZmuw== + dependencies: + "@verdaccio/config" "7.0.0-next.1" + "@verdaccio/core" "7.0.0-next.1" + "@verdaccio/url" "12.0.0-next.1" + "@verdaccio/utils" "7.0.0-next.1" + debug "4.3.4" + express "4.18.2" + express-rate-limit "5.5.1" + lodash "4.17.21" + lru-cache "7.18.3" + mime "2.6.0" + +"@verdaccio/search@7.0.0-next.1": + version "7.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/search/-/search-7.0.0-next.1.tgz" + integrity sha512-LoWi4YVTFTbjEtyAPOfLKZy+neR5ldBzcVWgQJvg9e8fXS+UhQglvu6YWDr2j1yrQqbzzDVfV7YlXf4a3GG6mw== + +"@verdaccio/signature@7.0.0-next.0": + version "7.0.0-next.0" + resolved "https://registry.npmjs.org/@verdaccio/signature/-/signature-7.0.0-next.0.tgz" + integrity sha512-9e28xxd/eH1qRd+I+U0QO0af7F+MEFMtcrRapcqYIayk8yGq03cEGoj18LIf+LXyAosu18Y5dTporPz/R6geHg== + dependencies: + debug "4.3.4" + jsonwebtoken "9.0.0" + lodash "4.17.21" + +"@verdaccio/streams@10.2.1": + version "10.2.1" + resolved "https://registry.npmjs.org/@verdaccio/streams/-/streams-10.2.1.tgz" + integrity sha512-OojIG/f7UYKxC4dYX8x5ax8QhRx1b8OYUAMz82rUottCuzrssX/4nn5QE7Ank0DUSX3C9l/HPthc4d9uKRJqJQ== + +"@verdaccio/tarball@12.0.0-next.1": + version "12.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/tarball/-/tarball-12.0.0-next.1.tgz" + integrity sha512-uEgeVUa434H2dg+a35Hm+fxxBRU97RblkIYmvvdb+FHMRmsQmlGTJkPqCQd5YM+hkVCWITr4YyAleaysl7cErQ== + dependencies: + "@verdaccio/core" "7.0.0-next.1" + "@verdaccio/url" "12.0.0-next.1" + "@verdaccio/utils" "7.0.0-next.1" + debug "4.3.4" + lodash "4.17.21" + +"@verdaccio/ui-theme@7.0.0-next.1": + version "7.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/ui-theme/-/ui-theme-7.0.0-next.1.tgz" + integrity sha512-0Bp2M5oejxjXNzzMBB4qsXIES74hFecHw+QhGswcpViNYi1nM2Yl4nENHE+h2BFOE0Lk4m8NKOijyRM8yKDneg== + +"@verdaccio/url@12.0.0-next.1": + version "12.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/url/-/url-12.0.0-next.1.tgz" + integrity sha512-8XL0ZGSMLnquKv/xizjbClf3xGXWWnEyjhP5GZEgtjMdkvMhzzV5B9FdNOpTdxP7rcDnRqf78hO8urCz3+4E7g== + dependencies: + "@verdaccio/core" "7.0.0-next.1" + debug "4.3.4" + lodash "4.17.21" + validator "13.9.0" + +"@verdaccio/utils@7.0.0-next.1": + version "7.0.0-next.1" + resolved "https://registry.npmjs.org/@verdaccio/utils/-/utils-7.0.0-next.1.tgz" + integrity sha512-cgDYNNjD0lWFMf06SRhizFb9qULVcE5Wq7Qm9HRbxqsLdSBWShvf4p9jvlk3PSzoSi/tRHym1VMq/DhoZfFATw== + dependencies: + "@verdaccio/core" "7.0.0-next.1" + lodash "4.17.21" + minimatch "3.1.2" + semver "7.5.4" + "@vitejs/plugin-basic-ssl@1.0.1": version "1.0.1" resolved "https://registry.npmjs.org/@vitejs/plugin-basic-ssl/-/plugin-basic-ssl-1.0.1.tgz" @@ -3258,6 +3559,13 @@ abbrev@^1.0.0: resolved "https://registry.npmjs.org/abbrev/-/abbrev-1.1.1.tgz" integrity sha512-nne9/IiQ/hzIhY6pdDnbBtz7DjPTKrY00P/zvPSm5pOFkl6xuGrGnXn/VtTNNfNtAfZ9/1RtehkszU9qcTii0Q== +abort-controller@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/abort-controller/-/abort-controller-3.0.0.tgz" + integrity sha512-h8lQ8tacZYnR3vNQTgibj+tODHI5/+l06Au2Pcriv/Gmet0eaj4TwWH41sO9wnHDiQsEj19q0drzdWdeAHtweg== + dependencies: + event-target-shim "^5.0.0" + accepts@~1.3.4, accepts@~1.3.5, accepts@~1.3.8: version "1.3.8" resolved "https://registry.npmjs.org/accepts/-/accepts-1.3.8.tgz" @@ -3375,6 +3683,16 @@ ajv@^6.10.0: json-schema-traverse "^0.4.1" uri-js "^4.2.2" +ajv@^6.12.3: + version "6.12.6" + resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" + integrity sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g== + dependencies: + fast-deep-equal "^3.1.1" + fast-json-stable-stringify "^2.0.0" + json-schema-traverse "^0.4.1" + uri-js "^4.2.2" + ajv@^6.12.4: version "6.12.6" resolved "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz" @@ -3486,12 +3804,17 @@ anymatch@^3.0.3, anymatch@~3.1.2: normalize-path "^3.0.0" picomatch "^2.0.4" +apache-md5@1.1.8: + version "1.1.8" + resolved "https://registry.npmjs.org/apache-md5/-/apache-md5-1.1.8.tgz" + integrity sha512-FCAJojipPn0bXjuEpjOOOMN8FZDkxfWWp4JGN9mifU2IhxvKyXZYqpzPHdnTSUpmPDy+tsslB6Z1g+Vg6nVbYA== + "aproba@^1.0.3 || ^2.0.0": version "2.0.0" resolved "https://registry.npmjs.org/aproba/-/aproba-2.0.0.tgz" integrity sha512-lYe4Gx7QT+MKGbDsA+Z+he/Wtef0BiwDOlK/XkBrdfsh9J/jPPXbX0tE9x9cl27Tmu5gg3QUbUrQYa/y+KOHPQ== -arch@^2.2.0: +arch@^2.1.0, arch@^2.2.0: version "2.2.0" resolved "https://registry.npmjs.org/arch/-/arch-2.2.0.tgz" integrity sha512-Of/R0wqp83cgHozfIYLbBMnej79U/SVGOOyuB3VVFv1NRM/PSFMK12x9KVtiYzJqmnU5WR2qp0Z5rHb7sWGnFQ== @@ -3590,7 +3913,7 @@ async@^2.6.4: dependencies: lodash "^4.17.14" -async@^3.2.0, async@^3.2.3: +async@^3.2.0, async@^3.2.3, async@3.2.4: version "3.2.4" resolved "https://registry.npmjs.org/async/-/async-3.2.4.tgz" integrity sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ== @@ -3605,6 +3928,11 @@ at-least-node@^1.0.0: resolved "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz" integrity sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg== +atomic-sleep@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/atomic-sleep/-/atomic-sleep-1.0.0.tgz" + integrity sha512-kNOjDqAh7px0XWNI+4QbzoiR/nTkHAWNud2uvnJquD1/x5a7EQZMJT0AczqK0Qn67oY/TTQ1LbUKajZpp3I9tQ== + autoprefixer@^10.4.12, autoprefixer@^10.4.6, autoprefixer@^10.4.9, autoprefixer@10.4.14: version "10.4.14" resolved "https://registry.npmjs.org/autoprefixer/-/autoprefixer-10.4.14.tgz" @@ -3816,11 +4144,41 @@ bcrypt-pbkdf@^1.0.0: dependencies: tweetnacl "^0.14.3" +bcryptjs@2.4.3: + version "2.4.3" + resolved "https://registry.npmjs.org/bcryptjs/-/bcryptjs-2.4.3.tgz" + integrity sha512-V/Hy/X9Vt7f3BbPJEi8BdVFMByHi+jNXrYkW3huaybV/kQ0KJg0Y6PkEMbn+zeT+i+SiKZ/HMqJGIIt4LZDqNQ== + big.js@^5.2.2: version "5.2.2" resolved "https://registry.npmjs.org/big.js/-/big.js-5.2.2.tgz" integrity sha512-vyL2OymJxmarO8gxMr0mhChsO9QGwhynfuu4+MHTAW6czfq9humCB7rKpUjDd9YUiDPU4mzpyupFSvOClAwbmQ== +bin-check@^4.1.0: + version "4.1.0" + resolved "https://registry.npmjs.org/bin-check/-/bin-check-4.1.0.tgz" + integrity sha512-b6weQyEUKsDGFlACWSIOfveEnImkJyK/FGW6FAG42loyoquvjdtOIqO6yBFzHyqyVVhNgNkQxxx09SFLK28YnA== + dependencies: + execa "^0.7.0" + executable "^4.1.0" + +bin-version-check@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/bin-version-check/-/bin-version-check-5.1.0.tgz" + integrity sha512-bYsvMqJ8yNGILLz1KP9zKLzQ6YpljV3ln1gqhuLkUtyfGi3qXKGuK2p+U4NAvjVFzDFiBBtOpCOSFNuYYEGZ5g== + dependencies: + bin-version "^6.0.0" + semver "^7.5.3" + semver-truncate "^3.0.0" + +bin-version@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/bin-version/-/bin-version-6.0.0.tgz" + integrity sha512-nk5wEsP4RiKjG+vF+uG8lFsEn4d7Y6FVDamzzftSunXOoOcOOkzcWdKVlGgFFwlUQCj63SgnUkLLGF8v7lufhw== + dependencies: + execa "^5.0.0" + find-versions "^5.0.0" + binary-extensions@^2.0.0: version "2.2.0" resolved "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz" @@ -3944,6 +4302,11 @@ buffer-crc32@~0.2.3: resolved "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz" integrity sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ== +buffer-equal-constant-time@1.0.1: + version "1.0.1" + resolved "https://registry.npmjs.org/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz" + integrity sha512-zRpUiDwd/xk6ADqPMATG8vc9VPrkck7T07OIx0gnjmJAnHnTVXNQG3vfvWNuiZIkwu9KrKdA1iJKfsfTVxE6NA== + buffer-from@^1.0.0: version "1.1.2" resolved "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz" @@ -3957,6 +4320,14 @@ buffer@^5.5.0, buffer@^5.6.0: base64-js "^1.3.1" ieee754 "^1.1.13" +buffer@^6.0.3: + version "6.0.3" + resolved "https://registry.npmjs.org/buffer/-/buffer-6.0.3.tgz" + integrity sha512-FTiCpNxtwiZZHEZbcbTIcZjERVICn9yq/pDFkTl95/AxzD1naBctN7YO68riM/gLSDY7sdrMby8hofADYuuqOA== + dependencies: + base64-js "^1.3.1" + ieee754 "^1.2.1" + builtin-modules@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz" @@ -4015,6 +4386,24 @@ cacache@17.1.3: tar "^6.1.11" unique-filename "^3.0.0" +cacheable-lookup@^5.0.3: + version "5.0.4" + resolved "https://registry.npmjs.org/cacheable-lookup/-/cacheable-lookup-5.0.4.tgz" + integrity sha512-2/kNscPhpcxrOigMZzbiWF7dz8ilhb/nIHU3EyZiXWXpeq/au8qJ8VhdftMkty3n7Gj6HIGalQG8oiBNB3AJgA== + +cacheable-request@^7.0.2: + version "7.0.4" + resolved "https://registry.npmjs.org/cacheable-request/-/cacheable-request-7.0.4.tgz" + integrity sha512-v+p6ongsrp0yTGbJXjgxPow2+DL93DASP4kXCDKb8/bwRtt9OEF3whggkkDkGNzgcWy2XaF4a8nZglC7uElscg== + dependencies: + clone-response "^1.0.2" + get-stream "^5.1.0" + http-cache-semantics "^4.0.0" + keyv "^4.0.0" + lowercase-keys "^2.0.0" + normalize-url "^6.0.1" + responselike "^2.0.0" + cachedir@^2.3.0: version "2.3.0" resolved "https://registry.npmjs.org/cachedir/-/cachedir-2.3.0.tgz" @@ -4191,6 +4580,13 @@ cli-width@^3.0.0: resolved "https://registry.npmjs.org/cli-width/-/cli-width-3.0.0.tgz" integrity sha512-FxqpkPPwu1HjuN93Omfm4h8uIanXofW0RxVEW3k5RKx+mJJYSthzNhp32Kzxxy3YAEZ/Dc/EWN1vZRY0+kOhbw== +clipanion@3.2.1: + version "3.2.1" + resolved "https://registry.npmjs.org/clipanion/-/clipanion-3.2.1.tgz" + integrity sha512-dYFdjLb7y1ajfxQopN05mylEpK9ZX0sO1/RfMXdfmwjlIsPkbh4p7A682x++zFPLDCo1x3p82dtljHf5cW2LKA== + dependencies: + typanion "^3.8.0" + cliui@^7.0.2: version "7.0.4" resolved "https://registry.npmjs.org/cliui/-/cliui-7.0.4.tgz" @@ -4218,6 +4614,13 @@ clone-deep@^4.0.1: kind-of "^6.0.2" shallow-clone "^3.0.0" +clone-response@^1.0.2: + version "1.0.3" + resolved "https://registry.npmjs.org/clone-response/-/clone-response-1.0.3.tgz" + integrity sha512-ROoL94jJH2dUVML2Y/5PEDNaSHgeOdSDicUyS7izcF63G6sTc/FTjLub4b8Il9S8S0beOfYt0TaA5qvFK+w0wA== + dependencies: + mimic-response "^1.0.0" + clone@^1.0.2: version "1.0.4" resolved "https://registry.npmjs.org/clone/-/clone-1.0.4.tgz" @@ -4272,7 +4675,7 @@ colorette@^1.1.0: resolved "https://registry.npmjs.org/colorette/-/colorette-1.4.0.tgz" integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== -colorette@^2.0.10, colorette@^2.0.16: +colorette@^2.0.10, colorette@^2.0.16, colorette@2.0.20: version "2.0.20" resolved "https://registry.npmjs.org/colorette/-/colorette-2.0.20.tgz" integrity sha512-IfEDxwoWIjkeXL1eXcDiow4UbKjhLdq6/EuSVR9GMN7KVH3r9gQ83e73hsz1Nd1T3ijd5xv1wcWRYO+D6kCI2w== @@ -4299,6 +4702,11 @@ commander@^6.2.1: resolved "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz" integrity sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA== +commander@^7.1.0: + version "7.2.0" + resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" + integrity sha512-QrWXB+ZQSVPmIWIhtEO9H+gwHaMGYiF5ChvoJ+K9ZGHG/sVsa6yiesAD1GC/x46sET00Xlwo1u49RVVVzvcSkw== + commander@^7.2.0: version "7.2.0" resolved "https://registry.npmjs.org/commander/-/commander-7.2.0.tgz" @@ -4334,7 +4742,7 @@ compressible@~2.0.16: dependencies: mime-db ">= 1.43.0 < 2" -compression@^1.7.4: +compression@^1.7.4, compression@1.7.4: version "1.7.4" resolved "https://registry.npmjs.org/compression/-/compression-1.7.4.tgz" integrity sha512-jaSIDzP9pZVS4ZfQ+TzvtiWhdpFhE2RDHz8QJkpX9SIpLq88VueF5jJw6t+6CUQcAoA6t+x89MLrWAqpfDE8iQ== @@ -4384,7 +4792,7 @@ console-control-strings@^1.1.0: resolved "https://registry.npmjs.org/console-control-strings/-/console-control-strings-1.1.0.tgz" integrity sha512-ty/fTekppD2fIwRvnZAVdeOiGd1c7YXEixbgJTNzqcxJWKQnjJ/V1bNEEE6hygpM3WjwHFUVK6HTjWSzV4a8sQ== -content-disposition@0.5.4: +content-disposition@^0.5.4, content-disposition@0.5.4: version "0.5.4" resolved "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz" integrity sha512-FveZTNuGw04cxlAiWbzi6zTAL/lhehaWbTtgluJh4/E95DqMwTmha3KZN1aAWA8cFIhHzMZUvLevkw5Rqk+tSQ== @@ -4574,6 +4982,14 @@ cookie@0.5.0: resolved "https://registry.npmjs.org/cookie/-/cookie-0.5.0.tgz" integrity sha512-YZ3GUyn/o8gfKJlnlX7g7xq4gyO6OSuhGPKaaGssGB2qgDUS0gPgtTvoyZLTt9Ab6dC4hfc9dV5arkvc/OCmrw== +cookies@0.8.0: + version "0.8.0" + resolved "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz" + integrity sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow== + dependencies: + depd "~2.0.0" + keygrip "~1.1.0" + copy-anything@^2.0.1: version "2.0.6" resolved "https://registry.npmjs.org/copy-anything/-/copy-anything-2.0.6.tgz" @@ -4612,6 +5028,11 @@ core-js-compat@^3.30.1, core-js-compat@^3.30.2: dependencies: browserslist "^4.21.5" +core-js@3.30.2: + version "3.30.2" + resolved "https://registry.npmjs.org/core-js/-/core-js-3.30.2.tgz" + integrity sha512-uBJiDmwqsbJCWHAwjrx3cvjbMXP7xD72Dmsn5LOJpiRmE3WbBbN5rCqQ2Qh6Ek6/eOrjlWngEynBWo4VxerQhg== + core-util-is@~1.0.0: version "1.0.3" resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz" @@ -4622,6 +5043,14 @@ core-util-is@1.0.2: resolved "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz" integrity sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ== +cors@2.8.5: + version "2.8.5" + resolved "https://registry.npmjs.org/cors/-/cors-2.8.5.tgz" + integrity sha512-KIHbLJqu73RGr/hnbrO9uBeixNGuvSQjul/jdFvS/KFSIH1hWVd1ng7zOHx+YrEfInLG7q4n6GHQ9cDtxv/P6g== + dependencies: + object-assign "^4" + vary "^1" + corser@^2.0.1: version "2.0.1" resolved "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz" @@ -4685,6 +5114,15 @@ critters@0.0.19: postcss "^8.4.23" pretty-bytes "^5.3.0" +cross-spawn@^5.0.1: + version "5.1.0" + resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-5.1.0.tgz" + integrity sha512-pTgQJ5KC0d2hcY8eyL1IzlBPYjTkyH72XRZPnLyKus2mBfNjQs3klqbJU2VILqZryAZUt9JOb3h/mWMy23/f5A== + dependencies: + lru-cache "^4.0.1" + shebang-command "^1.2.0" + which "^1.2.9" + cross-spawn@^7.0.0, cross-spawn@^7.0.2, cross-spawn@^7.0.3: version "7.0.3" resolved "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz" @@ -5026,7 +5464,7 @@ dateformat@^3.0.0: resolved "https://registry.npmjs.org/dateformat/-/dateformat-3.0.3.tgz" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -dayjs@^1.10.4: +dayjs@^1.10.4, dayjs@1.11.7: version "1.11.7" resolved "https://registry.npmjs.org/dayjs/-/dayjs-1.11.7.tgz" integrity sha512-+Yw9U6YO5TQohxLcIkrXBeY73WP3ejHWVvx8XCk3gxvQDCTEmS48ZrSZCKciI7Bhl/uCMyxYtE9UqRILmFphkQ== @@ -5052,7 +5490,7 @@ debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@4: +debug@^4.1.0, debug@^4.1.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4, debug@4, debug@4.3.4: version "4.3.4" resolved "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -5084,6 +5522,13 @@ decimal.js@^10.4.2: resolved "https://registry.npmjs.org/decimal.js/-/decimal.js-10.4.3.tgz" integrity sha512-VBBaLc1MgL5XpzgIP7ny5Z6Nx3UrRkIViUkPUdtl9aya5amy3De1gsUUSB1g3+3sExYNjCAsAznmukyxCb1GRA== +decompress-response@^6.0.0: + version "6.0.0" + resolved "https://registry.npmjs.org/decompress-response/-/decompress-response-6.0.0.tgz" + integrity sha512-aW35yZM6Bb/4oJlZncMH2LCoZtJXTRxES17vE3hoRiowU2kWHaJKFkSBDnDR+cm9J+9QhXmREyIfv0pji9ejCQ== + dependencies: + mimic-response "^3.1.0" + dedent@^0.7.0: version "0.7.0" resolved "https://registry.npmjs.org/dedent/-/dedent-0.7.0.tgz" @@ -5137,6 +5582,11 @@ defaults@^1.0.3: dependencies: clone "^1.0.2" +defer-to-connect@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/defer-to-connect/-/defer-to-connect-2.0.1.tgz" + integrity sha512-4tvttepXG1VaYGrRibk5EwJd1t4udunSOVMdLSAL6mId1ix438oPwPZMALY41FCijukO1L0twNcGsdzS7dHgDg== + define-lazy-prop@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/define-lazy-prop/-/define-lazy-prop-2.0.0.tgz" @@ -5160,7 +5610,7 @@ delegates@^1.0.0: resolved "https://registry.npmjs.org/delegates/-/delegates-1.0.0.tgz" integrity sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ== -depd@^2.0.0, depd@2.0.0: +depd@^2.0.0, depd@~2.0.0, depd@2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz" integrity sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw== @@ -5318,6 +5768,16 @@ duplexer@^0.1.1, duplexer@^0.1.2: resolved "https://registry.npmjs.org/duplexer/-/duplexer-0.1.2.tgz" integrity sha512-jtD6YG370ZCIi/9GTaJKQxWTZD045+4R4hTk/x1UyoqadyJ9x9CgSi1RlVDQF8U2sxLLSnFkCaMihqljHIWgMg== +duplexify@^4.1.2: + version "4.1.2" + resolved "https://registry.npmjs.org/duplexify/-/duplexify-4.1.2.tgz" + integrity sha512-fz3OjcNCHmRP12MJoZMPglx8m4rrFP8rovnk4vT8Fs+aonZoCwGg10dSsQsfP/E62eZcPTMSMP6686fu9Qlqtw== + dependencies: + end-of-stream "^1.4.1" + inherits "^2.0.3" + readable-stream "^3.1.1" + stream-shift "^1.0.0" + eastasianwidth@^0.2.0: version "0.2.0" resolved "https://registry.npmjs.org/eastasianwidth/-/eastasianwidth-0.2.0.tgz" @@ -5331,6 +5791,13 @@ ecc-jsbn@~0.1.1: jsbn "~0.1.0" safer-buffer "^2.1.0" +ecdsa-sig-formatter@1.0.11: + version "1.0.11" + resolved "https://registry.npmjs.org/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.11.tgz" + integrity sha512-nagl3RYrbNv6kQkeJIpt6NJZy8twLB/2vtz6yN9Z4vRKHN4/QZJIEbqohALSgwKdnksuY3k5Addp5lg8sVoVcQ== + dependencies: + safe-buffer "^5.0.1" + ee-first@1.1.1: version "1.1.1" resolved "https://registry.npmjs.org/ee-first/-/ee-first-1.1.1.tgz" @@ -5425,6 +5892,11 @@ env-paths@^2.2.0: resolved "https://registry.npmjs.org/env-paths/-/env-paths-2.2.1.tgz" integrity sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A== +envinfo@7.10.0: + version "7.10.0" + resolved "https://registry.npmjs.org/envinfo/-/envinfo-7.10.0.tgz" + integrity sha512-ZtUjZO6l5mwTHvc1L9+1q5p/R3wTopcfqMW8r5t8SJSKqeVI/LtajORwRFEKpEFuekjD0VBjwu1HMxL4UalIRw== + err-code@^2.0.2: version "2.0.3" resolved "https://registry.npmjs.org/err-code/-/err-code-2.0.3.tgz" @@ -5555,6 +6027,11 @@ escape-string-regexp@^4.0.0: resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz" integrity sha512-TtpcNJ3XAzx3Gq8sWRzJaVajRs0uVxA2YAkdb1jm2YkPz4G6egUFAyA3n5vtEIZefPk5Wa4UXbKuS5fKkJWdgA== +escape-string-regexp@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-5.0.0.tgz" + integrity sha512-/veY75JbMK4j1yjvuUxuVsiS/hr/4iHs9FTT6cgTexxdE0Ly/glccBAkloH/DofkjRbZU3bnoj38mOmhkZ0lHw== + escodegen@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/escodegen/-/escodegen-2.0.0.tgz" @@ -5724,6 +6201,11 @@ etag@~1.8.1: resolved "https://registry.npmjs.org/etag/-/etag-1.8.1.tgz" integrity sha512-aIL5Fx7mawVa300al2BnEE4iNvo1qETxLrPI/o05L7z6go7fCw1J6EQmbK4FmJ2AS7kgVF/KEZWufBfdClMcPg== +event-target-shim@^5.0.0: + version "5.0.1" + resolved "https://registry.npmjs.org/event-target-shim/-/event-target-shim-5.0.1.tgz" + integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== + eventemitter-asyncresource@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/eventemitter-asyncresource/-/eventemitter-asyncresource-1.0.0.tgz" @@ -5739,11 +6221,24 @@ eventemitter3@^4.0.0, eventemitter3@^4.0.4: resolved "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz" integrity sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw== -events@^3.2.0: +events@^3.2.0, events@^3.3.0: version "3.3.0" resolved "https://registry.npmjs.org/events/-/events-3.3.0.tgz" integrity sha512-mQw+2fkQbALzQ7V0MY0IqdnXNOeTtP4r0lN9z7AAawCXgqea7bDii20AYrIBrFd/Hx0M2Ocz6S111CaFkUcb0Q== +execa@^0.7.0: + version "0.7.0" + resolved "https://registry.npmjs.org/execa/-/execa-0.7.0.tgz" + integrity sha512-RztN09XglpYI7aBBrJCPW95jEH7YF1UEPOoX9yDhUTPdp7mK+CQvnLTuD10BNXZ3byLTu2uehZ8EcKT/4CGiFw== + dependencies: + cross-spawn "^5.0.1" + get-stream "^3.0.0" + is-stream "^1.1.0" + npm-run-path "^2.0.0" + p-finally "^1.0.0" + signal-exit "^3.0.0" + strip-eof "^1.0.0" + execa@^5.0.0, execa@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz" @@ -5774,7 +6269,7 @@ execa@4.1.0: signal-exit "^3.0.2" strip-final-newline "^2.0.0" -executable@^4.1.1: +executable@^4.1.0, executable@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/executable/-/executable-4.1.1.tgz" integrity sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg== @@ -5802,7 +6297,12 @@ exponential-backoff@^3.1.1: resolved "https://registry.npmjs.org/exponential-backoff/-/exponential-backoff-3.1.1.tgz" integrity sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw== -express@^4.17.3: +express-rate-limit@5.5.1: + version "5.5.1" + resolved "https://registry.npmjs.org/express-rate-limit/-/express-rate-limit-5.5.1.tgz" + integrity sha512-MTjE2eIbHv5DyfuFz4zLYWxpqVhEhkTiwFGuB74Q9CSou2WHO52nlE5y3Zlg6SIsiYUIPj6ifFxnkPz6O3sIUg== + +express@^4.17.3, express@4.18.2: version "4.18.2" resolved "https://registry.npmjs.org/express/-/express-4.18.2.tgz" integrity sha512-5/PsL6iGPdfQ/lKM1UuielYgv3BUoJfz1aUwU9vHZ+J7gyvwdQXFEBIEIaxeGf0GIcreATNyBExtalisDbuMqQ== @@ -5839,6 +6339,21 @@ express@^4.17.3: utils-merge "1.0.1" vary "~1.1.2" +ext-list@^2.0.0: + version "2.2.2" + resolved "https://registry.npmjs.org/ext-list/-/ext-list-2.2.2.tgz" + integrity sha512-u+SQgsubraE6zItfVA0tBuCBhfU9ogSRnsvygI7wht9TS510oLkBRXBsqopeUG/GBOIQyKZO9wjTqIu/sf5zFA== + dependencies: + mime-db "^1.28.0" + +ext-name@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/ext-name/-/ext-name-5.0.0.tgz" + integrity sha512-yblEwXAbGv1VQDmow7s38W77hzAgJAO50ztBLMcUyUBfxv1HC+LGwtiEN+Co6LtlqT/5uwVOxsD4TNIilWhwdQ== + dependencies: + ext-list "^2.0.0" + sort-keys-length "^1.0.0" + extend@~3.0.2: version "3.0.2" resolved "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz" @@ -5879,7 +6394,7 @@ fast-deep-equal@^3.1.1, fast-deep-equal@^3.1.3: resolved "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz" integrity sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q== -fast-glob@^3.0.3, fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.7, fast-glob@^3.2.9, fast-glob@3.2.12: +fast-glob@^3.0.3, fast-glob@^3.2.11, fast-glob@^3.2.12, fast-glob@^3.2.5, fast-glob@^3.2.7, fast-glob@^3.2.9, fast-glob@3.2.12: version "3.2.12" resolved "https://registry.npmjs.org/fast-glob/-/fast-glob-3.2.12.tgz" integrity sha512-DVj4CQIYYow0BlaelwK1pHl5n5cRSJfM60UA0zK891sVInoPri2Ekj7+e1CT3/3qxXenpI+nBBmQAcJPJgaj4w== @@ -5911,6 +6426,16 @@ fast-levenshtein@^2.0.6, fast-levenshtein@~2.0.6: resolved "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz" integrity sha512-DCXu6Ifhqcks7TZKY3Hxp3y6qphY5SJZmrWMDrKcERSOXWQdMhU9Ig/PYrzyw/ul9jOIyh0N4M0tbC5hodg8dw== +fast-redact@^3.0.0: + version "3.3.0" + resolved "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz" + integrity sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ== + +fast-safe-stringify@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/fast-safe-stringify/-/fast-safe-stringify-2.1.1.tgz" + integrity sha512-W+KJc2dmILlPplD/H4K9l9LcAHAfPtP6BY84uVLXQ6Evcz9Lcg33Y2z1IVblT6xdY54PXYVHEv+0Wpq8Io6zkA== + fastq@^1.6.0: version "1.15.0" resolved "https://registry.npmjs.org/fastq/-/fastq-1.15.0.tgz" @@ -5961,6 +6486,15 @@ file-loader@^6.2.0: loader-utils "^2.0.0" schema-utils "^3.0.0" +file-type@^17.1.6: + version "17.1.6" + resolved "https://registry.npmjs.org/file-type/-/file-type-17.1.6.tgz" + integrity sha512-hlDw5Ev+9e883s0pwUsuuYNu4tD7GgpUnOvykjv1Gya0ZIjuKumthDRua90VUn6/nlRKAjcxLUnHNTIUWwWIiw== + dependencies: + readable-web-to-node-stream "^3.0.2" + strtok3 "^7.0.0-alpha.9" + token-types "^5.0.0-alpha.2" + filelist@^1.0.1: version "1.0.4" resolved "https://registry.npmjs.org/filelist/-/filelist-1.0.4.tgz" @@ -5968,6 +6502,20 @@ filelist@^1.0.1: dependencies: minimatch "^5.0.1" +filename-reserved-regex@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/filename-reserved-regex/-/filename-reserved-regex-3.0.0.tgz" + integrity sha512-hn4cQfU6GOT/7cFHXBqeBg2TbrMBgdD0kcjLhvSQYYwm3s4B6cjvBfb7nBALJLAXqmU5xajSa7X2NnUud/VCdw== + +filenamify@^5.0.2: + version "5.1.1" + resolved "https://registry.npmjs.org/filenamify/-/filenamify-5.1.1.tgz" + integrity sha512-M45CbrJLGACfrPOkrTp3j2EcO9OBkKUYME0eiqOCa7i2poaklU0jhlIaMlr8ijLorT0uLAzrn3qXOp5684CkfA== + dependencies: + filename-reserved-regex "^3.0.0" + strip-outer "^2.0.0" + trim-repeated "^2.0.0" + fill-range@^7.0.1: version "7.0.1" resolved "https://registry.npmjs.org/fill-range/-/fill-range-7.0.1.tgz" @@ -6020,6 +6568,13 @@ find-up@^5.0.0: locate-path "^6.0.0" path-exists "^4.0.0" +find-versions@^5.0.0: + version "5.1.0" + resolved "https://registry.npmjs.org/find-versions/-/find-versions-5.1.0.tgz" + integrity sha512-+iwzCJ7C5v5KgcBuueqVoNiHVoQpwiUK5XFLjf0affFTep+Wcw93tPvmb8tqujDNmzhBDPddnWV/qgWSXgq+Hg== + dependencies: + semver-regex "^4.0.5" + flat-cache@^3.0.4: version "3.0.4" resolved "https://registry.npmjs.org/flat-cache/-/flat-cache-3.0.4.tgz" @@ -6255,6 +6810,11 @@ get-pkg-repo@^4.0.0: through2 "^2.0.0" yargs "^16.2.0" +get-stream@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/get-stream/-/get-stream-3.0.0.tgz" + integrity sha512-GlhdIUuVakc8SJ6kK0zAFbiGzRFzNnY4jUuEbV9UROo4Y+0Ny4fjvcZFVTeDA4odpFyOQzaw6hXukJSq/f28sQ== + get-stream@^5.0.0, get-stream@^5.1.0: version "5.2.0" resolved "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz" @@ -6345,6 +6905,17 @@ glob@^10.2.2: minipass "^5.0.0" path-scurry "^1.7.0" +glob@^6.0.1: + version "6.0.4" + resolved "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz" + integrity sha512-MKZeRNyYZAVVVG1oZeLaWie1uweH40m9AZwIwxyPbTSX4hHrVYSzLg0Ro5Z5R7XKkIX+Cc6oD1rqeDJnwsB8/A== + dependencies: + inflight "^1.0.4" + inherits "2" + minimatch "2 || 3" + once "^1.3.0" + path-is-absolute "^1.0.0" + glob@^7.1.3, glob@^7.1.4, glob@^7.1.6: version "7.2.3" resolved "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz" @@ -6458,7 +7029,24 @@ gopd@^1.0.1: dependencies: get-intrinsic "^1.1.3" -graceful-fs@^4.1.2, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: +got@^11.8.5: + version "11.8.6" + resolved "https://registry.npmjs.org/got/-/got-11.8.6.tgz" + integrity sha512-6tfZ91bOr7bOXnK7PRDCGBLa1H4U080YHNaAQ2KsMGlLEzRbk44nsZF2E1IeRc3vtJHPVbKCYgdFbaGO2ljd8g== + dependencies: + "@sindresorhus/is" "^4.0.0" + "@szmarczak/http-timer" "^4.0.5" + "@types/cacheable-request" "^6.0.1" + "@types/responselike" "^1.0.0" + cacheable-lookup "^5.0.3" + cacheable-request "^7.0.2" + decompress-response "^6.0.0" + http2-wrapper "^1.0.0-beta.5.2" + lowercase-keys "^2.0.0" + p-cancelable "^2.0.0" + responselike "^2.0.0" + +graceful-fs@^4.1.2, graceful-fs@^4.1.3, graceful-fs@^4.1.6, graceful-fs@^4.2.0, graceful-fs@^4.2.4, graceful-fs@^4.2.6, graceful-fs@^4.2.9: version "4.2.11" resolved "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz" integrity sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ== @@ -6480,7 +7068,7 @@ handle-thing@^2.0.0: resolved "https://registry.npmjs.org/handle-thing/-/handle-thing-2.0.1.tgz" integrity sha512-9Qn4yBxelxoh2Ow62nP+Ka/kMnOXRi8BXnRaUwezLNhqelnN49xKz4F/dPP8OYLxLxq6JDtZb2i9XznUQbNPTg== -handlebars@^4.7.7: +handlebars@^4.7.7, handlebars@4.7.7: version "4.7.7" resolved "https://registry.npmjs.org/handlebars/-/handlebars-4.7.7.tgz" integrity sha512-aAcXm5OAfE/8IXkcZvCepKU3VzW1/39Fb5ZuqMtgI/hT8X2YgoMvBY5dLhq/cpOvw7Lk1nK/UF71aLG/ZnVYRA== @@ -6492,6 +7080,19 @@ handlebars@^4.7.7: optionalDependencies: uglify-js "^3.1.4" +har-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz" + integrity sha512-Oqluz6zhGX8cyRaTQlFMPw80bSJVG2x/cFb8ZPhUILGgHka9SsokCCOQgpveePerqidZOrT14ipqfJb7ILcW5Q== + +har-validator@~5.1.3: + version "5.1.5" + resolved "https://registry.npmjs.org/har-validator/-/har-validator-5.1.5.tgz" + integrity sha512-nmT2T0lljbxdQZfspsno9hgrG3Uir6Ks5afism62poxqBM6sDnMEuPmzTq8XN0OEwqKLLdh1jQI3qyE66Nzb3w== + dependencies: + ajv "^6.12.3" + har-schema "^2.0.0" + hard-rejection@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/hard-rejection/-/hard-rejection-2.1.0.tgz" @@ -6623,7 +7224,7 @@ htmlparser2@^8.0.2: domutils "^3.0.1" entities "^4.4.0" -http-cache-semantics@^4.1.1: +http-cache-semantics@^4.0.0, http-cache-semantics@^4.1.1: version "4.1.1" resolved "https://registry.npmjs.org/http-cache-semantics/-/http-cache-semantics-4.1.1.tgz" integrity sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ== @@ -6707,6 +7308,15 @@ http-server@^14.1.0: union "~0.5.0" url-join "^4.0.1" +http-signature@~1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz" + integrity sha512-CAbnr6Rz4CYQkLYUtSNXxQPUH2gK8f3iWexVlsnMeD+GjlsQ0Xsy1cOX+mN3dtxYomRy21CiOzU8Uhw6OwncEQ== + dependencies: + assert-plus "^1.0.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + http-signature@~1.3.6: version "1.3.6" resolved "https://registry.npmjs.org/http-signature/-/http-signature-1.3.6.tgz" @@ -6716,6 +7326,19 @@ http-signature@~1.3.6: jsprim "^2.0.2" sshpk "^1.14.1" +http-status-codes@2.2.0: + version "2.2.0" + resolved "https://registry.npmjs.org/http-status-codes/-/http-status-codes-2.2.0.tgz" + integrity sha512-feERVo9iWxvnejp3SEfm/+oNG517npqL2/PIA8ORjyOZjGC7TwCRQsZylciLS64i6pJ0wRYz3rkXLRwbtFa8Ng== + +http2-wrapper@^1.0.0-beta.5.2: + version "1.0.3" + resolved "https://registry.npmjs.org/http2-wrapper/-/http2-wrapper-1.0.3.tgz" + integrity sha512-V+23sDMr12Wnz7iTcDeJr3O6AIxlnvT/bmaAAAP/Xda35C90p9599p0F1eHR/N1KILWSoWVAiOMFjBBXaXSMxg== + dependencies: + quick-lru "^5.1.1" + resolve-alpn "^1.0.0" + https-proxy-agent@^5.0.0, https-proxy-agent@^5.0.1, https-proxy-agent@5.0.1: version "5.0.1" resolved "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.1.tgz" @@ -6784,7 +7407,7 @@ identity-obj-proxy@3.0.0: dependencies: harmony-reflect "^1.4.6" -ieee754@^1.1.13: +ieee754@^1.1.13, ieee754@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz" integrity sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA== @@ -7116,6 +7739,11 @@ is-path-inside@^3.0.2: resolved "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz" integrity sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ== +is-plain-obj@^1.0.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" + integrity sha512-yvkRyxmFKEOQ4pNXCmJG5AEQNlXJS5LaONXo5/cLdTZdWvsZ1ioJEonLGAosKlMWE8lwUy/bJzMjcw8az73+Fg== + is-plain-obj@^1.1.0: version "1.1.0" resolved "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz" @@ -7143,6 +7771,11 @@ is-potential-custom-element-name@^1.0.1: resolved "https://registry.npmjs.org/is-potential-custom-element-name/-/is-potential-custom-element-name-1.0.1.tgz" integrity sha512-bCYeRA2rVibKZd+s2625gGnGF/t7DSqDs4dP7CrLA1m7jKWz6pps0LpYLJN8Q64HtmPKJ1hrN3nzPNKFEKOUiQ== +is-promise@^2.1.0: + version "2.2.2" + resolved "https://registry.npmjs.org/is-promise/-/is-promise-2.2.2.tgz" + integrity sha512-+lP4/6lKUBfQjZ2pdxThZvLUAafmZb8OAxFb8XXtiQmS35INgr85hdOGoEs124ez1FCnZJt6jau/T+alh58QFQ== + is-reference@^1.2.1: version "1.2.1" resolved "https://registry.npmjs.org/is-reference/-/is-reference-1.2.1.tgz" @@ -7170,6 +7803,11 @@ is-shared-array-buffer@^1.0.2: dependencies: call-bind "^1.0.2" +is-stream@^1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/is-stream/-/is-stream-1.1.0.tgz" + integrity sha512-uQPm8kcs47jx38atAcWTVxyltQYoPT68y9aWYdV6yWXSyW8mzSat0TL6CiWdZeCdF3KrAvpVtnHbTv4RN+rqdQ== + is-stream@^2.0.0: version "2.0.1" resolved "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz" @@ -7464,7 +8102,7 @@ jest-environment-jsdom@29.4.3: jest-util "^29.4.3" jsdom "^20.0.0" -jest-environment-node@^29.5.0: +jest-environment-node@^29.4.1, jest-environment-node@^29.5.0: version "29.5.0" resolved "https://registry.npmjs.org/jest-environment-node/-/jest-environment-node-29.5.0.tgz" integrity sha512-ExxuIK/+yQ+6PRGaHkKewYtg6hto2uGCgvKdb2nfJfKXgZ17DfXjvbZ+jA1Qt9A8EQSfPnt5FKIfnOO3u1h9qw== @@ -7848,6 +8486,11 @@ jsesc@~0.5.0: resolved "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz" integrity sha512-uZz5UnB7u4T9LvwmFqXii7pZSouaRPorGs5who1Ip7VO0wxanFvBL7GkM6dTHlgX+jhBApRetaWpnDabOeTcnA== +json-buffer@3.0.1: + version "3.0.1" + resolved "https://registry.npmjs.org/json-buffer/-/json-buffer-3.0.1.tgz" + integrity sha512-4bV5BfR2mqfQTJm+V5tPPdf+ZpuhiIvTuAB5g8kcrXOZpTT/QwwVRWBywX1ozr6lEuPdbHxwaJlm9G6mI2sfSQ== + json-parse-better-errors@^1.0.1: version "1.0.2" resolved "https://registry.npmjs.org/json-parse-better-errors/-/json-parse-better-errors-1.0.2.tgz" @@ -7929,7 +8572,7 @@ jsonparse@^1.2.0, jsonparse@^1.3.1: resolved "https://registry.npmjs.org/jsonparse/-/jsonparse-1.3.1.tgz" integrity sha512-POQXvpdL69+CluYsillJ7SUhKvytYjW9vG/GKpnf+xP8UWgYEM/RaMzHHofbALDiKbbP1W8UEYmgGl39WkPZsg== -JSONStream@^1.0.4: +JSONStream@^1.0.4, JSONStream@1.3.5: version "1.3.5" resolved "https://registry.npmjs.org/JSONStream/-/JSONStream-1.3.5.tgz" integrity sha512-E+iruNOY8VV9s4JEbe1aNEm6MiszPRr/UfcHMz0TQh1BXSxHK+ASV1R6W4HpjBhSeS+54PIsAMCBmwD06LLsqQ== @@ -7937,6 +8580,36 @@ JSONStream@^1.0.4: jsonparse "^1.2.0" through ">=2.2.7 <3" +jsonwebtoken@9.0.0: + version "9.0.0" + resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.0.tgz" + integrity sha512-tuGfYXxkQGDPnLJ7SibiQgVgeDgfbPq2k2ICcbgqW8WxWLBAxKQM/ZCu/IT8SOSwmaYl4dpTFCW5xZv7YbbWUw== + dependencies: + jws "^3.2.2" + lodash "^4.17.21" + ms "^2.1.1" + semver "^7.3.8" + +jsonwebtoken@9.0.1: + version "9.0.1" + resolved "https://registry.npmjs.org/jsonwebtoken/-/jsonwebtoken-9.0.1.tgz" + integrity sha512-K8wx7eJ5TPvEjuiVSkv167EVboBDv9PZdDoF7BgeQnBLVvZWW9clr2PsQHVJDTKaEIH5JBIwHujGcHp7GgI2eg== + dependencies: + jws "^3.2.2" + lodash "^4.17.21" + ms "^2.1.1" + semver "^7.3.8" + +jsprim@^1.2.2: + version "1.4.2" + resolved "https://registry.npmjs.org/jsprim/-/jsprim-1.4.2.tgz" + integrity sha512-P2bSOMAc/ciLz6DzgjVlGJP9+BrJWu5UDGK70C2iweC5QBIeFf0ZXRvGjEj2uYgrY2MkAAhsSWHDWlFtEroZWw== + dependencies: + assert-plus "1.0.0" + extsprintf "1.3.0" + json-schema "0.4.0" + verror "1.10.0" + jsprim@^2.0.2: version "2.0.2" resolved "https://registry.npmjs.org/jsprim/-/jsprim-2.0.2.tgz" @@ -7947,6 +8620,23 @@ jsprim@^2.0.2: json-schema "0.4.0" verror "1.10.0" +jwa@^1.4.1: + version "1.4.1" + resolved "https://registry.npmjs.org/jwa/-/jwa-1.4.1.tgz" + integrity sha512-qiLX/xhEEFKUAJ6FiBMbes3w9ATzyk5W7Hvzpa/SLYdxNtng+gcurvrI7TbACjIXlsJyr05/S1oUhZrc63evQA== + dependencies: + buffer-equal-constant-time "1.0.1" + ecdsa-sig-formatter "1.0.11" + safe-buffer "^5.0.1" + +jws@^3.2.2: + version "3.2.2" + resolved "https://registry.npmjs.org/jws/-/jws-3.2.2.tgz" + integrity sha512-YHlZCB6lMTllWDtSPHz/ZXTsi8S00usEV6v1tjq8tOUZzw7DpSDWVXjXDre6ed1w/pd495ODpHZYSdkRTsa0HA== + dependencies: + jwa "^1.4.1" + safe-buffer "^5.0.1" + karma-source-map-support@1.4.0: version "1.4.0" resolved "https://registry.npmjs.org/karma-source-map-support/-/karma-source-map-support-1.4.0.tgz" @@ -7954,6 +8644,20 @@ karma-source-map-support@1.4.0: dependencies: source-map-support "^0.5.5" +keygrip@~1.1.0: + version "1.1.0" + resolved "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz" + integrity sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ== + dependencies: + tsscmp "1.0.6" + +keyv@^4.0.0: + version "4.5.3" + resolved "https://registry.npmjs.org/keyv/-/keyv-4.5.3.tgz" + integrity sha512-QCiSav9WaX1PgETJ+SpNnx2PRRapJ/oRSXM4VO5OGYGSjrxbKPVFVhB3l2OCbLCk329N8qyAtsJjSjvVBWzEug== + dependencies: + json-buffer "3.0.1" + kind-of@^6.0.2, kind-of@^6.0.3: version "6.0.3" resolved "https://registry.npmjs.org/kind-of/-/kind-of-6.0.3.tgz" @@ -7964,6 +8668,11 @@ kleur@^3.0.3: resolved "https://registry.npmjs.org/kleur/-/kleur-3.0.3.tgz" integrity sha512-eTIzlVOSUR+JxdDFepEYcBMtZ9Qqdef+rnzWdRZuMbOywu5tO2w2N7rqjoANZ5k9vywhL6Br1VRjUIgTQx4E8w== +kleur@4.1.5: + version "4.1.5" + resolved "https://registry.npmjs.org/kleur/-/kleur-4.1.5.tgz" + integrity sha512-o+NO+8WrRiQEE4/7nwRJhN1HWpVmJm511pBHUxPLtp0BUISzlBplORYSmTclCnJvQq2tKu/sgl3xVpkc7ZWuQQ== + klona@^2.0.4, klona@^2.0.5, klona@^2.0.6: version "2.0.6" resolved "https://registry.npmjs.org/klona/-/klona-2.0.6.tgz" @@ -8158,6 +8867,13 @@ locate-path@^6.0.0: dependencies: p-locate "^5.0.0" +lockfile@1.0.4: + version "1.0.4" + resolved "https://registry.npmjs.org/lockfile/-/lockfile-1.0.4.tgz" + integrity sha512-cvbTwETRfsFh4nHsL1eGWapU1XFi5Ot9E85sWAwia7Y7EgB7vfqcZhTKZ+l7hCGxSPoushMv5GKhT5PdLv03WA== + dependencies: + signal-exit "^3.0.2" + lodash-es@^4.17.21: version "4.17.21" resolved "https://registry.npmjs.org/lodash-es/-/lodash-es-4.17.21.tgz" @@ -8198,7 +8914,7 @@ lodash.uniq@^4.5.0: resolved "https://registry.npmjs.org/lodash.uniq/-/lodash.uniq-4.5.0.tgz" integrity sha512-xfBaXQd9ryd9dlSDvnvI0lvxfLJlYAZzXomUYzLKtUeOQvOP5piqAWuGtrhWeqaXK9hhoM/iyJc5AV+XfsX3HQ== -lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21: +lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.20, lodash@^4.17.21, lodash@4, lodash@4.17.21: version "4.17.21" resolved "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz" integrity sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg== @@ -8221,6 +8937,30 @@ log-update@^4.0.0: slice-ansi "^4.0.0" wrap-ansi "^6.2.0" +lowdb@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/lowdb/-/lowdb-1.0.0.tgz" + integrity sha512-2+x8esE/Wb9SQ1F9IHaYWfsC9FIecLOPrK4g17FGEayjUWH172H6nwicRovGvSE2CPZouc2MCIqCI7h9d+GftQ== + dependencies: + graceful-fs "^4.1.3" + is-promise "^2.1.0" + lodash "4" + pify "^3.0.0" + steno "^0.4.1" + +lowercase-keys@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/lowercase-keys/-/lowercase-keys-2.0.0.tgz" + integrity sha512-tqNXrS78oMOE73NMxK4EMLQsQowWf8jKooH9g7xPavRT706R6bkQJ6DY2Te7QukaZsulxa30wQ7bk0pm4XiHmA== + +lru-cache@^4.0.1: + version "4.1.5" + resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-4.1.5.tgz" + integrity sha512-sWZlbEP2OsHNkXrMl5GYk/jKk70MBng6UU4YI/qGDYbgf6YbP4EvmqISbXCoJiRKs+1bSpFHVgQxvJ17F2li5g== + dependencies: + pseudomap "^1.0.2" + yallist "^2.1.2" + lru-cache@^5.1.1: version "5.1.1" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-5.1.1.tgz" @@ -8235,7 +8975,7 @@ lru-cache@^6.0.0: dependencies: yallist "^4.0.0" -lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1: +lru-cache@^7.4.4, lru-cache@^7.5.1, lru-cache@^7.7.1, lru-cache@7.18.3: version "7.18.3" resolved "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz" integrity sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA== @@ -8396,7 +9136,7 @@ micromatch@^4.0.0, micromatch@^4.0.2, micromatch@^4.0.4, micromatch@^4.0.5: braces "^3.0.2" picomatch "^2.3.1" -"mime-db@>= 1.43.0 < 2", mime-db@1.52.0: +mime-db@^1.28.0, "mime-db@>= 1.43.0 < 2", mime-db@1.52.0: version "1.52.0" resolved "https://registry.npmjs.org/mime-db/-/mime-db-1.52.0.tgz" integrity sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg== @@ -8418,11 +9158,31 @@ mime@~2.5.2: resolved "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz" integrity sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg== +mime@2.6.0: + version "2.6.0" + resolved "https://registry.npmjs.org/mime/-/mime-2.6.0.tgz" + integrity sha512-USPkMeET31rOMiarsBNIHZKLGgvKc/LrjofAnBlOttf5ajRvqiRA8QsenbcooctK6d6Ts6aqZXBA+XbkKthiQg== + +mime@3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/mime/-/mime-3.0.0.tgz" + integrity sha512-jSCU7/VB1loIWBZe14aEYHU/+1UMEHoaO7qxCOVJOw9GgH72VAWppxNcjU+x9a2k3GSIBXNKxXQFqRvvZ7vr3A== + mimic-fn@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +mimic-response@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-1.0.1.tgz" + integrity sha512-j5EctnkH7amfV/q5Hgmoal1g2QHFJRraOtmx0JpIqkxhBhI/lJSl1nMpQ45hVarwNETOoWEimndZ4QK0RHxuxQ== + +mimic-response@^3.1.0: + version "3.1.0" + resolved "https://registry.npmjs.org/mimic-response/-/mimic-response-3.1.0.tgz" + integrity sha512-z0yWI+4FDrrweS8Zmt4Ej5HdJmky15+L2e6Wgn3+iK5fWzb6T3fhNFq2+MeTRb064c6Wr4N/wv0DzQTjNzHNGQ== + min-indent@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/min-indent/-/min-indent-1.0.1.tgz" @@ -8452,7 +9212,7 @@ minimalistic-assert@^1.0.0: resolved "https://registry.npmjs.org/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz" integrity sha512-UtJcAD4yEaGtjPezWuO9wC4nwUnVH/8/Im3yEHQP4b67cXlD/Qr9hdITCU1xDbSEXg2XKNaP8jsReV7vQd00/A== -minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2: +minimatch@^3.0.4, minimatch@^3.1.1, minimatch@^3.1.2, "minimatch@2 || 3", minimatch@3.1.2: version "3.1.2" resolved "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz" integrity sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw== @@ -8594,11 +9354,18 @@ mkdirp@^0.5.6: dependencies: minimist "^1.2.6" -mkdirp@^1.0.3: +mkdirp@^1.0.3, mkdirp@1.0.4: version "1.0.4" resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-1.0.4.tgz" integrity sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw== +mkdirp@~0.5.1: + version "0.5.6" + resolved "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz" + integrity sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw== + dependencies: + minimist "^1.2.6" + modify-values@^1.0.0: version "1.0.1" resolved "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz" @@ -8637,6 +9404,20 @@ mute-stream@0.0.8: resolved "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.8.tgz" integrity sha512-nnbWWOkoWyUsTjKrhgD0dcz22mdkSnpYqbEjIm2nhwhuxlSkpywJmBo8h0ZqJdkp73mb90SssHkN4rsRaBAfAA== +mv@2.1.1: + version "2.1.1" + resolved "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz" + integrity sha512-at/ZndSy3xEGJ8i0ygALh8ru9qy7gWW1cmkaqBN29JmMlIvM//MEO9y1sk/avxuwnPcfhkejkLsuPxH81BrkSg== + dependencies: + mkdirp "~0.5.1" + ncp "~2.0.0" + rimraf "~2.4.0" + +nanoclone@^0.2.1: + version "0.2.1" + resolved "https://registry.npmjs.org/nanoclone/-/nanoclone-0.2.1.tgz" + integrity sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA== + nanoid@^3.3.6: version "3.3.6" resolved "https://registry.npmjs.org/nanoid/-/nanoid-3.3.6.tgz" @@ -8652,6 +9433,11 @@ natural-compare@^1.4.0: resolved "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz" integrity sha512-OWND8ei3VtNC9h7V60qff3SVobHr996CTwgxubgyQYEpg290h9J0buyECNNJexkFm5sOajh5G116RYA1c8ZMSw== +ncp@~2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/ncp/-/ncp-2.0.0.tgz" + integrity sha512-zIdGUrPRFTUELUvr3Gmc7KZ2Sw/h1PiVM0Af/oHB6zgnV1ikqSfRk+TOufi79aHYCW3NiOXmr1BP5nWbzojLaA== + needle@^3.1.0: version "3.2.0" resolved "https://registry.npmjs.org/needle/-/needle-3.2.0.tgz" @@ -8728,6 +9514,13 @@ node-addon-api@^3.0.0, node-addon-api@^3.2.1: resolved "https://registry.npmjs.org/node-addon-api/-/node-addon-api-3.2.1.tgz" integrity sha512-mmcei9JghVNDYydghQmeDX8KoAm0FAiYyIcUt/N4nhyAipB17pllZQDOJD2fotxABnt4Mdz+dKTO7eftLg4d0A== +node-fetch@cjs: + version "2.6.7" + resolved "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz" + integrity sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ== + dependencies: + whatwg-url "^5.0.0" + node-forge@^1: version "1.3.1" resolved "https://registry.npmjs.org/node-forge/-/node-forge-1.3.1.tgz" @@ -8891,6 +9684,13 @@ npm-registry-fetch@^14.0.0: npm-package-arg "^10.0.0" proc-log "^3.0.0" +npm-run-path@^2.0.0: + version "2.0.2" + resolved "https://registry.npmjs.org/npm-run-path/-/npm-run-path-2.0.2.tgz" + integrity sha512-lJxZYlT4DW/bRUtFh1MQIWqmLwQfAxnqWG4HhEdjMlkrJYnJn0Jrr2u3mgxqaWsdiBc76TYkTG/mhrnYTuzfHw== + dependencies: + path-key "^2.0.0" + npm-run-path@^4.0.0, 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" @@ -8987,6 +9787,16 @@ nx@16.4.0: "@nx/nx-win32-arm64-msvc" "16.4.0" "@nx/nx-win32-x64-msvc" "16.4.0" +oauth-sign@~0.9.0: + version "0.9.0" + resolved "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz" + integrity sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ== + +object-assign@^4: + version "4.1.1" + resolved "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz" + integrity sha512-rJgTQnkUnH1sFw8yT6VSU3zD3sWmu6sZhIseY8VX+GRu3P6F7Fu+JNDoXfklElbLJSnc3FUQHVe4cU5hj+BcUg== + object-inspect@^1.12.2, object-inspect@^1.9.0: version "1.12.3" resolved "https://registry.npmjs.org/object-inspect/-/object-inspect-1.12.3.tgz" @@ -9020,6 +9830,11 @@ obuf@^1.0.0, obuf@^1.1.2: resolved "https://registry.npmjs.org/obuf/-/obuf-1.1.2.tgz" integrity sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg== +on-exit-leak-free@^0.2.0: + version "0.2.0" + resolved "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-0.2.0.tgz" + integrity sha512-dqaz3u44QbRXQooZLTUKU41ZrzYrcvLISVgbrzbyCMxpmSLJvZ3ZamIJIZ29P6OhZIkNIQKosdeM6t1LYbA9hg== + on-finished@2.4.1: version "2.4.1" resolved "https://registry.npmjs.org/on-finished/-/on-finished-2.4.1.tgz" @@ -9107,6 +9922,13 @@ ora@^5.1.0, ora@^5.4.1, ora@5.4.1: strip-ansi "^6.0.0" wcwidth "^1.0.1" +os-filter-obj@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/os-filter-obj/-/os-filter-obj-2.0.0.tgz" + integrity sha512-uksVLsqG3pVdzzPvmAHpBK0wKxYItuzZr7SziusRPoz67tGV8rL1szZ6IdeUrbqLjGDwApBtN29eEE3IqGHOjg== + dependencies: + arch "^2.1.0" + os-tmpdir@~1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz" @@ -9117,6 +9939,11 @@ ospath@^1.2.2: resolved "https://registry.npmjs.org/ospath/-/ospath-1.2.2.tgz" integrity sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA== +p-cancelable@^2.0.0: + version "2.1.1" + resolved "https://registry.npmjs.org/p-cancelable/-/p-cancelable-2.1.1.tgz" + integrity sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg== + p-finally@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/p-finally/-/p-finally-1.0.0.tgz" @@ -9311,6 +10138,11 @@ path-is-absolute@^1.0.0: resolved "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz" integrity sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg== +path-key@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz" + integrity sha512-fEHGKCSmUSDPv4uoj8AlD+joPlq3peND+HRYyxFz4KPw4z926S/b8rIuFs2FYJg3BwsxJf6A9/3eIdLaYC+9Dw== + path-key@^3.0.0, path-key@^3.1.0: version "3.1.1" resolved "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz" @@ -9346,6 +10178,11 @@ path-type@^4.0.0: resolved "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz" integrity sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw== +peek-readable@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/peek-readable/-/peek-readable-5.0.0.tgz" + integrity sha512-YtCKvLUOvwtMGmrniQPdO7MwPjgkFBtFIrmfSbYmYuq3tKDV/mcfAhBth1+C3ru7uXIZasc/pHnb+YDYNkkj4A== + pend@~1.2.0: version "1.2.0" resolved "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz" @@ -9391,6 +10228,44 @@ pify@^5.0.0: resolved "https://registry.npmjs.org/pify/-/pify-5.0.0.tgz" integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== +pino-abstract-transport@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-1.0.0.tgz" + integrity sha512-c7vo5OpW4wIS42hUVcT5REsL8ZljsUfBjqV/e2sFxmFEFZiq1XLUp5EYLtuDH6PEHq9W1egWqRbnLUP5FuZmOA== + dependencies: + readable-stream "^4.0.0" + split2 "^4.0.0" + +pino-abstract-transport@v0.5.0: + version "0.5.0" + resolved "https://registry.npmjs.org/pino-abstract-transport/-/pino-abstract-transport-0.5.0.tgz" + integrity sha512-+KAgmVeqXYbTtU2FScx1XS3kNyfZ5TrXY07V96QnUSFqo2gAqlvmaxH67Lj7SWazqsMabf+58ctdTcBgnOLUOQ== + dependencies: + duplexify "^4.1.2" + split2 "^4.0.0" + +pino-std-serializers@^4.0.0: + version "4.0.0" + resolved "https://registry.npmjs.org/pino-std-serializers/-/pino-std-serializers-4.0.0.tgz" + integrity sha512-cK0pekc1Kjy5w9V2/n+8MkZwusa6EyyxfeQCB799CQRhRt/CqYKiWs5adeu8Shve2ZNffvfC/7J64A2PJo1W/Q== + +pino@7.11.0: + version "7.11.0" + resolved "https://registry.npmjs.org/pino/-/pino-7.11.0.tgz" + integrity sha512-dMACeu63HtRLmCG8VKdy4cShCPKaYDR4youZqoSWLxl5Gu99HUw8bw75thbPv9Nip+H+QYX8o3ZJbTdVZZ2TVg== + dependencies: + atomic-sleep "^1.0.0" + fast-redact "^3.0.0" + on-exit-leak-free "^0.2.0" + pino-abstract-transport v0.5.0 + pino-std-serializers "^4.0.0" + process-warning "^1.0.0" + quick-format-unescaped "^4.0.3" + real-require "^0.1.0" + safe-stable-stringify "^2.1.0" + sonic-boom "^2.2.1" + thread-stream "^0.15.1" + pirates@^4.0.4: version "4.0.5" resolved "https://registry.npmjs.org/pirates/-/pirates-4.0.5.tgz" @@ -9414,6 +10289,11 @@ pkg-dir@^4.1.0, pkg-dir@^4.2.0: dependencies: find-up "^4.0.0" +pkginfo@0.4.1: + version "0.4.1" + resolved "https://registry.npmjs.org/pkginfo/-/pkginfo-0.4.1.tgz" + integrity sha512-8xCNE/aT/EXKenuMDZ+xTVwkT8gsoHN2z/Q29l80u0ppGEXVvsKRzNMbtKhg8LS8k1tJLAHHylf6p4VFmP6XUQ== + portfinder@^1.0.28: version "1.0.32" resolved "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz" @@ -10234,6 +11114,16 @@ process-nextick-args@~2.0.0: resolved "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.1.tgz" integrity sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag== +process-warning@^1.0.0, process-warning@1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/process-warning/-/process-warning-1.0.0.tgz" + integrity sha512-du4wfLyj4yCZq1VupnVSZmRsPJsNuxoDQFdCFHLaYiEbFBD7QE0a+I4D7hOxrVnh78QE/YipFAj9lXHiXocV+Q== + +process@^0.11.10: + version "0.11.10" + resolved "https://registry.npmjs.org/process/-/process-0.11.10.tgz" + integrity sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A== + promise-inflight@^1.0.1: version "1.0.1" resolved "https://registry.npmjs.org/promise-inflight/-/promise-inflight-1.0.1.tgz" @@ -10260,6 +11150,11 @@ prompts@^2.0.1: kleur "^3.0.3" sisteransi "^1.0.5" +property-expr@^2.0.4: + version "2.0.5" + resolved "https://registry.npmjs.org/property-expr/-/property-expr-2.0.5.tgz" + integrity sha512-IJUkICM5dP5znhCckHSv30Q4b5/JA5enCtkRHYaOVOAocnH/1BQEYTC5NMfT3AVl/iXKdr3aqQbQn9DxyWknwA== + proxy-addr@~2.0.7: version "2.0.7" resolved "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz" @@ -10283,6 +11178,11 @@ prr@~1.0.1: resolved "https://registry.npmjs.org/prr/-/prr-1.0.1.tgz" integrity sha512-yPw4Sng1gWghHQWj0B3ZggWUm4qVbPwPFcRG8KyxiU7J2OHFSoEHKS+EZ3fv5l1t9CyCiop6l/ZYeWbrgoQejw== +pseudomap@^1.0.2: + version "1.0.2" + resolved "https://registry.npmjs.org/pseudomap/-/pseudomap-1.0.2.tgz" + integrity sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ== + psl@^1.1.28, psl@^1.1.33: version "1.9.0" resolved "https://registry.npmjs.org/psl/-/psl-1.9.0.tgz" @@ -10325,6 +11225,11 @@ qs@~6.10.3: dependencies: side-channel "^1.0.4" +qs@~6.5.2: + version "6.5.3" + resolved "https://registry.npmjs.org/qs/-/qs-6.5.3.tgz" + integrity sha512-qxXIEh4pCGfHICj1mAJQ2/2XVZkjCDTcEgfoSQxc/fYivUZxTkk7L3bDBJSoNrEzXI17oUO5Dp07ktqE5KzczA== + qs@6.11.0: version "6.11.0" resolved "https://registry.npmjs.org/qs/-/qs-6.11.0.tgz" @@ -10342,11 +11247,21 @@ queue-microtask@^1.2.2: resolved "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz" integrity sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A== +quick-format-unescaped@^4.0.3: + version "4.0.4" + resolved "https://registry.npmjs.org/quick-format-unescaped/-/quick-format-unescaped-4.0.4.tgz" + integrity sha512-tYC1Q1hgyRuHgloV/YXs2w15unPVh8qfu/qCTfhTYamaw7fyhumKa2yGpdSo87vY32rIclj+4fWYQXUMs9EHvg== + quick-lru@^4.0.1: version "4.0.1" resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-4.0.1.tgz" integrity sha512-ARhCpm70fzdcvNQfPoy49IaanKkTlRWF2JMzqhcJbhSFRZv7nPTvZJdcY7301IPmvW+/p0RgIWnQDLJxifsQ7g== +quick-lru@^5.1.1: + version "5.1.1" + resolved "https://registry.npmjs.org/quick-lru/-/quick-lru-5.1.1.tgz" + integrity sha512-WuyALRjWPDGtt/wzJiadO5AXY+8hZ80hVpe6MyivgraREW751X3SbhRvG3eLKOYN+8VEvqLcf3wdnt44Z4S4SA== + randombytes@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/randombytes/-/randombytes-2.1.0.tgz" @@ -10457,6 +11372,17 @@ readable-stream@^3.0.0, readable-stream@^3.0.2, readable-stream@^3.0.6, readable string_decoder "^1.1.1" util-deprecate "^1.0.1" +readable-stream@^4.0.0: + version "4.4.2" + resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz" + integrity sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA== + dependencies: + abort-controller "^3.0.0" + buffer "^6.0.3" + events "^3.3.0" + process "^0.11.10" + string_decoder "^1.3.0" + readable-stream@~2.3.6: version "2.3.8" resolved "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz" @@ -10470,6 +11396,13 @@ readable-stream@~2.3.6: string_decoder "~1.1.1" util-deprecate "~1.0.1" +readable-web-to-node-stream@^3.0.2: + version "3.0.2" + resolved "https://registry.npmjs.org/readable-web-to-node-stream/-/readable-web-to-node-stream-3.0.2.tgz" + integrity sha512-ePeK6cc1EcKLEhJFt/AebMCLL+GgSKhuygrZ/GLaKZYEecIgIECf4UaUuaByiGtzckwR4ain9VzUh95T1exYGw== + dependencies: + readable-stream "^3.6.0" + readdirp@~3.6.0: version "3.6.0" resolved "https://registry.npmjs.org/readdirp/-/readdirp-3.6.0.tgz" @@ -10477,6 +11410,11 @@ readdirp@~3.6.0: dependencies: picomatch "^2.2.1" +real-require@^0.1.0: + version "0.1.0" + resolved "https://registry.npmjs.org/real-require/-/real-require-0.1.0.tgz" + integrity sha512-r/H9MzAWtrv8aSVjPCMFpDMl5q66GqtmmRkRjpHTsp4zBAa+snZyiQNlMONiUmEJcsnaw0wCauJ2GWODr/aFkg== + redent@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/redent/-/redent-3.0.0.tgz" @@ -10559,6 +11497,32 @@ request-progress@^3.0.0: dependencies: throttleit "^1.0.0" +request@2.88.2: + version "2.88.2" + resolved "https://registry.npmjs.org/request/-/request-2.88.2.tgz" + integrity sha512-MsvtOrfG9ZcrOwAW+Qi+F6HbD0CWXEh9ou77uOb7FM2WPhwT7smM833PzanhJLsgXjN89Ir6V2PczXNnMpwKhw== + dependencies: + aws-sign2 "~0.7.0" + aws4 "^1.8.0" + caseless "~0.12.0" + combined-stream "~1.0.6" + extend "~3.0.2" + forever-agent "~0.6.1" + form-data "~2.3.2" + har-validator "~5.1.3" + http-signature "~1.2.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.19" + oauth-sign "~0.9.0" + performance-now "^2.1.0" + qs "~6.5.2" + safe-buffer "^5.1.2" + tough-cookie "~2.5.0" + tunnel-agent "^0.6.0" + uuid "^3.3.2" + require-directory@^2.1.1: version "2.1.1" resolved "https://registry.npmjs.org/require-directory/-/require-directory-2.1.1.tgz" @@ -10574,6 +11538,11 @@ requires-port@^1.0.0: resolved "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz" integrity sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ== +resolve-alpn@^1.0.0: + version "1.2.1" + resolved "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz" + integrity sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g== + resolve-cwd@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/resolve-cwd/-/resolve-cwd-3.0.0.tgz" @@ -10628,6 +11597,13 @@ resolve@^1.1.7, resolve@^1.10.0, resolve@^1.12.0, resolve@^1.14.2, resolve@^1.17 path-parse "^1.0.7" supports-preserve-symlinks-flag "^1.0.0" +responselike@^2.0.0: + version "2.0.1" + resolved "https://registry.npmjs.org/responselike/-/responselike-2.0.1.tgz" + integrity sha512-4gl03wn3hj1HP3yzgdI7d3lCkF95F21Pz4BPGvKHinyQzALR5CapwC8yIi0Rh58DEMQ/SguC03wFj2k0M/mHhw== + dependencies: + lowercase-keys "^2.0.0" + restore-cursor@^3.1.0: version "3.1.0" resolved "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz" @@ -10663,6 +11639,13 @@ rimraf@^3.0.0, rimraf@^3.0.2: dependencies: glob "^7.1.3" +rimraf@~2.4.0: + version "2.4.5" + resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz" + integrity sha512-J5xnxTyqaiw06JjMftq7L9ouA448dw/E7dKghkP9WpKNuwmARNNg+Gk8/u5ryb9N/Yo2+z3MCwuqFK/+qPOPfQ== + dependencies: + glob "^6.0.1" + rimraf@~2.6.2: version "2.6.3" resolved "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz" @@ -10818,6 +11801,11 @@ safe-identifier@^0.4.2: resolved "https://registry.npmjs.org/safe-identifier/-/safe-identifier-0.4.2.tgz" integrity sha512-6pNbSMW6OhAi9j+N8V+U715yBQsaWJ7eyEUaOrawX+isg5ZxhUlV1NipNtgaKHmFGiABwt+ZF04Ii+3Xjkg+8w== +safe-stable-stringify@^2.1.0: + version "2.4.3" + resolved "https://registry.npmjs.org/safe-stable-stringify/-/safe-stable-stringify-2.4.3.tgz" + integrity sha512-e2bDA2WJT0wxseVd4lsDP4+3ONX6HpMXQa1ZhFQ7SU+GjvORCmShbCMltrtIDfkYhVHrOcPtj+KhmDBdPdZD1g== + safer-buffer@^2.0.2, safer-buffer@^2.1.0, "safer-buffer@>= 2.1.2 < 3", "safer-buffer@>= 2.1.2 < 3.0.0", safer-buffer@~2.1.0: version "2.1.2" resolved "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz" @@ -10933,6 +11921,18 @@ selfsigned@^2.1.1: dependencies: node-forge "^1" +semver-regex@^4.0.5: + version "4.0.5" + resolved "https://registry.npmjs.org/semver-regex/-/semver-regex-4.0.5.tgz" + integrity sha512-hunMQrEy1T6Jr2uEVjrAIqjwWcQTgOAcIM52C8MY1EZSD3DDNft04XzvYKPqjED65bNVVko0YI38nYeEHCX3yw== + +semver-truncate@^3.0.0: + version "3.0.0" + resolved "https://registry.npmjs.org/semver-truncate/-/semver-truncate-3.0.0.tgz" + integrity sha512-LJWA9kSvMolR51oDE6PN3kALBNaUdkxzAGcexw8gjMA8xr5zUqK0JiR3CgARSqanYF3Z1YHvsErb1KDgh+v7Rg== + dependencies: + semver "^7.3.5" + semver@^5.6.0: version "5.7.1" resolved "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz" @@ -10948,10 +11948,10 @@ semver@^6.1.1, semver@^6.1.2, semver@^6.3.0: resolved "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@7.x: - version "7.5.0" - resolved "https://registry.npmjs.org/semver/-/semver-7.5.0.tgz" - integrity sha512-+XC0AD/R7Q2mPSRuy2Id0+CGTZ98+8f+KvwirxOKIEyid+XSx6HbC63p+O4IndTHuX5Z+JxQ0TghCkO5Cg/2HA== +semver@^7.0.0, semver@^7.1.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5, semver@^7.3.7, semver@^7.3.8, semver@^7.5.3, semver@7.5.4, semver@7.x: + version "7.5.4" + resolved "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz" + integrity sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA== dependencies: lru-cache "^6.0.0" @@ -11052,6 +12052,13 @@ shallow-clone@^3.0.0: dependencies: kind-of "^6.0.2" +shebang-command@^1.2.0: + version "1.2.0" + resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz" + integrity sha512-EV3L1+UQWGor21OmnvojK36mhg+TyIKDh3iFBKBohr5xeXIhNBcx8oWdgkTEEQ+BEFFYdLRuqMfd5L84N1V5Vg== + dependencies: + shebang-regex "^1.0.0" + shebang-command@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz" @@ -11059,6 +12066,11 @@ shebang-command@^2.0.0: dependencies: shebang-regex "^3.0.0" +shebang-regex@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz" + integrity sha512-wpoSFAxys6b2a2wHZ1XpDSgD7N9iVjg29Ph9uV/uaP9Ex/KXlkTZTeddxDPSYQpgvzKLGJke2UU0AzoGCjNIvQ== + shebang-regex@^3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz" @@ -11078,7 +12090,7 @@ side-channel@^1.0.4: get-intrinsic "^1.0.2" object-inspect "^1.9.0" -signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: +signal-exit@^3.0.0, signal-exit@^3.0.2, signal-exit@^3.0.3, signal-exit@^3.0.7: version "3.0.7" resolved "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz" integrity sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ== @@ -11103,7 +12115,7 @@ sisteransi@^1.0.5: resolved "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz" integrity sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg== -slash@^3.0.0: +slash@^3.0.0, slash@3.0.0: version "3.0.0" resolved "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz" integrity sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q== @@ -11170,6 +12182,34 @@ socks@^2.6.2: ip "^2.0.0" smart-buffer "^4.2.0" +sonic-boom@^2.2.1: + version "2.8.0" + resolved "https://registry.npmjs.org/sonic-boom/-/sonic-boom-2.8.0.tgz" + integrity sha512-kuonw1YOYYNOve5iHdSahXPOK49GqwA+LZhI6Wz/l0rP57iKyXXIHaRagOBHAPmGwJC6od2Z9zgvZ5loSgMlVg== + dependencies: + atomic-sleep "^1.0.0" + +sonic-boom@3.3.0: + version "3.3.0" + resolved "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz" + integrity sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g== + dependencies: + atomic-sleep "^1.0.0" + +sort-keys-length@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/sort-keys-length/-/sort-keys-length-1.0.1.tgz" + integrity sha512-GRbEOUqCxemTAk/b32F2xa8wDTs+Z1QHOkbhJDQTvv/6G3ZkbJ+frYWsTcc7cBB3Fu4wy4XlLCuNtJuMn7Gsvw== + dependencies: + sort-keys "^1.0.0" + +sort-keys@^1.0.0: + version "1.1.2" + resolved "https://registry.npmjs.org/sort-keys/-/sort-keys-1.1.2.tgz" + integrity sha512-vzn8aSqKgytVik0iwdBEi+zevbTYZogewTUM6dtpmGwEcdzbub/TX4bCzRhebDCRC3QzXgJsLRKB2V/Oof7HXg== + dependencies: + is-plain-obj "^1.0.0" + source-map-explorer@^2.5.2: version "2.5.3" resolved "https://registry.npmjs.org/source-map-explorer/-/source-map-explorer-2.5.3.tgz" @@ -11323,12 +12363,17 @@ split2@^3.0.0: dependencies: readable-stream "^3.0.0" +split2@^4.0.0: + version "4.2.0" + resolved "https://registry.npmjs.org/split2/-/split2-4.2.0.tgz" + integrity sha512-UcjcJOWknrNkF6PLX83qcHM6KHgVKNkV62Y8a5uYDVv9ydGQVwAHMKqHdJje1VTWpljG0WYpCDhrCdAOYH4TWg== + sprintf-js@~1.0.2: version "1.0.3" resolved "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz" integrity sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g== -sshpk@^1.14.1: +sshpk@^1.14.1, sshpk@^1.7.0: version "1.17.0" resolved "https://registry.npmjs.org/sshpk/-/sshpk-1.17.0.tgz" integrity sha512-/9HIEs1ZXGhSPE8X6Ccm7Nam1z8KcoCqPdI7ecm1N33EzAetWahvQWVqLZtaZQ+IDKX4IyA2o0gBzqIMkAagHQ== @@ -11372,6 +12417,13 @@ statuses@2.0.1: resolved "https://registry.npmjs.org/statuses/-/statuses-2.0.1.tgz" integrity sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ== +steno@^0.4.1: + version "0.4.4" + resolved "https://registry.npmjs.org/steno/-/steno-0.4.4.tgz" + integrity sha512-EEHMVYHNXFHfGtgjNITnka0aHhiAlo93F7z2/Pwd+g0teG9CnM3JIINM7hVVB5/rhw9voufD7Wukwgtw2uqh6w== + dependencies: + graceful-fs "^4.1.3" + stop-iteration-iterator@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/stop-iteration-iterator/-/stop-iteration-iterator-1.0.0.tgz" @@ -11379,7 +12431,12 @@ stop-iteration-iterator@^1.0.0: dependencies: internal-slot "^1.0.4" -string_decoder@^1.1.1: +stream-shift@^1.0.0: + version "1.0.1" + resolved "https://registry.npmjs.org/stream-shift/-/stream-shift-1.0.1.tgz" + integrity sha512-AiisoFqQ0vbGcZgQPY1cdP2I76glaVA/RauYR4G4thNFgkTqr90yXTo4LYX60Jl+sIlPNHHdGSwo01AvbKUSVQ== + +string_decoder@^1.1.1, string_decoder@^1.3.0: version "1.3.0" resolved "https://registry.npmjs.org/string_decoder/-/string_decoder-1.3.0.tgz" integrity sha512-hkRX8U1WjJFd8LsDJ2yQ/wWWxaopEsABU1XfkM8A+j0+85JAGppt16cr1Whg6KIbb4okU6Mql6BOj+uup/wKeA== @@ -11478,6 +12535,11 @@ strip-bom@^4.0.0: resolved "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz" integrity sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w== +strip-eof@^1.0.0: + version "1.0.0" + resolved "https://registry.npmjs.org/strip-eof/-/strip-eof-1.0.0.tgz" + integrity sha512-7FCwGGmx8mD5xQd3RPUvnSpUXHM3BWuzjtpD4TXsfcZ9EL4azvVVUscFYwD9nx8Kh+uCBC00XBtAykoMHwTh8Q== + strip-final-newline@^2.0.0: version "2.0.0" resolved "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz" @@ -11495,6 +12557,11 @@ strip-json-comments@^3.1.0, strip-json-comments@^3.1.1: resolved "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz" integrity sha512-6fPc+R4ihwqP6N/aIv2f1gMH8lOVtWQHoqC4yK6oSDVVocumAsfCqjkXnqiYMhmMwS/mEHLp7Vehlt3ql6lEig== +strip-outer@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/strip-outer/-/strip-outer-2.0.0.tgz" + integrity sha512-A21Xsm1XzUkK0qK1ZrytDUvqsQWict2Cykhvi0fBQntGG5JSprESasEyV1EZ/4CiR5WB5KjzLTrP/bO37B0wPg== + strong-log-transformer@^2.1.0: version "2.1.0" resolved "https://registry.npmjs.org/strong-log-transformer/-/strong-log-transformer-2.1.0.tgz" @@ -11504,6 +12571,14 @@ strong-log-transformer@^2.1.0: minimist "^1.2.0" through "^2.3.4" +strtok3@^7.0.0-alpha.9: + version "7.0.0" + resolved "https://registry.npmjs.org/strtok3/-/strtok3-7.0.0.tgz" + integrity sha512-pQ+V+nYQdC5H3Q7qBZAz/MO6lwGhoC2gOAjuouGf/VO0m7vQRh8QNMl2Uf6SwAtzZ9bOw3UIeBukEGNJl5dtXQ== + dependencies: + "@tokenizer/token" "^0.3.0" + peek-readable "^5.0.0" + style-inject@^0.3.0: version "0.3.0" resolved "https://registry.npmjs.org/style-inject/-/style-inject-0.3.0.tgz" @@ -11704,6 +12779,13 @@ text-table@^0.2.0, text-table@0.2.0: resolved "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz" integrity sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw== +thread-stream@^0.15.1: + version "0.15.2" + resolved "https://registry.npmjs.org/thread-stream/-/thread-stream-0.15.2.tgz" + integrity sha512-UkEhKIg2pD+fjkHQKyJO3yoIvAP3N6RlNFt2dUhcS1FGvCD1cQa1M/PGknCLFIyZdtJOWQjejp7bdNqmN7zwdA== + dependencies: + real-require "^0.1.0" + throttleit@^1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/throttleit/-/throttleit-1.0.0.tgz" @@ -11770,6 +12852,19 @@ toidentifier@1.0.1: resolved "https://registry.npmjs.org/toidentifier/-/toidentifier-1.0.1.tgz" integrity sha512-o5sSPKEkg/DIQNmH43V0/uerLrpzVedkUh8tGNvaeXpfpuwjKenlSox/2O/BTlZUtEe+JG7s5YhEz608PlAHRA== +token-types@^5.0.0-alpha.2: + version "5.0.1" + resolved "https://registry.npmjs.org/token-types/-/token-types-5.0.1.tgz" + integrity sha512-Y2fmSnZjQdDb9W4w4r1tswlMHylzWIeOKpx0aZH9BgGtACHhrk3OkT52AzwcuqTRBZtvvnTjDBh8eynMulu8Vg== + dependencies: + "@tokenizer/token" "^0.3.0" + ieee754 "^1.2.1" + +toposort@^2.0.2: + version "2.0.2" + resolved "https://registry.npmjs.org/toposort/-/toposort-2.0.2.tgz" + integrity sha512-0a5EOkAUp8D4moMi2W8ZF8jcga7BgZd91O/yabJCFY8az+XSzeGyTKs0Aoo897iV1Nj6guFq8orWDS96z91oGg== + tough-cookie@^4.1.2: version "4.1.2" resolved "https://registry.npmjs.org/tough-cookie/-/tough-cookie-4.1.2.tgz" @@ -11795,6 +12890,11 @@ tr46@^3.0.0: dependencies: punycode "^2.1.1" +tr46@~0.0.3: + version "0.0.3" + resolved "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz" + integrity sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw== + tree-kill@1.2.2: version "1.2.2" resolved "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz" @@ -11805,6 +12905,13 @@ trim-newlines@^3.0.0: resolved "https://registry.npmjs.org/trim-newlines/-/trim-newlines-3.0.1.tgz" integrity sha512-c1PTsA3tYrIsLGkJkzHF+w9F2EyxfXGo4UyJc4pFL++FMjnq0HJS69T3M7d//gKrFKwy429bouPescbjecU+Zw== +trim-repeated@^2.0.0: + version "2.0.0" + resolved "https://registry.npmjs.org/trim-repeated/-/trim-repeated-2.0.0.tgz" + integrity sha512-QUHBFTJGdOwmp0tbOG505xAgOp/YliZP/6UgafFXYZ26WT1bvQmSMJUvkeVSASuJJHbqsFbynTvkd5W8RBTipg== + dependencies: + escape-string-regexp "^5.0.0" + ts-action-operators@^9.1.1: version "9.1.2" resolved "https://registry.npmjs.org/ts-action-operators/-/ts-action-operators-9.1.2.tgz" @@ -11891,6 +12998,11 @@ tslib@2.5.3: resolved "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz" integrity sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w== +tsscmp@1.0.6: + version "1.0.6" + resolved "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz" + integrity sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA== + tsutils@^3.21.0: version "3.21.0" resolved "https://registry.npmjs.org/tsutils/-/tsutils-3.21.0.tgz" @@ -11919,6 +13031,11 @@ tweetnacl@^0.14.3, tweetnacl@~0.14.0: resolved "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz" integrity sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA== +typanion@^3.8.0: + version "3.14.0" + resolved "https://registry.npmjs.org/typanion/-/typanion-3.14.0.tgz" + integrity sha512-ZW/lVMRabETuYCd9O9ZvMhAh8GslSqaUjxmK/JLPCh6l73CvLBiuXswj/+7LdnWOgYsQ130FqLzFz5aGT4I3Ug== + type-check@^0.4.0: version "0.4.0" resolved "https://registry.npmjs.org/type-check/-/type-check-0.4.0.tgz" @@ -12062,6 +13179,11 @@ universalify@^2.0.0: resolved "https://registry.npmjs.org/universalify/-/universalify-2.0.0.tgz" integrity sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ== +unix-crypt-td-js@1.1.4: + version "1.1.4" + resolved "https://registry.npmjs.org/unix-crypt-td-js/-/unix-crypt-td-js-1.1.4.tgz" + integrity sha512-8rMeVYWSIyccIJscb9NdCfZKSRBKYTeVnwmiRYT2ulE3qd1RaDQ0xQDP+rI3ccIWbhu/zuo5cgN8z73belNZgw== + unpipe@~1.0.0, unpipe@1.0.0: version "1.0.0" resolved "https://registry.npmjs.org/unpipe/-/unpipe-1.0.0.tgz" @@ -12110,6 +13232,11 @@ utils-merge@1.0.1: resolved "https://registry.npmjs.org/utils-merge/-/utils-merge-1.0.1.tgz" integrity sha512-pMZTvIkT1d+TFGvDOqodOclx0QWkkgi6Tdoa8gC8ffGAAqz9pzPTZWAybbsHHoED/ztMtkv/VoYTYyShUn81hA== +uuid@^3.3.2: + version "3.4.0" + resolved "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz" + integrity sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A== + uuid@^8.3.2: version "8.3.2" resolved "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz" @@ -12149,11 +13276,90 @@ validate-npm-package-name@^5.0.0: dependencies: builtins "^5.0.0" -vary@~1.1.2: +validator@13.11.0: + version "13.11.0" + resolved "https://registry.npmjs.org/validator/-/validator-13.11.0.tgz" + integrity sha512-Ii+sehpSfZy+At5nPdnyMhx78fEoPDkR2XW/zimHEL3MyGJQOCQ7WeP20jPYRz7ZCpcKLB21NxuXHF3bxjStBQ== + +validator@13.9.0: + version "13.9.0" + resolved "https://registry.npmjs.org/validator/-/validator-13.9.0.tgz" + integrity sha512-B+dGG8U3fdtM0/aNK4/X8CXq/EcxU2WPrPEkJGslb47qyHsxmbggTWK0yEA4qnYVNF+nxNlN88o14hIcPmSIEA== + +vary@^1, vary@~1.1.2: version "1.1.2" resolved "https://registry.npmjs.org/vary/-/vary-1.1.2.tgz" integrity sha512-BNGbWLfd0eUPabhkXUVm0j8uuvREyTh5ovRa/dyow/BqAbZJyC+5fU+IzQOzmAKzYqYRAISoRhdQr3eIZ/PXqg== +verdaccio-audit@12.0.0-next.1: + version "12.0.0-next.1" + resolved "https://registry.npmjs.org/verdaccio-audit/-/verdaccio-audit-12.0.0-next.1.tgz" + integrity sha512-5TJflIvZNZ10Dx5oD/RETjK6xVV/Shm9JbtpFmIqOhwnwhfHBVw/vI+BM1zvGkXuXmgbXa9qrsG30DI/58sIfQ== + dependencies: + "@verdaccio/config" "7.0.0-next.1" + "@verdaccio/core" "7.0.0-next.1" + express "4.18.2" + https-proxy-agent "5.0.1" + node-fetch cjs + +verdaccio-htpasswd@12.0.0-next.1: + version "12.0.0-next.1" + resolved "https://registry.npmjs.org/verdaccio-htpasswd/-/verdaccio-htpasswd-12.0.0-next.1.tgz" + integrity sha512-NNjltevHBJnZo6pKyZqe2THXM3RAFRbrCcTimlVSNL23MbSlcBXvbM4w8MCLzyC5kVixE+i4+ha5diPQLGVN2A== + dependencies: + "@verdaccio/core" "7.0.0-next.1" + "@verdaccio/file-locking" "12.0.0-next.0" + apache-md5 "1.1.8" + bcryptjs "2.4.3" + core-js "3.30.2" + debug "4.3.4" + http-errors "2.0.0" + unix-crypt-td-js "1.1.4" + +verdaccio@^5.0.4: + version "5.26.2" + resolved "https://registry.npmjs.org/verdaccio/-/verdaccio-5.26.2.tgz" + integrity sha512-JWkjJn+m7WmIA8rEcJw3r/MVg6uFgOZKt6lX8/zveyHCjth+NCLMS7Zjt16dEWMKeSkTVRakifzBGv2IXipt5g== + dependencies: + "@verdaccio/config" "7.0.0-next.1" + "@verdaccio/core" "7.0.0-next.1" + "@verdaccio/local-storage" "10.3.3" + "@verdaccio/logger-7" "7.0.0-next.1" + "@verdaccio/middleware" "7.0.0-next.1" + "@verdaccio/search" "7.0.0-next.1" + "@verdaccio/signature" "7.0.0-next.0" + "@verdaccio/streams" "10.2.1" + "@verdaccio/tarball" "12.0.0-next.1" + "@verdaccio/ui-theme" "7.0.0-next.1" + "@verdaccio/url" "12.0.0-next.1" + "@verdaccio/utils" "7.0.0-next.1" + async "3.2.4" + clipanion "3.2.1" + compression "1.7.4" + cookies "0.8.0" + cors "2.8.5" + debug "^4.3.4" + envinfo "7.10.0" + express "4.18.2" + express-rate-limit "5.5.1" + fast-safe-stringify "2.1.1" + handlebars "4.7.7" + js-yaml "4.1.0" + JSONStream "1.3.5" + jsonwebtoken "9.0.1" + kleur "4.1.5" + lodash "4.17.21" + lru-cache "7.18.3" + mime "3.0.0" + mkdirp "1.0.4" + mv "2.1.1" + pkginfo "0.4.1" + request "2.88.2" + semver "7.5.4" + validator "13.11.0" + verdaccio-audit "12.0.0-next.1" + verdaccio-htpasswd "12.0.0-next.1" + verror@1.10.0: version "1.10.0" resolved "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz" @@ -12210,6 +13416,11 @@ wcwidth@^1.0.1: dependencies: defaults "^1.0.3" +webidl-conversions@^3.0.0: + version "3.0.1" + resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz" + integrity sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ== + webidl-conversions@^7.0.0: version "7.0.0" resolved "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-7.0.0.tgz" @@ -12400,6 +13611,14 @@ whatwg-url@^11.0.0: tr46 "^3.0.0" webidl-conversions "^7.0.0" +whatwg-url@^5.0.0: + version "5.0.0" + resolved "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz" + integrity sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw== + dependencies: + tr46 "~0.0.3" + webidl-conversions "^3.0.0" + which-boxed-primitive@^1.0.2: version "1.0.2" resolved "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz" @@ -12433,6 +13652,13 @@ which-typed-array@^1.1.9: has-tostringtag "^1.0.0" is-typed-array "^1.1.10" +which@^1.2.9: + version "1.3.1" + resolved "https://registry.npmjs.org/which/-/which-1.3.1.tgz" + integrity sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ== + dependencies: + isexe "^2.0.0" + which@^2.0.1: version "2.0.2" resolved "https://registry.npmjs.org/which/-/which-2.0.2.tgz" @@ -12557,6 +13783,11 @@ y18n@^5.0.5: resolved "https://registry.npmjs.org/y18n/-/y18n-5.0.8.tgz" integrity sha512-0pfFzegeDWJHJIAmTLRP2DwHjdF5s7jo9tuztdQxAhINCdvS+3nGINqPd00AphqJR/0LhANUS6/+7SCb98YOfA== +yallist@^2.1.2: + version "2.1.2" + resolved "https://registry.npmjs.org/yallist/-/yallist-2.1.2.tgz" + integrity sha512-ncTzHV7NvsQZkYe1DW7cbDLm0YpzHmZF5r/iyP3ZnQtMiJ+pjzisCiMNI+Sj+xQF5pXhSHxSB3uDbsBTzY/c2A== + yallist@^3.0.2: version "3.1.1" resolved "https://registry.npmjs.org/yallist/-/yallist-3.1.1.tgz" @@ -12631,6 +13862,19 @@ yocto-queue@^0.1.0: resolved "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz" integrity sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q== +yup@0.32.11: + version "0.32.11" + resolved "https://registry.npmjs.org/yup/-/yup-0.32.11.tgz" + integrity sha512-Z2Fe1bn+eLstG8DRR6FTavGD+MeAwyfmouhHsIUgaADz8jvFKbO/fXc2trJKZg+5EBjh4gGm3iU/t3onKlXHIg== + dependencies: + "@babel/runtime" "^7.15.4" + "@types/lodash" "^4.14.175" + lodash "^4.17.21" + lodash-es "^4.17.21" + nanoclone "^0.2.1" + property-expr "^2.0.4" + toposort "^2.0.2" + zone.js@0.13.0: version "0.13.0" resolved "https://registry.npmjs.org/zone.js/-/zone.js-0.13.0.tgz"