Press n or j to go to the next uncovered block, b, p or k for the previous block.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 | 1x 1x 1x 1x 78x 78x 78x 2098x 2098x 2098x 78x 1x 130x 130x 130x 130x 3770x 3770x 3770x 116x 3764x 3764x 145x 78x 2176x 2176x 2176x 117x 117x 163x 163x 117x 117x 45x 72x 6x | import Ajv from 'ajv/lib/ajv'; import pagedClient from './client'; import schema from './schema'; import handlers from './handlers'; import { Assets, AssetTypes, Auth0APIClient, BaseAuth0APIClient } from '../../types'; import APIHandler from './handlers/default'; import { ConfigFunction } from '../../configFactory'; export type Stage = 'load' | 'validate' | 'processChanges'; type StageFunction = APIHandler['load']; // Using `load` method as a template for what type stage functions resemble function sortByOrder(toSort: APIHandler[], stage: Stage): APIHandler[] { const defaultOrder = 50; const sorted = [...toSort]; sorted.sort((a, b) => { //@ts-ignore because this doesn't actually work. TODO: apply stage order const aOrder = a[stage].order || defaultOrder; //@ts-ignore because this doesn't actually work. TODO: apply stage order const bOrder = b[stage].order || defaultOrder; return aOrder - bOrder; }); return sorted; } export default class Auth0 { client: Auth0APIClient; config: ConfigFunction; assets: Assets; handlers: APIHandler[]; constructor(client: BaseAuth0APIClient, assets: Assets, config: ConfigFunction) { this.client = pagedClient(client); this.config = config; this.assets = assets; this.handlers = Object.values(handlers) .map((handler) => { //@ts-ignore because class expects `type` property but gets directly injected into class constructors return new handler.default({ client: this.client, config: this.config }); }) .filter((handler) => { const excludedAssetTypes: undefined | AssetTypes[] = config('AUTH0_EXCLUDED'); if (excludedAssetTypes === undefined) return true; return !excludedAssetTypes.includes(handler.type as AssetTypes); }) .filter((handler) => { const onlyIncludedAssetTypes: undefined | AssetTypes[] = config('AUTH0_INCLUDED_ONLY'); if (onlyIncludedAssetTypes === undefined) return true; return onlyIncludedAssetTypes.includes(handler.type as AssetTypes); }); } async runStage(stage: Stage): Promise<void> { // Sort by priority for (const handler of sortByOrder(this.handlers, stage)) { // eslint-disable-line try { const stageFn: StageFunction = Object.getPrototypeOf(handler)[stage]; this.assets = { ...this.assets, ...((await stageFn.apply(handler, [this.assets])) || {}), }; } catch (err) { err.type = handler.type; err.stage = stage; throw err; } } } async validate(): Promise<void> { const ajv = new Ajv({ useDefaults: true, nullable: true }); const nonNullAssets = Object.keys(this.assets) .filter((k) => this.assets[k] != null) .reduce((a, k) => ({ ...a, [k]: this.assets[k] }), {}); const valid = ajv.validate(schema, nonNullAssets); if (!valid) { throw new Error(`Schema validation failed loading ${JSON.stringify(ajv.errors, null, 4)}`); } await this.runStage('validate'); } async loadAssetsFromAuth0(): Promise<void> { // Populate assets from auth0 tenant await this.runStage('load'); } async processChanges(): Promise<void> { await this.runStage('processChanges'); } } |