@datawheel/bespoke 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +19 -0
- package/dist/Viz-41329377.js +368 -0
- package/dist/Viz-41329377.js.map +1 -0
- package/dist/Viz-ef983f01.js +368 -0
- package/dist/Viz-ef983f01.js.map +1 -0
- package/dist/index-9c337b90.js +6680 -0
- package/dist/index-9c337b90.js.map +1 -0
- package/dist/index-cf73f4fa.js +6680 -0
- package/dist/index-cf73f4fa.js.map +1 -0
- package/dist/index.js +53 -0
- package/dist/index.js.map +1 -0
- package/dist/server.js +2944 -0
- package/dist/server.js.map +1 -0
- package/dist/style.css +765 -0
- package/package.json +125 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"server.js","sources":["../libs/configs/getLogging.ts","../db/models/block.ts","../db/models/block_content.ts","../db/models/block_input.ts","../libs/stats.js","../libs/libs.ts","../types/cms.ts","../libs/formatters/abbreviate.js","../libs/formatters/abs.js","../libs/formatters/bucket.js","../libs/formatters/commas.js","../libs/formatters/date.js","../libs/formatters/dollar.js","../libs/formatters/formatFieldName.js","../libs/formatters/grewTo.js","../libs/formatters/grewWord.js","../libs/formatters/growing.js","../libs/formatters/growth.js","../libs/formatters/growthPct.js","../libs/formatters/growthWord.js","../libs/formatters/highWord.js","../libs/formatters/increaseWord.js","../libs/formatters/increasedWord.js","../libs/formatters/increasing.js","../libs/formatters/largerThan.js","../libs/formatters/list.js","../libs/formatters/longWord.js","../libs/formatters/lowerCaseFirst.js","../libs/formatters/moreFewerWord.js","../libs/formatters/moreLess.js","../libs/formatters/moreWord.js","../libs/formatters/olderWord.js","../libs/formatters/olderYounger.js","../libs/formatters/plural.js","../libs/formatters/pxToInt.js","../libs/formatters/salary.js","../libs/formatters/stripEntities.js","../libs/formatters/stripHTML.js","../libs/formatters/stripOL.js","../libs/formatters/stripP.js","../libs/formatters/stripUL.js","../libs/formatters/toKebabCase.js","../libs/formatters/toSpacedCase.js","../libs/formatters/upperCaseFirst.js","../db/models/formatter.ts","../db/models/image.ts","../db/models/image_content.ts","../db/models/report.ts","../db/models/report_dimension.ts","../db/models/report_dimension_variant.ts","../db/models/search.ts","../db/models/search_content.ts","../db/models/section.ts","../db/models/index.ts","../db/index.ts","../api/lib.ts","../libs/configs/getLocales.ts","../libs/js/arrayUtils.ts","../libs/js/stripHTML.ts","../libs/js/stripEntities.ts","../libs/js/slugify.ts","../api/db/member/ingestMembers.ts","../api/db/member/readMember.ts","../api/db/member/readMemberImage.ts","../search/index.ts","../api/db/member/searchMember.ts","../api/db/member/updateMember.ts","../api/db/member/index.ts","../api/db/include.ts","../api/db/entityCRUD/block.ts","../api/db/entityCRUD/dimension.ts","../api/db/entityCRUD/formatter.ts","../api/db/entityCRUD/report.ts","../api/db/entityCRUD/section.ts","../api/db/entityCRUD/variant.ts","../api/db/entityCRUD/index.ts","../api/db/image/helpers/uploadImage.ts","../api/db/image/providers/flickr.ts","../api/endpoints/lib.ts","../api/endpoints/member.ts","../api/db/image/providers/local.ts","../api/db/image/providers/unsplash.ts","../api/db/image/providers/upload.ts","../api/db/image/imageSave.ts","../api/db/image/imageSearch.ts","../api/db/readMetadata.ts","../api/db/regenerateSearch.ts","../api/db/searchReport.ts","../api/db/urlProxy.ts","../api/db/index.ts","../api/helpers/parseBody.ts","../api/endpoints/entityCRUD.ts","../api/endpoints/image/imageSave.ts","../api/endpoints/image/imageSearch.ts","../api/endpoints/readMetadata.ts","../api/endpoints/regenerateSearch.ts","../api/endpoints/searchReport.ts","../api/endpoints/urlProxy.ts","../api/endpoints/index.ts","../cms/crosswalk/index.ts"],"sourcesContent":["import yn from \"yn\";\n\nexport default (env = process.env) => yn(env.REPORTS_LOGGING);\n","import {\n DataTypes, ForeignKey, Model, Sequelize,\n} from \"sequelize\";\nimport type {ReportsDB} from \".\";\nimport type {AnyNestedBlock, BlockType, LocaleContent} from \"../../models/block\";\nimport type {BlockContentModel} from \"./block_content\";\nimport type {BlockInputAttributes} from \"./block_input\";\n\nexport interface BlockAttributes {\n id: number;\n section_id: ForeignKey<number>;\n block_input?: BlockInputAttributes;\n blockcol: string;\n blockrow: string;\n settings: Record<string, unknown>;\n shared: boolean;\n type: string;\n}\n\nexport interface BlockAssociations {\n contentByLocale: LocaleContent[];\n inputs: (BlockAttributes & BlockAssociations)[];\n consumers: (BlockAttributes & BlockAssociations)[];\n}\n\nexport interface BlockCreationAttributes {\n blockcol: string;\n blockrow: string;\n section_id: number;\n type: BlockType;\n contentByLocale: {\n locale: string;\n }[];\n inputs?: BlockCreationAttributes[];\n consumers?: BlockCreationAttributes[];\n}\n\nexport class BlockModel\n extends Model<BlockAttributes, BlockCreationAttributes> {\n declare id: number;\n\n declare section_id: number;\n\n declare block_input?: BlockInputAttributes;\n\n declare contentByLocale: BlockContentModel[];\n\n declare inputs: BlockModel[];\n\n declare consumers: BlockModel[];\n\n getContent(locale: string) {\n const content = this.contentByLocale.find((item) => item.locale === locale);\n if (!content) {\n throw new Error(`Missing SearchContent for locale '${locale}' on Search ID '${this.id}'`);\n }\n return content;\n }\n\n toJSON(): AnyNestedBlock {\n const attributes = this.get({plain: true});\n delete attributes.block_input;\n\n const {inputs = [], consumers = [], contentByLocale = []} = this;\n return {\n ...attributes,\n inputs: inputs.map((item) => item.toJSON()),\n consumers: consumers.map((item) => item.toJSON()),\n contentByLocale: Object.fromEntries(\n contentByLocale.map((content) => [content.locale, content.toJSON()]),\n ),\n } as AnyNestedBlock;\n }\n}\n\nfunction initModel(sequelize: Sequelize) {\n BlockModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n autoIncrement: true,\n },\n\n /* block metadata */\n settings: {\n type: DataTypes.JSON,\n defaultValue: {},\n },\n type: {\n type: DataTypes.STRING,\n defaultValue: \"paragraph\", // BLOCK_TYPES.PARAGRAPH\n },\n shared: {\n type: DataTypes.BOOLEAN,\n defaultValue: false,\n },\n\n blockrow: DataTypes.STRING,\n blockcol: DataTypes.STRING,\n\n /* relations */\n section_id: {\n type: DataTypes.INTEGER,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_section\",\n key: \"id\",\n },\n },\n }, {\n sequelize,\n modelName: \"block\",\n tableName: \"bespoke_reports_block\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return (models: ReportsDB) => {\n BlockModel.hasMany(models.block_content, {foreignKey: \"id\", sourceKey: \"id\", as: \"contentByLocale\"});\n // Blocks that provide info to this\n BlockModel.belongsToMany(models.block, {\n through: \"block_input\", foreignKey: \"block_id\", otherKey: \"input_id\", as: \"inputs\",\n });\n // Blocks this provides info to\n BlockModel.belongsToMany(models.block, {\n through: \"block_input\", foreignKey: \"input_id\", otherKey: \"block_id\", as: \"consumers\",\n });\n\n return BlockModel;\n };\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\nimport {LocaleContent} from \"../../models/block\";\n\ninterface BlockContentCreationAttributes {\n locale: LocaleContent[\"locale\"];\n}\n\nexport class BlockContentModel\n extends Model<LocaleContent, BlockContentCreationAttributes> {\n id: number;\n locale: LocaleContent[\"locale\"];\n content: LocaleContent[\"content\"];\n}\n\nfunction initModel(sequelize: Sequelize) {\n BlockContentModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_block\",\n key: \"id\",\n },\n },\n locale: {\n type: DataTypes.STRING,\n primaryKey: true,\n },\n content: {\n type: DataTypes.JSON,\n defaultValue: {},\n },\n }, {\n sequelize,\n modelName: \"block_content\",\n tableName: \"bespoke_reports_block_content\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return () => BlockContentModel;\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\n\nexport interface BlockInputAttributes {\n id: number;\n block_id: number;\n input_id: number;\n}\n\nexport interface BlockInputCreationAttributes {\n block_id: number;\n input_id: number;\n}\n\n// eslint-disable-next-line @typescript-eslint/no-empty-interface\nexport class BlockInputModel\n extends Model<BlockInputAttributes, BlockInputCreationAttributes> {\n id: number;\n block_id: number;\n input_id: number;\n}\n\nfunction initModel(sequelize: Sequelize) {\n BlockInputModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n autoIncrement: true,\n },\n block_id: {\n type: DataTypes.INTEGER,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_block\",\n key: \"id\",\n },\n },\n input_id: {\n type: DataTypes.INTEGER,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_block\",\n key: \"id\",\n },\n },\n }, {\n sequelize,\n modelName: \"block_input\",\n tableName: \"bespoke_reports_block_input\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return () => BlockInputModel;\n}\n\nexport default initModel\n","// adapted from http://www.math.ucla.edu/~tom/distributions/binomial.html\n/** */\nfunction logGamma(Z) {\n const S = 1 + 76.18009173 / Z - 86.50532033 / (Z + 1) + 24.01409822 / (Z + 2) - 1.231739516 / (Z + 3) + 0.00120858003 / (Z + 4) - 0.00000536382 / (Z + 5);\n return (Z - 0.5) * Math.log(Z + 4.5) - (Z + 4.5) + Math.log(S * 2.50662827465);\n}\n\n/** */\nfunction betinc(X, A, B) {\n let A0 = 0;\n let B0 = 1;\n let A1 = 1;\n let B1 = 1;\n let M9 = 0;\n let A2 = 0;\n let C9;\n while (Math.abs((A1 - A2) / A1) > 0.00001) {\n A2 = A1;\n C9 = -(A + M9) * (A + B + M9) * X / (A + 2 * M9) / (A + 2 * M9 + 1);\n A0 = A1 + C9 * A0;\n B0 = B1 + C9 * B0;\n M9 += 1;\n C9 = M9 * (B - M9) * X / (A + 2 * M9 - 1) / (A + 2 * M9);\n A1 = A0 + C9 * A1;\n B1 = B0 + C9 * B1;\n A0 /= B1;\n B0 /= B1;\n A1 /= B1;\n B1 = 1;\n }\n return A1 / A;\n}\n\n/** */\nfunction binomialCdf(X, N, P) {\n let betacdf; let\n bincdf;\n if (X < 0) bincdf = 0;\n else if (X >= N) bincdf = 1;\n else {\n X = Math.floor(X);\n const Z = P;\n const A = X + 1;\n const B = N - X;\n const S = A + B;\n const BT = Math.exp(logGamma(S) - logGamma(B) - logGamma(A) + A * Math.log(Z) + B * Math.log(1 - Z));\n if (Z < (A + 1) / (S + 2)) {\n betacdf = BT * betinc(Z, A, B);\n } else {\n betacdf = 1 - BT * betinc(1 - Z, B, A);\n }\n bincdf = 1 - betacdf;\n }\n return Math.round(bincdf * 100000) / 100000;\n}\n\n/**\nCompute mid-p confidence interval around single ratio\nCredit to @JogoShugh\nSourced from: https://github.com/JogoShugh/OpenEpi.com/blob/8c90dc075c6a9b8e2a8de8ff26d7cd0b1987762a/OpenEpi/Proportion/Proportion.js\n*/\n\n/**\n *\n */\nfunction criticalValue(confLevel) {\n // Returns z value for various levels of confidence and 1 degree\n // of freedom. OEConfLevel must be expressed as\n // a string with two digits, then two optional digits, without a % sign.\n const critMap = {\n 0.99999: 15.137,\n 0.99: 6.635,\n 0.95: 3.841,\n 0.9: 2.706,\n };\n // TODO: check if confLevel in critMap\n return critMap[confLevel];\n}\n\n/**\n *\n */\nfunction binP(N, p, x1, x2) {\n const q = p / (1 - p);\n let k = 0;\n let v = 1;\n let s = 0;\n let tot = 0;\n while (k <= N) {\n tot += v;\n if (k >= x1 & k <= x2) {\n s += v;\n }\n if (tot > 1e30) {\n s /= 1e30;\n tot /= 1e30;\n v /= 1e30;\n }\n k += 1;\n v = v * q * (N + 1 - k) / k;\n }\n return s / tot;\n}\n\n/**\n *\n */\nfunction computeMidP(vx, vN, confLevel) {\n // TODO check vx and vN are >= 0\n // TODO check vx not larger than n\n const vP = vx / vN;\n // const npq = vN * vP * (1 - vP);\n // const crit = criticalValue(confLevel);\n // const zL = Math.sqrt(crit);\n // const zSquare = Math.pow(zL, 2);\n const prob = confLevel * 100;\n const vTL = (100 - prob) / 2;\n\n let T1; let\n T2;\n if (vx === 0) {\n T1 = 0;\n } else {\n let v = vP / 2;\n let vsL = 0;\n let vsH = vP;\n const p = vTL / 100;\n while (vsH - vsL > 1e-5) {\n if (binP(vN, v, vx, vx) * 0.5 + binP(vN, v, vx + 1, vN) > p) {\n vsH = v;\n v = (vsL + v) / 2;\n } else {\n vsL = v;\n v = (vsH + v) / 2;\n }\n }\n T1 = v;\n }\n if (vx === vN) {\n T2 = 0;\n } else {\n let v = (1 + vP) / 2;\n let vsL = vP;\n let vsH = 1;\n const p = vTL / 100;\n while (vsH - vsL > 1e-5) {\n if (binP(vN, v, vx, vx) * 0.5 + binP(vN, v, 0, vx - 1) < p) {\n vsH = v;\n v = (vsL + v) / 2;\n } else {\n vsL = v;\n v = (vsH + v) / 2;\n }\n }\n T2 = v;\n }\n\n return {lci: T1, uci: T2};\n}\n\n/**\n * Adapted from JogoShugh's SMR https://github.com/JogoShugh/OpenEpi.com/blob/master/OpenEpi/SMR/SMR.js\n * @param {*} observedVal\n * @param {*} expectedVal\n */\nfunction smr(observedVal, expectedVal) {\n /* Calculates standard morbidity ratio given observed and expected values */\n const vx = observedVal;\n const vN = expectedVal;\n\n // Fisher's exact test for poisson distribution ;\n const Obs = vx;\n const Exp = vN;\n\n const ci = 95; // currently hard-wired to 95% CI\n\n // Mid-P exact test;\n // Lower tail;\n let v = 0.5;\n let dv = 0.5;\n const vTL = (100 - ci) / 2;\n let p = vTL / 100;\n\n const vZ = Obs;\n while (dv > 1e-5) {\n dv /= 2; if (poisP((1 + vZ) * v / (1 - v), vZ + 1, 1e10) + 0.5 * poisP((1 + vZ) * v / (1 - v), vZ, vZ) > p) {\n v -= dv;\n } else {\n v += dv;\n }\n }\n\n const QL = (1 + vZ) * v / (1 - v) / Exp;\n\n // Upper tail;\n v = 0.5;\n dv = 0.5;\n const vTU = (100 - ci) / 2;\n p = vTU / 100;\n\n while (dv > 1e-5) {\n dv /= 2; if (poisP((1 + vZ) * v / (1 - v), 0, vZ - 1) + 0.5 * poisP((1 + vZ) * v / (1 - v), vZ, vZ) < p) {\n v -= dv;\n } else {\n v += dv;\n }\n }\n const QU = (1 + vZ) * v / (1 - v) / Exp;\n return {lci: QL, uci: QU};\n}\n\n/**\n * Poisson iteration;\n * @param {*} Z\n * @param {*} x1\n * @param {*} x2\n */\nfunction poisP(Z, x1, x2) {\n let q = 1; let tot = 0; let s = 0; let k = 0;\n while (k < Z || q > tot * 1e-10) {\n tot += q;\n if (k >= x1 & k <= x2) {\n s += q;\n }\n if (tot > 1e30) {\n s /= 1e30; tot /= 1e30; q /= 1e30;\n }\n k += 1; q = q * Z / k;\n }\n return s / tot;\n}\n\nexport default {\n binomialCdf,\n binP,\n computeMidP,\n criticalValue,\n smr,\n};\n","import * as d3Array from \"d3-array\";\nimport * as d3Collection from \"d3-collection\";\nimport * as d3Format from \"d3-format\";\nimport * as d3TimeFormat from \"d3-time-format\";\nimport {formatAbbreviate} from \"d3plus-format\";\nimport {date} from \"d3plus-axis\";\nimport {assign, closest, merge} from \"d3plus-common\";\nimport {strip, titleCase} from \"d3plus-text\";\nimport stats from \"./stats\";\n\nexport const libs = {\n d3: {\n ...d3Array, ...d3Collection, ...d3Format, ...d3TimeFormat,\n },\n d3plus: {\n assign, closest, date, formatAbbreviate, merge, strip, titleCase,\n },\n stats,\n} as const;\n\nexport type EnvLibs = typeof libs;\n\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\ntype FormatterFn = (...args: any[]) => any;\n\ninterface FormatterManifest {\n name: string;\n description: string;\n logicFactory: (libs: EnvLibs) => FormatterFn;\n inputType: \"string\" | \"number\" | \"object\" | \"date\";\n testValue: string;\n type: \"formatter\" | \"function\";\n}\n\ninterface FormatterContent {\n description: string;\n inputType: string;\n logic: string;\n testValue: string;\n type: string;\n [key: string]: string;\n}\n\nexport const declaredFormatters: Record<string, FormatterContent> = {};\n\nexport function declareFormatter(manifest: FormatterManifest) {\n const func = manifest.logicFactory(libs);\n declaredFormatters[manifest.name] = {\n description: manifest.description,\n inputType: manifest.inputType,\n logic: stringifyFn(func),\n testValue: manifest.testValue,\n type: manifest.type || \"formatter\",\n };\n return func;\n}\n\n// eslint-disable-next-line @typescript-eslint/ban-types\nfunction stringifyFn(func: Function): string {\n const strFunc = func.toString().trim();\n if (strFunc.startsWith(\"function\")) {\n return strFunc\n .replace(/^function(?:\\s\\w+)?\\([^\\)]\\)/, \"\")\n .trim()\n .replace(/^{([\\s\\S]+)\\}$/, \"$1\");\n }\n const noArgs = strFunc.replace(/^.+?=>/, \"\").trim();\n return noArgs.startsWith(\"{\")\n ? noArgs.replace(/^{([\\s\\S]+)\\}$/, \"$1\")\n : `return ${noArgs}`;\n}\n\nexport default libs;\n","/**\n * Top-level entity types - every \"entity\" in the CMS is one of these,\n * and has CRUD operations accordingly.\n */\nexport const ENTITY_TYPES = {\n REPORT: \"report\",\n SECTION: \"section\",\n BLOCK: \"block\",\n INPUT: \"block_input\",\n FORMATTER: \"formatter\",\n DIMENSION: \"report_dimension\",\n VARIANT: \"report_dimension_variant\",\n SEARCH: \"search\",\n};\n\nexport const CONTENT_TYPES = [ENTITY_TYPES.BLOCK, ENTITY_TYPES.SEARCH];\n\n/**\n * For each ENTITY_TYPE, store a pretty name for window titles, etc.\n */\nexport const ENTITY_PRETTY_NAMES = {\n report: \"Report\",\n section: \"Section\",\n block: \"Block\",\n block_input: \"Input\",\n formatter: \"Formatter\",\n dimension: \"Dimension\",\n variant: \"Variant\",\n search: \"Search\",\n};\n\nexport const ENTITY_PARENT_REFS = {\n [ENTITY_TYPES.SECTION]: \"report_id\",\n [ENTITY_TYPES.DIMENSION]: \"report_id\",\n [ENTITY_TYPES.VARIANT]: \"dimension_id\",\n [ENTITY_TYPES.BLOCK]: \"section_id\",\n [ENTITY_TYPES.INPUT]: \"block_id\",\n};\n\n/**\n * Reports and stories are nearly identical, but stories have a\n * publish date, and support for footnotes / authors\n */\nexport const REPORT_TYPES = {\n REPORT: \"report\",\n STORY: \"story\",\n};\n\n/**\n * Report mode is a simplification of dimension.length === 1 ? 'uni':'multi'\n */\nexport const REPORT_MODES = {\n UNILATERAL: \"uni\",\n MULTILATERAL: \"multi\",\n};\n\n/**\n * Selectors have two types, single and multi\n */\nexport const SELECTOR_TYPES = {\n SINGLE: \"single\",\n MULTI: \"multi\",\n};\n\n/**\n * NOTE ON FIELDS, MAPS, AND SETTINGS\n * Many elements of the CMS are stored as JSON blobs in the database, to allow\n * easy addition of new or custom keys without a database migration. However, the\n * standard keys for any given entity or settings element are contained here.\n * FIELDS - all available fields for a given entity, regardless of type\n * MAP - what subset of those fields belong to which type of that entity\n * SETTINGS - a list of settings keys expected in the settings object\n */\n\nexport const REPORT_FIELDS = {\n TITLE: \"title\",\n SUBTITLE: \"subtitle\",\n LABEL: \"label\",\n};\n\nexport const REPORT_MAP = {\n [REPORT_TYPES.REPORT]: Object.values(REPORT_FIELDS),\n [REPORT_TYPES.STORY]: Object.values(REPORT_FIELDS),\n};\n\nexport const ALLOWED = {\n ALLOWED: \"allowed\",\n ALLOWED_LOGIC: \"allowedLogic\",\n};\n\nexport const VIZ_SETTINGS = {\n VIZ_SETTINGS_LOGIC: \"vizSettingsLogic\",\n};\n\nexport const REPORT_SETTINGS = {\n ...ALLOWED,\n};\n\nexport const SECTION_FIELDS = {\n TITLE: \"title\",\n SHORT: \"short\",\n};\n\nexport const SECTION_SETTINGS = {\n POSITION: \"position\",\n ICON: \"icon\",\n ...ALLOWED,\n};\n\nexport const BLOCK_CONTENT_TYPES = {\n // AUTHOR: \"author\",\n // FOOTNOTE: \"footnote\",\n IMAGE: \"image\",\n PARAGRAPH: \"paragraph\",\n SELECTOR: \"selector\", // todo1.0 - move to logic types\n STAT: \"stat\",\n SUBTITLE: \"subtitle\",\n TITLE: \"title\",\n // todo1.0, how to put custom blocks in here?\n};\n\nexport const BLOCK_LOGIC_TYPES = {\n GENERATOR: \"generator\",\n VIZ: \"visualization\",\n};\n\nexport const BLOCK_LOGIC_LOCALE = \"logic\";\n\nexport const BLOCK_TYPES = {...BLOCK_CONTENT_TYPES, ...BLOCK_LOGIC_TYPES};\n\n// Types that shouldn't update on keystroke -- only after the user presses execute.\nexport const BLOCK_EXECUTE_TYPES = [\n BLOCK_TYPES.GENERATOR,\n BLOCK_TYPES.SELECTOR,\n BLOCK_TYPES.VIZ,\n BLOCK_TYPES.IMAGE,\n];\n\nexport const BLOCK_FIELDS = {\n ALT: \"alt\",\n AUTHOR: \"author\",\n FOOTNOTE: \"footnote\",\n BIO: \"bio\",\n IMAGE: \"image\",\n LOGIC: \"logic\",\n SIMPLE: \"simple\",\n SIMPLE_ENABLED: \"simpleEnabled\",\n PARAGRAPH: \"paragraph\",\n SELECTOR_DEFAULT: \"selectorDefault\",\n SELECTOR_DYNAMIC: \"selectorDynamic\",\n SELECTOR_NAME: \"selectorName\",\n SELECTOR_TYPE: \"selectorType\",\n SRC: \"src\",\n SLUG: \"slug\",\n SUBTITLE: \"subtitle\",\n TITLE: \"title\",\n TOOLTIP: \"tooltip\",\n TWITTER: \"twitter\",\n VALUE: \"value\",\n};\n\n/**\n * When exporting content variables for use by other blocks, skip over the following fields\n */\nexport const BLOCK_FIELDS_EXCLUDE = [\n BLOCK_FIELDS.LOGIC,\n BLOCK_FIELDS.SIMPLE,\n BLOCK_FIELDS.SIMPLE_ENABLED,\n];\n\nexport const BLOCK_MAP = {\n /*\n [BLOCK_TYPES.AUTHOR]: [\n BLOCK_FIELDS.AUTHOR,\n BLOCK_FIELDS.BIO,\n BLOCK_FIELDS.IMAGE,\n BLOCK_FIELDS.TITLE,\n ],\n [BLOCK_TYPES.FOOTNOTE]: [\n BLOCK_FIELDS.FOOTNOTE,\n ],\n */\n [BLOCK_TYPES.IMAGE]: [\n BLOCK_FIELDS.SRC,\n BLOCK_FIELDS.ALT,\n ],\n [BLOCK_TYPES.PARAGRAPH]: [\n BLOCK_TYPES.PARAGRAPH,\n BLOCK_FIELDS.TOOLTIP,\n ],\n [BLOCK_TYPES.SELECTOR]: [\n BLOCK_FIELDS.SELECTOR_DEFAULT,\n BLOCK_FIELDS.SELECTOR_DYNAMIC,\n BLOCK_FIELDS.SELECTOR_NAME,\n BLOCK_FIELDS.SELECTOR_TYPE,\n ],\n [BLOCK_TYPES.STAT]: [\n BLOCK_FIELDS.TITLE,\n BLOCK_FIELDS.SUBTITLE,\n BLOCK_FIELDS.VALUE,\n BLOCK_FIELDS.TOOLTIP,\n ],\n [BLOCK_TYPES.SUBTITLE]: [\n BLOCK_FIELDS.SUBTITLE,\n BLOCK_FIELDS.TOOLTIP,\n ],\n [BLOCK_TYPES.TITLE]: [\n BLOCK_FIELDS.TITLE,\n BLOCK_FIELDS.SLUG,\n BLOCK_FIELDS.TOOLTIP,\n ],\n [BLOCK_TYPES.GENERATOR]: [],\n [BLOCK_TYPES.VIZ]: [],\n};\n\n/*\nObject.keys(BLOCK_MAP).forEach(k => {\n BLOCK_MAP[k] = BLOCK_MAP[k].concat([\n BLOCK_FIELDS.LOGIC,\n BLOCK_FIELDS.LOGIC_ENABLED,\n BLOCK_FIELDS.LOGIC_SIMPLE,\n BLOCK_FIELDS.LOGIC_SIMPLE_ENABLED\n ]);\n});\n*/\n\nexport const BLOCK_SETTINGS = {\n NAME: \"name\",\n DESCRIPTION: \"description\",\n ...ALLOWED,\n};\n\n/**\n * Reports could have several dimensions:\n * - One dimension only is the default and is called UNILATERAL.\n * - More than one dimension is called MULTILATERAL.\n */\nexport const REPORT_MEMBER_TYPES = {\n UNILATERAL: \"uni\",\n MULTILATERAL: \"multi\",\n};\n\n/**\n * Formatter types\n * - \"formatter\" for a regular small thing to calculate or decorate some results\n * - \"function\" for bigger and global functions we want to use\n */\nexport const FORMATTER_TYPES = {\n FORMATTER: \"formatter\",\n FUNCTION: \"function\"\n};\nexport const FORMATTER_TYPES_NAMES = {\n [FORMATTER_TYPES.FORMATTER]: \"Formatter\",\n [FORMATTER_TYPES.FUNCTION]: \"Function\",\n};\n\n/**\n * Input type for formatter functions help us parse, call and test\n */\nexport const FORMATTER_INPUT_TYPES = {\n STRING: \"string\",\n NUMBER: \"number\",\n OBJECT: \"object\",\n DATE: \"date\",\n};\nexport const FORMATTER_INPUT_TYPES_NAMES = {\n [FORMATTER_INPUT_TYPES.STRING]: \"String\",\n [FORMATTER_INPUT_TYPES.NUMBER]: \"Number\",\n [FORMATTER_INPUT_TYPES.OBJECT]: \"Object/Array\",\n [FORMATTER_INPUT_TYPES.DATE]: \"Date\",\n};","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"abbreviate\",\n description: \"Abbreviates a number into a smaller more human-readable number.\",\n logicFactory(libs) {\n /**\n * @link https://github.com/d3plus/d3plus-format/blob/master/src/abbreviate.js#L44\n * @param {number} n 123456\n */\n return (n) => libs.d3plus.formatAbbreviate(n);\n },\n inputType: \"number\",\n testValue: \"123456\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"abs\",\n description: \"Simple Absolute Value.\",\n logicFactory(libs) {\n /**\n * @param {number} n -123\n */\n return (n) => Math.abs(n);\n },\n inputType: \"number\",\n testValue: \"-123\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\n/**\n * Sanitizes bucket strings to \"< n\", \"n1 - n2\", and \"n+\"\n * @param {number} n 1234\n */\nconst logicFactory = () => function bucket(n) {\n // eslint-disable-next-line prefer-regex-literals, no-useless-escape\n const re = new RegExp(/([\\$0-9\\,]+)[A-z\\-\\s\\&]*([\\$0-9\\,]*)/g);\n let nums = re.exec(n);\n if (nums) {\n nums = nums.slice(1)\n .filter((d) => d.length)\n .map((d) => {\n if (d.includes(\",\")) {\n if (d.indexOf(\",\") === d.length - 4) {\n d = d\n .replace(/,000$/g, \"k\")\n .replace(/([0-9]+)(,999$)/g, (n) => `${parseInt(n) + 1}k`);\n } else if (d.indexOf(\",\") === d.length - 8) {\n d = d\n .replace(/,000,000$/g, \"M\")\n .replace(/([0-9]+)(,999,999$)/g, (n) => `${parseInt(n) + 1}M`);\n }\n }\n return d;\n });\n if (nums.length === 2) return nums.join(\" - \");\n if (n.toLowerCase().match(/under|less|\\</g)) return `< ${nums[0]}`;\n if (n.toLowerCase().match(/over|more|\\+|\\>/g)) return `${nums[0]}+`;\n return `${nums[0]}`;\n }\n return \"None\";\n};\n\nexport default declareFormatter({\n name: \"bucket\",\n description: \"Sanitizes bucket strings to '< n', 'n1 - n2', and 'n+'\",\n logicFactory,\n inputType: \"number\",\n testValue: \"1234\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"commas\",\n description: \"* Rounds to nearest whole number and adds commas.\",\n logicFactory(libs) {\n /**\n * @param {number} n 1234.6\n */\n return (n) => libs.d3.format(\",\")(Math.round(n));\n },\n inputType: \"number\",\n testValue: \"1234.6\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"date\",\n description: \"Formats a date into '%B %d, %Y' format.\",\n logicFactory(libs) {\n /**\n * @param {date} n 2022-01-01\n */\n return (n) => {\n if (typeof n === \"string\") {\n // eslint-disable-next-line no-param-reassign\n n = libs.d3plus.date(n);\n };\n return libs.d3.timeFormat(\"%B %d, %Y\")(n);\n };\n },\n inputType: \"date\",\n testValue: \"2022-01-01\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"date\",\n description: \"Adds a US dollar sign to the beginning of a String or Number.\",\n logicFactory(libs) {\n /**\n * @param {number} n 123\n */\n return (n) => {\n if (typeof n === \"number\") n = libs.d3plus.formatAbbreviate(n);\n return n.charAt(0) === \"-\" ? n.replace(\"-\", \"-$\") : `$${n}`;\n };\n },\n inputType: \"number\",\n testValue: \"123\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"formatFieldName\",\n description: \"Based on field name returns a string\",\n logicFactory(libs) {\n /**\n * @param {number} n 123\n */\n return (n) => {\n // stats\n if (n.contentType.toLowerCase() === \"stat\") {\n if (n.field === \"title\") return \"Stat label\";\n if (n.field === \"value\") return \"Stat value\";\n if (n.field === \"subtitle\") return \"Stat subtitle\";\n if (n.field === \"tooltip\") return \"Tooltip text\";\n }\n\n if (n.contentType.toLowerCase() === \"section\") {\n if (n.field === \"short\") return \"Short title\";\n }\n\n // paragraphs\n if (n.contentType.toLowerCase() === \"description\") {\n if (n.field === \"description\") return \"Paragraph\";\n }\n\n // everything else\n return n.field;\n };\n },\n inputType: \"object\",\n testValue: \"{\\\"field\\\":\\\"title\\\",\\\"contentType\\\":\\\"stat\\\"}\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"grewTo\",\n description: \"Returns the text with grow direction: 'declined from', 'grew to' o 'stayed at'\",\n logicFactory(libs) {\n /**\n * @param {number} n -123\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"declined from\" : n > 0 ? \"grew to\" : \"stayed at\");\n },\n inputType: \"number\",\n testValue: \"-1234\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"grewWord\",\n description: \"Returns either 'grew', 'declined', or 'stayed' depending on the provided number's sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n -123\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"declined\" : n > 0 ? \"grew\" : \"stayed\");\n },\n inputType: \"number\",\n testValue: \"-1234\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"growing\",\n description: \"Returns either 'declining', 'growing' depending on the provided number's sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n -123\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"declining\" : \"growing\");\n },\n inputType: \"number\",\n testValue: \"-1234\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\n/**\n * Calculates the growth percentage between two numbers provided the following object format: {curr, prev}. Also supports calculating the growth between two margin of errors using this format: {curr, currMoe, prev, prevMoe}.\n * @param {object} n {\"curr\":10,\"currMoe\":0,\"prev\":13,\"prevMoe\":0}\n */\nconst logicFactory = () => function growth(n) {\n const {\n curr, currMoe = 0, prev, prevMoe = 0,\n } = n;\n let value;\n if (currMoe || prevMoe) {\n const f1 = (-prev / curr ** 2) ** 2 * currMoe ** 2;\n const f2 = (1 / curr) ** 2 * prevMoe ** 2;\n value = Math.sqrt(f1 + f2);\n } else value = (curr - prev) / prev;\n return value * 100;\n};\n\nexport default declareFormatter({\n name: \"growth\",\n // eslint-disable-next-line max-len\n description: \"Calculates the growth percentage between two numbers provided the following object format: {curr, prev}. Also supports calculating the growth between two margin of errors using this format: {curr, currMoe, prev, prevMoe}\",\n logicFactory,\n inputType: \"object\",\n testValue: \"{\\\"curr\\\":10,\\\"currMoe\\\":0,\\\"prev\\\":13,\\\"prevMoe\\\":0}\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"growthPct\",\n description: \"Abbreviates a growth value, turns it absolute, and adds a percent sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n return (n) => `${libs.d3plus.formatAbbreviate(Math.abs(n))}%`;\n },\n inputType: \"number\",\n testValue: \"12345\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"growthWord\",\n description: \"Returns either 'growth' or 'decline' depending on the provided number's sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n return (n) => (n < 0 ? \"decline\" : \"growth\");\n },\n inputType: \"number\",\n testValue: \"-1234\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"highWord\",\n // eslint-disable-next-line max-len\n description: \"Returns either 'higher than', 'lower than', or 'approximately the same as' depending on the provided number's sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"lower than\" : n > 0 ? \"higher than\" : \"approximately the same as\");\n },\n inputType: \"number\",\n testValue: \"0\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"increaseWord\",\n // eslint-disable-next-line max-len\n description: \"Returns either 'increase', 'decrease', or 'change' depending on the provided number's sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"decrease\" : n > 0 ? \"increase\" : \"change\");\n },\n inputType: \"number\",\n testValue: \"1234\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"increasedWord\",\n // eslint-disable-next-line max-len\n description: \"Returns either 'increased', 'decreased', or 'remained the same' depending on the provided number's sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"decreased\" : n > 0 ? \"increased\" : \"remained the same\");\n },\n inputType: \"number\",\n testValue: \"0\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"increasing\",\n description: \"Returns either 'decreasing', 'increasing' or 'maintaining' depending on the provided number's sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"decreasing\" : n > 0 ? \"increasing\" : \"maintaining\");\n },\n inputType: \"number\",\n testValue: \"-1234\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"largerThan\",\n // eslint-disable-next-line max-len\n description: \"Returns either 'higher than', 'lower than', or 'approximately the same as' depending on the provided number's sign\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"smaller than\" : n > 0 ? \"larger than\" : \"the same as\");\n },\n inputType: \"number\",\n testValue: \"-1234\",\n type: \"formatter\",\n});\n","/* eslint-disable no-param-reassign */\nimport {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"list\",\n // eslint-disable-next-line max-len\n description: \"Joins an array of strings together, adding commas and 'and' when necessary.\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n return (n) => n.reduce((str, item, i) => {\n if (!i) str += item;\n else if (i === n.length - 1 && i === 1) str += ` and ${item}`;\n else if (i === n.length - 1) str += `, and ${item}`;\n else str += `, ${item}`;\n return str;\n }, \"\");\n },\n inputType: \"object\",\n testValue: \"[\\\"foo\\\",\\\"bar\\\",\\\"bee\\\"]\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"longWord\",\n description: \"\",\n logicFactory(libs) {\n /**\n * @param {number} n 5\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"shorter\" : n > 0 ? \"longer\" : \"similar\");\n },\n inputType: \"number\",\n testValue: \"5\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"lowerCaseFirst\",\n description: \"Converts the first letter of a string to lowercase\",\n logicFactory(libs) {\n /**\n * @param {string} n 12345\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (typeof n === \"string\" ? n.charAt(0).toLowerCase() + n.slice(1) : n);\n },\n inputType: \"string\",\n testValue: \"foo\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"moreFewerWord\",\n description: \"\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n return (n) => (n < 0 ? \"fewer\" : \"more\");\n },\n inputType: \"number\",\n testValue: \"-5\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"moreLess\",\n description: \"Returns either 'more' or 'less' depending on the provided number's sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n return (n) => (n < 0 ? \"less\" : \"more\");\n },\n inputType: \"number\",\n testValue: \"-5\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"moreLess\",\n // eslint-disable-next-line max-len\n description: \"Returns either 'more than', 'less than', or 'approximately the same' depending on the provided number's sign.\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"less than\" : n > 0 ? \"more than\" : \"approximately the same\");\n },\n inputType: \"number\",\n testValue: \"-5\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"olderWord\",\n description: \"\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"getting younger\" : n > 0 ? \"getting older\" : \"staying the same age\");\n },\n inputType: \"number\",\n testValue: \"-5\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"olderYounger\",\n description: \"\",\n logicFactory(libs) {\n /**\n * @param {number} n 12345\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => (n < 0 ? \"younger than\" : n > 0 ? \"older than\" : \"the same age as\");\n },\n inputType: \"number\",\n testValue: \"-5\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"plural\",\n description: \"Pluralizes a word.\",\n logicFactory(libs) {\n /**\n * @param {string} n Foo\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => n.replace(/\\w$/g, (chr) => (chr === \"y\" ? \"ies\" : `${chr}s`));\n },\n inputType: \"string\",\n testValue: \"Foo\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"pxToInt\",\n description: \"Takes a pixel value and converts it to an integer\",\n logicFactory(libs) {\n /**\n * @param {string} n 12px\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => parseInt(n.replace(/\\D+/g, \"\"), 10);\n },\n inputType: \"string\",\n testValue: \"12px\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"salary\",\n description: \"Displays salary values with proper precision (ie. '$74,200' instead of '$74.2k')\",\n logicFactory(libs) {\n /**\n * @param {number} n 1000000\n */\n // eslint-disable-next-line no-nested-ternary\n return (n) => {\n let str;\n if (n < 1000000) {\n str = libs.d3.format(\",\")(n.toFixed(0));\n } else str = libs.d3plus.formatAbbreviate(n);\n return `$${str}`;\n };\n },\n inputType: \"number\",\n testValue: \"1000000\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"stripEntities\",\n description: \"Removes non breaking spaces & other html entities from a string\",\n logicFactory(libs) {\n /**\n * @param {string} n <b>MyText</b>\n */\n return (n) => (typeof n === \"string\"\n ? String(n).replace(/&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-f]{1,6});/ig, \" \")\n : n);\n },\n inputType: \"string\",\n testValue: \"<b>MyText</b>\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"stripHTML\",\n description: \"Converts html tags to spaces, then removes redundant spaces\",\n logicFactory(libs) {\n /**\n * @param {string} n <b>MyText</b>\n */\n return (n) => {\n // Internal list of HTML entities for escaping.\n const entities = {\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n \""\": \"\\\"\",\n \"'\": \"'\",\n \"`\": \"`\",\n \" \": \"\",\n };\n\n const source = `(?:${Object.keys(entities).join(\"|\")})`;\n const testRegexp = RegExp(source);\n const replaceRegexp = RegExp(source, \"g\");\n\n const s = String(n).replace(/<[^>]+>/g, \" \").replace(/\\s+/g, \" \").trim();\n return testRegexp.test(s) ? s.replace(replaceRegexp, (match) => entities[match]) : s;\n };\n },\n inputType: \"string\",\n testValue: \"<b>My text</b>\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"stripOL\",\n description: \"Removes ordered list wrapper tags from a string.\",\n logicFactory(libs) {\n /**\n * @param {string} n <ol><li>My list</li></ol>\n */\n return (n) => (n.replace(/<ol>/g, \"\").replace(/<\\/ol>/g, \"\"));\n },\n inputType: \"string\",\n testValue: \"<ol><li>My list</li></ol>\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"stripP\",\n description: \"Removes all paragraph tags from a string.\",\n logicFactory(libs) {\n /**\n * @param {string} n <p>My p</p>\n */\n return (n) => (n.replace(/<p>/g, \"\").replace(/<\\/p>/g, \"\"));\n },\n inputType: \"string\",\n testValue: \"<p>My p</p>\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"stripUL\",\n description: \"Removes unordered list wrapper tags from a string.\",\n logicFactory(libs) {\n /**\n * @param {string} n <ul><li>My list</li></ul>\n */\n return (n) => (n.replace(/<ul>/g, \"\").replace(/<\\/ul>/g, \"\"));\n },\n inputType: \"string\",\n testValue: \"<ul><li>My list</li></ul>\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"toKebabCase\",\n description: \"Takes a camelCase or PascalCase string and converts it to kebab-case.\",\n logicFactory(libs) {\n /**\n * @param {string} n <ul><li>My list</li></ul>\n */\n return (n) => {\n // make sure this is a valid string and this makes sense\n if (typeof n === \"string\") {\n // make sure the first character is lowercase\n // eslint-disable-next-line no-param-reassign\n n = n.charAt(0).toLowerCase() + n.substring(1);\n // grab uppercase characters, add a dash before them, and convert the whole thing to lowercase\n return n.replace(/([A-Z])/g, \"-$1\").toLowerCase();\n }\n\n // error handling\n return \"invalid string passed to toKebabCase()\";\n };\n },\n inputType: \"string\",\n testValue: \"camelCaseText\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"toSpacedCase\",\n // eslint-disable-next-line max-len\n description: \"Takes a camelCase or PascalCase string and adds spaces (I know Spaced Case isn't a thing, deal with it).\",\n logicFactory(libs) {\n /**\n * @param {string} n <ul><li>My list</li></ul>\n */\n return (n) => {\n // make sure this is a valid string and this makes sense\n if (typeof n === \"string\") {\n // grab uppercase characters, add a space before them, convert the whole thing to lowercase, and remove leading white space\n return n.replace(/([A-Z])/g, \" $1\").toLowerCase().trim();\n }\n\n // error handling\n return \"invalid string passed to toSpacedCase()\";\n };\n },\n inputType: \"string\",\n testValue: \"camelCaseText\",\n type: \"formatter\",\n});\n","import {declareFormatter} from \"../libs\";\n\nexport default declareFormatter({\n name: \"upperCaseFirst\",\n // eslint-disable-next-line max-len\n description: \"Converts the first letter of a string to uppercase\",\n logicFactory(libs) {\n /**\n * @param {string} n <ul><li>My list</li></ul>\n */\n return (n) => n.charAt(0).toUpperCase() + n.slice(1);\n },\n inputType: \"string\",\n testValue: \"my name\",\n type: \"formatter\",\n});\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\nimport {declaredFormatters} from \"../../libs/libs\";\nimport {FormatterContent} from \"../../models/formatter\";\nimport {FORMATTER_INPUT_TYPES, FORMATTER_TYPES} from \"../../types/cms\";\nimport * as formatters from \"../../libs/formatters\"; // Force to load all of them\nimport getLogging from \"../../libs/configs/getLogging\";\n\nconst verbose = getLogging();\nif (verbose) console.log(`Loaded formatters: ${Object.keys(formatters)}`);\n\nexport interface FormatterAttributes {\n id: number;\n name: string;\n content: FormatterContent;\n}\n\nexport interface FormatterCreationAttributes {\n name: string;\n content?: FormatterContent;\n}\n\nexport class FormatterModel\n extends Model<FormatterAttributes, FormatterCreationAttributes> {\n declare id: number;\n\n declare name: string;\n\n declare content: FormatterContent;\n}\n\nfunction initModel(sequelize: Sequelize) {\n FormatterModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n autoIncrement: true,\n },\n name: {\n type: DataTypes.STRING,\n defaultValue: \"\",\n },\n content: {\n type: DataTypes.JSONB,\n defaultValue: {\n description: \"\",\n testValue: \"Foo\",\n type: FORMATTER_TYPES.FORMATTER,\n inputType: FORMATTER_INPUT_TYPES.STRING,\n logic: \"return n;\",\n },\n },\n }, {\n sequelize,\n modelName: \"formatter\",\n tableName: \"bespoke_reports_formatter\",\n freezeTableName: true,\n timestamps: false,\n hooks: {\n async afterSync(options) {\n const existingFormatters = await FormatterModel.findAll();\n if (options.force || existingFormatters.length === 0) {\n const defaultFormatters = Object.entries(declaredFormatters)\n .map(([name, content]) => ({name, content}));\n await FormatterModel.bulkCreate(defaultFormatters);\n }\n },\n },\n });\n\n return () => FormatterModel;\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\nimport {ReportsDB} from \".\";\nimport {ImageContentModel} from \"./image_content\";\n\nexport interface ImageAttributes {\n id: number;\n url: string;\n author: string;\n license: string;\n splash: any;\n thumb: any;\n}\n\nexport interface ImageCreationAttributes {\n url: string;\n}\n\nexport class ImageModel\n extends Model<ImageAttributes, ImageCreationAttributes> {\n declare id: number;\n\n declare url: string;\n\n declare author: string;\n\n declare license: string;\n\n declare splash: any;\n\n declare thumb: any;\n\n declare contentByLocale: ImageContentModel[];\n\n getContent(locale: string) {\n const {contentByLocale} = this;\n if (!contentByLocale) {\n throw new Error(\"This ImageModel entity didn't include its ImageContentModel association.\");\n }\n const content = contentByLocale.find((item) => item.locale === locale);\n if (!content) {\n throw new Error(`Missing SearchContent for locale '${locale}' on Search ID '${this.id}'`);\n }\n return content;\n }\n}\n\nfunction initModel(sequelize: Sequelize) {\n ImageModel.init({\n id: {\n autoIncrement: true,\n primaryKey: true,\n type: DataTypes.INTEGER,\n },\n url: {\n type: DataTypes.TEXT,\n unique: true,\n },\n author: DataTypes.TEXT,\n license: DataTypes.TEXT,\n splash: DataTypes.BLOB,\n thumb: DataTypes.BLOB,\n }, {\n sequelize,\n modelName: \"image\",\n tableName: \"bespoke_reports_image\",\n freezeTableName: true,\n });\n\n return (models: ReportsDB) => {\n ImageModel.hasMany(models.image_content, {\n foreignKey: \"id\",\n sourceKey: \"id\",\n as: \"contentByLocale\",\n });\n\n return ImageModel;\n };\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\n\nexport class ImageContentModel extends Model {\n id: number;\n locale: string;\n meta: string;\n}\n\nfunction initModel(sequelize: Sequelize) {\n ImageContentModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_image\",\n key: \"id\",\n },\n },\n locale: {\n type: DataTypes.STRING,\n primaryKey: true,\n },\n meta: DataTypes.TEXT,\n }, {\n sequelize,\n modelName: \"image_content\",\n tableName: \"bespoke_reports_image_content\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return () => ImageContentModel\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\nimport {ReportsDB} from \".\";\nimport {AnyNestedReport, AnyReport} from \"../../models/report\";\nimport type {\n DimensionAssociations, DimensionAttributes, DimensionCreationAttributes, DimensionModel,\n} from \"./report_dimension\";\nimport type {\n SectionAssociations, SectionAttributes, SectionCreationAttributes, SectionModel,\n} from \"./section\";\n\nexport interface ReportAttributes {\n id: number;\n date: string;\n name: string;\n settings: Record<string, unknown>;\n type: AnyReport[\"type\"];\n visible: boolean;\n}\n\nexport interface ReportAssociations {\n dimensions: (DimensionAttributes & DimensionAssociations)[];\n sections: (SectionAttributes & SectionAssociations)[];\n}\n\nexport interface ReportCreationAttributes {\n name: string;\n dimensions?: DimensionCreationAttributes[];\n sections?: SectionCreationAttributes[];\n}\n\nexport class ReportModel\n extends Model<ReportAttributes, ReportCreationAttributes> {\n declare id: number;\n\n declare date: Date;\n\n declare name: string;\n\n declare settings: Record<string, unknown>;\n\n declare type: AnyReport[\"type\"];\n\n declare visible: boolean;\n\n declare dimensions: DimensionModel[];\n\n declare sections: SectionModel[];\n\n toJSON(): AnyNestedReport {\n const attributes = this.get({plain: true});\n const {dimensions = [], sections = []} = this;\n return {\n ...attributes,\n settings: attributes.settings as AnyNestedReport[\"settings\"],\n date: new Date(this.date || Date.now()).toISOString(),\n dimensions: dimensions.map((item) => item.toJSON()),\n sections: sections.map((item) => item.toJSON()),\n };\n }\n}\n\nfunction initModel(sequelize: Sequelize) {\n ReportModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n autoIncrement: true,\n },\n name: {\n type: DataTypes.STRING,\n allowNull: false,\n defaultValue: \"\",\n },\n visible: {\n type: DataTypes.BOOLEAN,\n defaultValue: true,\n },\n date: {\n type: DataTypes.DATE,\n defaultValue: DataTypes.NOW,\n },\n type: {\n type: DataTypes.STRING,\n defaultValue: \"report\",\n validate: {\n isIn: [[\"report\", \"story\"]],\n },\n },\n settings: {\n type: DataTypes.JSON,\n defaultValue: {},\n },\n }, {\n sequelize,\n modelName: \"report\",\n tableName: \"bespoke_reports_report\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return (models: ReportsDB) => {\n ReportModel.hasMany(models.dimension, {\n foreignKey: \"report_id\",\n sourceKey: \"id\",\n as: \"dimensions\",\n });\n ReportModel.hasMany(models.section, {\n foreignKey: \"report_id\",\n sourceKey: \"id\",\n as: \"sections\",\n });\n\n return ReportModel;\n };\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\nimport {ReportsDB} from \".\";\nimport {NestedDimension} from \"../../models/dimension\";\nimport type {ReportModel} from \"./report\";\nimport type {VariantAttributes, VariantCreationAttributes, VariantModel} from \"./report_dimension_variant\";\n\nexport interface DimensionAttributes {\n id: number;\n report_id: number;\n name: string;\n ordering: NestedDimension[\"ordering\"];\n settings: Record<string, unknown>;\n visible: boolean;\n}\n\nexport interface DimensionAssociations {\n variants: VariantAttributes[];\n}\n\nexport interface DimensionCreationAttributes {\n report_id: number;\n name: string;\n variants?: VariantCreationAttributes[];\n}\n\nexport class DimensionModel\n extends Model<DimensionAttributes, DimensionCreationAttributes> {\n declare id: number;\n\n declare report_id: number;\n\n declare name: string;\n\n declare report: ReportModel;\n\n declare variants: VariantModel[];\n\n toJSON(): NestedDimension {\n const attributes = this.get({plain: true});\n const {variants = []} = this;\n return {\n ...attributes,\n variants: variants.map((item) => item.toJSON()),\n };\n }\n}\n\nfunction initModel(sequelize: Sequelize) {\n DimensionModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n autoIncrement: true,\n },\n report_id: {\n type: DataTypes.INTEGER,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_report\",\n key: \"id\",\n },\n },\n name: {\n type: DataTypes.STRING,\n defaultValue: \"\",\n },\n settings: {\n type: DataTypes.JSONB,\n defaultValue: {},\n },\n ordering: {\n type: DataTypes.INTEGER,\n defaultValue: 0,\n },\n visible: {\n type: DataTypes.BOOLEAN,\n defaultValue: true,\n },\n }, {\n sequelize,\n modelName: \"dimension\",\n tableName: \"bespoke_reports_report_dimension\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return (models: ReportsDB) => {\n DimensionModel.hasMany(models.variant, {\n foreignKey: \"dimension_id\",\n sourceKey: \"id\",\n as: \"variants\",\n constraints: false,\n });\n DimensionModel.belongsTo(models.report, {\n foreignKey: \"report_id\",\n targetKey: \"id\",\n as: \"report\",\n constraints: false,\n });\n\n return DimensionModel;\n };\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\nimport {ReportsDB} from \".\";\nimport {Variant, VariantLocaleSettings} from \"../../models/variant\";\nimport type {DimensionModel} from \"./report_dimension\";\nimport type {SearchModel} from \"./search\";\n\nexport interface VariantAttributes {\n id: number;\n dimension_id: number;\n settings: Record<string, unknown>;\n config: Record<string, VariantLocaleSettings>;\n name: string;\n slug: string;\n visible: boolean;\n}\n\nexport interface VariantCreationAttributes {\n dimension_id: number;\n slug: Variant[\"slug\"];\n name: Variant[\"name\"];\n}\n\nexport class VariantModel\n extends Model<VariantAttributes, VariantCreationAttributes> {\n declare id: number;\n\n declare dimension_id: number;\n\n declare config: Variant[\"config\"];\n\n declare name: Variant[\"name\"];\n\n declare settings: Variant[\"settings\"];\n\n declare slug: Variant[\"slug\"];\n\n declare visible: Variant[\"visible\"];\n\n declare dimension: DimensionModel;\n\n declare members: SearchModel[];\n\n get report() {\n return this.dimension?.report;\n }\n\n toJSON(): Variant {\n return this.get({plain: true});\n }\n}\n\nfunction initModel(sequelize: Sequelize) {\n VariantModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n autoIncrement: true,\n },\n dimension_id: {\n type: DataTypes.INTEGER,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_report_dimension\",\n key: \"id\",\n },\n },\n slug: {\n type: DataTypes.STRING,\n defaultValue: \"\",\n },\n name: {\n type: DataTypes.STRING,\n defaultValue: \"\",\n },\n settings: {\n type: DataTypes.JSONB,\n defaultValue: {},\n },\n config: {\n type: DataTypes.JSONB,\n defaultValue: {},\n },\n visible: {\n type: DataTypes.BOOLEAN,\n defaultValue: true,\n },\n }, {\n sequelize,\n modelName: \"variant\",\n tableName: \"bespoke_reports_report_dimension_variant\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return (models: ReportsDB) => {\n VariantModel.hasMany(models.search, {\n foreignKey: \"variant_id\",\n sourceKey: \"id\",\n as: \"members\",\n constraints: false,\n });\n VariantModel.belongsTo(models.dimension, {\n foreignKey: \"dimension_id\",\n targetKey: \"id\",\n as: \"dimension\",\n constraints: false,\n });\n\n return VariantModel;\n };\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\nimport {\n DimensionModel, ImageModel, ReportModel,\n ReportsDB, SearchContentModel, VariantModel,\n} from \".\";\n\nexport interface SearchAttributes {\n id: number;\n zvalue: number;\n slug: string;\n image_id: number;\n content_id: number;\n dimension_id: number;\n variant_id: number;\n report_id: number;\n visible: boolean;\n}\n\nexport interface SearchCreationAttributes {\n slug: string;\n}\n\nexport class SearchModel\n extends Model<SearchAttributes, SearchCreationAttributes> {\n declare id: number;\n\n declare slug: string;\n\n declare visible: boolean;\n\n declare zvalue: number;\n\n declare content_id: number;\n\n declare dimension_id: number;\n\n declare image_id: number;\n\n declare report_id: number;\n\n declare variant_id: number;\n\n declare dimension: DimensionModel;\n\n declare image: ImageModel;\n\n declare report: ReportModel;\n\n declare variant: VariantModel;\n\n declare contentByLocale: SearchContentModel[];\n\n getContent(locale: string) {\n const {contentByLocale} = this;\n if (!contentByLocale) {\n throw new Error(\"This SearchModel entity didn't include its SearchContentModel association.\");\n }\n const content = contentByLocale.find((item) => item.locale === locale);\n if (!content) {\n throw new Error(`Missing SearchContent for locale '${locale}' on Search ID '${this.id}'`);\n }\n return content;\n }\n}\n\nfunction initModel(sequelize: Sequelize) {\n SearchModel.init({\n id: {\n primaryKey: true,\n type: DataTypes.TEXT,\n },\n zvalue: DataTypes.DOUBLE,\n slug: DataTypes.TEXT,\n image_id: {\n type: DataTypes.INTEGER,\n references: {\n model: \"bespoke_reports_image\",\n key: \"id\",\n },\n },\n content_id: {\n autoIncrement: true,\n type: DataTypes.INTEGER,\n unique: true,\n },\n variant_id: {\n primaryKey: true,\n type: DataTypes.INTEGER,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_report_dimension_variant\",\n key: \"id\",\n },\n },\n dimension_id: {\n primaryKey: true,\n type: DataTypes.INTEGER,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_report_dimension\",\n key: \"id\",\n },\n },\n report_id: {\n primaryKey: true,\n type: DataTypes.INTEGER,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_report\",\n key: \"id\",\n },\n },\n visible: {\n type: DataTypes.BOOLEAN,\n defaultValue: true,\n },\n }, {\n sequelize,\n modelName: \"search\",\n tableName: \"bespoke_reports_search\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return (models: ReportsDB) => {\n SearchModel.belongsTo(models.variant, {\n foreignKey: \"variant_id\",\n targetKey: \"id\",\n as: \"variant\",\n constraints: false,\n });\n SearchModel.belongsTo(models.dimension, {\n foreignKey: \"dimension_id\",\n targetKey: \"id\",\n as: \"dimension\",\n constraints: false,\n });\n SearchModel.belongsTo(models.report, {\n foreignKey: \"report_id\",\n targetKey: \"id\",\n as: \"report\",\n constraints: false,\n });\n SearchModel.belongsTo(models.image, {\n foreignKey: \"image_id\",\n targetKey: \"id\",\n as: \"image\",\n constraints: false,\n });\n\n SearchModel.hasMany(models.search_content, {\n foreignKey: \"id\",\n sourceKey: \"content_id\",\n as: \"contentByLocale\",\n });\n\n return SearchModel;\n };\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\n\nexport interface SearchContentAttributes {\n id: number;\n annotations: Record<string, unknown>;\n attributes: Record<string, unknown>;\n keywords: string[];\n locale: string;\n name: string;\n}\n\nexport interface SearchContentCreationAttributes {\n name: string;\n}\n\nexport class SearchContentModel\n extends Model<SearchContentAttributes, SearchContentCreationAttributes> {\n declare id: number;\n\n declare annotations: Record<string, unknown>;\n\n declare attributes: Record<string, unknown>;\n\n declare keywords: string[];\n\n declare locale: string;\n\n declare name: string;\n}\n\nfunction initModel(sequelize: Sequelize) {\n SearchContentModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_search\",\n key: \"content_id\",\n },\n },\n locale: {\n type: DataTypes.STRING,\n primaryKey: true,\n },\n name: DataTypes.TEXT,\n annotations: {\n type: DataTypes.JSONB,\n defaultValue: {},\n },\n attributes: {\n type: DataTypes.JSONB,\n defaultValue: {},\n },\n keywords: DataTypes.ARRAY(DataTypes.TEXT),\n }, {\n sequelize,\n modelName: \"search_content\",\n tableName: \"bespoke_reports_search_content\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return () => SearchContentModel;\n}\n\nexport default initModel\n","import {DataTypes, Model, Sequelize} from \"sequelize\";\nimport {ReportsDB} from \".\";\nimport {NestedSection} from \"../../models/section\";\nimport {\n BlockAssociations, BlockAttributes, BlockCreationAttributes, BlockModel,\n} from \"./block\";\n\nexport interface SectionAttributes {\n id: number;\n report_id: number;\n heading: NestedSection[\"heading\"];\n ordering: NestedSection[\"ordering\"];\n settings: NestedSection[\"settings\"];\n}\n\nexport interface SectionAssociations {\n blocks: (BlockAttributes & BlockAssociations)[];\n}\n\nexport interface SectionCreationAttributes {\n report_id: SectionAttributes[\"report_id\"];\n ordering: SectionAttributes[\"ordering\"];\n blocks?: BlockCreationAttributes[];\n}\n\nexport class SectionModel\n extends Model<SectionAttributes, SectionCreationAttributes> {\n declare id: number;\n\n declare report_id: number;\n\n declare blocks: BlockModel[];\n\n toJSON(): NestedSection {\n const attributes = this.get({plain: true});\n const {blocks = []} = this;\n return {\n ...attributes,\n blocks: blocks.map((item) => item.toJSON()),\n };\n }\n}\n\nfunction initModel(sequelize: Sequelize) {\n SectionModel.init({\n id: {\n type: DataTypes.INTEGER,\n primaryKey: true,\n autoIncrement: true,\n },\n\n /* metadata */\n settings: {\n type: DataTypes.JSON,\n defaultValue: {},\n },\n heading: {\n type: DataTypes.INTEGER,\n defaultValue: 1,\n },\n\n ordering: DataTypes.STRING,\n\n /* relations */\n report_id: {\n type: DataTypes.INTEGER,\n onDelete: \"cascade\",\n references: {\n model: \"bespoke_reports_report\",\n key: \"id\",\n },\n },\n }, {\n sequelize,\n modelName: \"section\",\n tableName: \"bespoke_reports_section\",\n freezeTableName: true,\n timestamps: false,\n });\n\n return (models: ReportsDB) => {\n SectionModel.hasMany(models.block, {\n foreignKey: \"section_id\",\n sourceKey: \"id\",\n as: \"blocks\",\n });\n\n return SectionModel;\n };\n}\n\nexport default initModel\n","/* eslint-disable camelcase */\n\nimport block, {BlockModel} from \"./block\";\nimport block_content, {BlockContentModel} from \"./block_content\";\nimport block_input, {BlockInputModel} from \"./block_input\";\nimport formatter, {FormatterModel} from \"./formatter\";\nimport image, {ImageModel} from \"./image\";\nimport image_content, {ImageContentModel} from \"./image_content\";\nimport report, {ReportModel} from \"./report\";\nimport dimension, {DimensionModel} from \"./report_dimension\";\nimport variant, {VariantModel} from \"./report_dimension_variant\";\nimport search, {SearchModel} from \"./search\";\nimport search_content, {SearchContentModel} from \"./search_content\";\nimport section, {SectionModel} from \"./section\";\n\nexport const modelFactoryMap = {\n block,\n block_content,\n block_input,\n formatter,\n image,\n image_content,\n report,\n dimension,\n variant,\n search,\n search_content,\n section,\n};\n\nexport type {\n BlockModel,\n BlockContentModel,\n BlockInputModel,\n FormatterModel,\n ImageModel,\n ImageContentModel,\n ReportModel,\n DimensionModel,\n VariantModel,\n SearchModel,\n SearchContentModel,\n SectionModel,\n};\n\ntype AssociationFactoryMap = typeof modelFactoryMap;\n\ntype ModelFactoryMap = {\n [K in keyof AssociationFactoryMap]: ReturnType<AssociationFactoryMap[K]>;\n}\n\nexport type ReportsDB = {\n [K in keyof ModelFactoryMap]: ReturnType<ModelFactoryMap[K]>;\n}\n","import * as pg from \"pg\";\nimport {Sequelize, Error as SequelizeError} from \"sequelize\";\nimport yn from \"yn\";\nimport getLogging from \"../libs/configs/getLogging\";\nimport {modelFactoryMap, ReportsDB} from \"./models\";\n\nexport type {ReportsDB};\n\nconst verbose = getLogging();\n\nconst connectionString = process.env.REPORTS_DB_CONNECTION || \"\";\nconst shouldWipe = yn(process.env.REPORTS_DB_WIPE);\n\nif (!connectionString) {\n throw new Error(`\n Env var 'REPORTS_DB_CONNECTION' is not present.\n This is required to connect to a database to save the Reports CMS changes.\n `);\n}\n\n// eslint-disable-next-line space-before-function-paren, @typescript-eslint/no-explicit-any\nfunction memoizeResult<T extends (...args: any[]) => any>(factory: T): T {\n let result: ReturnType<T> | undefined;\n return ((...args) => {\n result = result || factory(...args);\n return result;\n }) as T;\n}\n\n/**\n * Returns the instance connection to the DB.\n * This connection is shared through all items in the running server.\n * The function must run synchronously, so async startup operations are set to\n * run without `await`ing or monitoring the result.\n */\nexport const getDB = memoizeResult(() => {\n let sequelize: Sequelize;\n\n try {\n if (verbose) console.log(\"INITIALIZING DB CONNECTION\");\n sequelize = new Sequelize(connectionString, {\n // logging: verbose ? console.log : false,\n logging: false,\n dialectModule: pg,\n });\n } catch (e) {\n throw new Error(`\n Could not connect to the database using the given connection string.\n Please check that the connection string 'REPORTS_DB_CONNECTION' is correct.\n Details:\n ${e.message}\n `);\n }\n\n Object.values(modelFactoryMap)\n .map((modelFactory) => modelFactory(sequelize))\n .map((modelAssociator) => modelAssociator(sequelize.models as ReportsDB));\n\n return sequelize.sync({force: shouldWipe})\n .catch((err) => {\n if (err instanceof SequelizeError) {\n // We can get more information if Error implements CommonErrorProperties\n console.error(\n \"=\".repeat(40),\n \"\\nError initializing sequelize connection:\\n\",\n err.stack || err.message\n );\n process.exit(1);\n }\n throw err;\n })\n .then(() => sequelize.models as ReportsDB);\n});\n","import {PublicAPI} from \"./db\";\nimport {\n CreateMethod, DeleteMethod, EntityType, FailureResult, ReadMethod, Result, SuccessResult, UpdateMethod,\n} from \"./types\";\n\nexport class BackendError extends Error {\n code: number;\n\n constructor(code: number, message: string) {\n super(message);\n this.code = code;\n }\n\n toJSON() {\n return failureResult(this);\n }\n\n static is(obj: any): obj is BackendError {\n return Object.prototype.hasOwnProperty.call(obj, \"code\") && typeof obj.code === \"number\";\n }\n}\n\nfunction successResult<T>(result: T): SuccessResult<T> {\n return {ok: true, status: 200, data: result};\n}\n\nfunction failureResult(err: Error): FailureResult<string> {\n return {ok: false, status: BackendError.is(err) ? err.code : 500, error: err.message};\n}\n\n/**\n * Takes a function which returns a `Promise`, which might\n * resolve to a `Value` or reject with `BackendError`,\n * and wraps it to always resolve to `Result<Value, string>`\n */\nexport function resultWrapper<Param, Return>(\n method: (param: Param) => Promise<Return>,\n): (param: Param) => Promise<Result<Return>> {\n return (param) => method(param).then(successResult, failureResult);\n}\n\nexport function pickMethod<T extends EntityType>(api: PublicAPI, operation: \"create\", entity: T): CreateMethod<T>;\nexport function pickMethod<T extends EntityType>(api: PublicAPI, operation: \"read\", entity: T): ReadMethod<T>;\nexport function pickMethod<T extends EntityType>(api: PublicAPI, operation: \"update\", entity: T): UpdateMethod<T>;\nexport function pickMethod<T extends EntityType>(api: PublicAPI, operation: \"delete\", entity: T): DeleteMethod;\nexport function pickMethod<T extends EntityType>(\n api: PublicAPI,\n operation: \"create\" | \"read\" | \"update\" | \"delete\",\n entity: T,\n): CreateMethod<T> | ReadMethod<T> | UpdateMethod<T> | DeleteMethod {\n const name = `${operation}${capitalize(entity)}` as const;\n return api[name] as DeleteMethod;\n}\n\nexport function capitalize<T extends string>(str: T) {\n return str[0].toUpperCase() + str.slice(1) as Capitalize<T>;\n}\n","export default (): {localeDefault: string, locales: string[]} => {\n const localeDefault = process.env.NEXT_PUBLIC_REPORTS_LOCALE_DEFAULT || \"en\";\n const locales = process.env.NEXT_PUBLIC_REPORTS_LOCALES?.split(\",\") || [localeDefault];\n if (!locales.includes(localeDefault)) locales.push(localeDefault);\n return {localeDefault, locales};\n};\n","/**\n * Given an object, crawls down keys recursively looking for arrays. Returns a list of\n * string accessors, separated by dots if nested, e.g., \"data.payload.results\"\n */\nconst arrayFinder = (obj) => {\n const keys = [];\n if (Array.isArray(obj)) return [];\n const parse = (obj, prefix = \"\") => {\n if (!obj || typeof obj !== \"object\") return;\n Object.keys(obj).forEach((key) => {\n if (Array.isArray(obj[key])) {\n keys.push(`${prefix ? `${prefix}.` : \"\"}${key}`);\n } else if (typeof obj[key] === \"object\") {\n parse(obj[key], `${prefix ? `${prefix}.` : \"\"}${key}`);\n } else return;\n });\n };\n parse(obj);\n return keys;\n};\n\n/**\n * Given an object and a dot-separated string accessor like \"prop1.prop2.prop3\", drill down to find the nested value\n */\nconst keyDiver = (obj, str) => (!str ? obj : typeof str === \"string\" ? str.split(\".\").reduce((o, i) => o[i], obj) : obj);\n\n/**\n *\n */\nconst insertAtOrdering = (array, id, ordering) => {\n // remove the item from the array by id\n let items = array.filter((d) => d !== id);\n // insert it at the ordering spot\n items.splice(ordering, 0, id);\n // set orderings based on array location\n items = items.map((d, i) => ({id: d, ordering: i}));\n // create an ordering lookup hash\n const itemOrderings = items.reduce((acc, d) => ({...acc, [d.id]: d.ordering}), {});\n return items.map((d) => ({...d, ordering: itemOrderings[d.id]})).sort((a, b) => a.ordering - b.ordering).map((d) => d.id);\n};\n\nexport {arrayFinder, keyDiver, insertAtOrdering};\n","/**\n* Converts html tags to spaces, then removes redundant spaces\n* @param {string} n <b>My text</b>\n*/\nexport default function stripHTML(n:string) {\n // Internal list of HTML entities for escaping.\n const entities = {\n \"&\": \"&\",\n \"<\": \"<\",\n \">\": \">\",\n \""\": \"\\\"\",\n \"'\": \"'\",\n \"`\": \"`\",\n \" \": \"\",\n };\n\n const source = `(?:${Object.keys(entities).join(\"|\")})`;\n const testRegexp = RegExp(source);\n const replaceRegexp = RegExp(source, \"g\");\n\n const s = String(n).replace(/<[^>]+>/g, \" \").replace(/\\s+/g, \" \").trim();\n return testRegexp.test(s) ? s.replace(replaceRegexp, (match) => entities[match]) : s;\n}\n","/**\n* Removes non breaking spaces & other html entities from a string\n* @param {string} n <b>MyText</b>\n*/\nexport default function stripEntities(n:string) {\n return typeof n === \"string\" ? String(n).replace(/&([a-z0-9]+|#[0-9]{1,6}|#x[0-9a-f]{1,6});/ig, \" \") : n;\n}\n","import slugifyFn from \"slugify\";\nimport stripHTML from \"./stripHTML\";\nimport stripEntities from \"./stripEntities\";\n\nfunction slugify(str) {\n if (!str) return \"\";\n return slugifyFn(\n stripEntities(stripHTML(str)),\n {\n replacement: \"-\", // replace spaces with replacement character, defaults to `-`\n remove: /[*+~.()'\"!:@]/g, // remove characters that match regex, defaults to `undefined`\n lower: true, // convert to lower case, defaults to `false`\n strict: true, // strip special characters except replacement, defaults to `false`\n // locale: locale, // language code of the locale to use\n trim: true, // trim leading and trailing replacement chars, defaults to `true`\n },\n );\n}\n\nexport default slugify;\n","import axios from \"axios\";\nimport {col, fn} from \"sequelize\";\n\nimport {ReportsDB} from \"../../../db/models\";\nimport {VariantModel} from \"../../../db/models/report_dimension_variant\";\nimport {SearchAttributes} from \"../../../db/models/search\";\nimport getLocales from \"../../../libs/configs/getLocales\";\nimport {keyDiver} from \"../../../libs/js/arrayUtils\";\nimport slugify from \"../../../libs/js/slugify\";\nimport {BackendError} from \"../../lib\";\n\nconst {localeDefault} = getLocales();\n\nexport function ingestMembersFactory(db: ReportsDB) {\n const {search: Search, search_content: SearchContent} = db;\n\n return ingestMembers;\n\n async function ingestMembers(variant: VariantModel) {\n const {id, config = {}} = variant;\n\n const defaultLocale = config[localeDefault] ? localeDefault : Object.keys(config)[0];\n\n // Default ingestion: Ingest the Search main entities for the first element, assumed as default locale\n const {\n accessor, path, idKey, labelKey,\n } = config[localeDefault];\n\n if (!path || !idKey || !labelKey) return;\n const memberFetch = await axios.get(path).catch((e) => ({data: [], error: e}));\n const members = keyDiver(memberFetch.data, accessor);\n\n try {\n await ingestDefaultMembers(variant, defaultLocale, members);\n } catch (error) {\n const errorMsg = `[ERROR] Ingesting default member items for ${defaultLocale}`;\n console.error(errorMsg, error);\n throw new BackendError(500, errorMsg);\n }\n\n // Ingest localized content\n const ingestions = Object.entries(config).map(async ([locale, config]) => {\n const {\n path, accessor, idKey, labelKey, attributes = [],\n } = config;\n\n if (!path || !idKey || !labelKey) return;\n\n const memberFetch = await axios.get(path).catch((e) => ({data: [], error: e}));\n const members = keyDiver(memberFetch.data, accessor);\n\n // Ingest the localized content for every locales\n const contentHash = await Search.findAll({where: {variant_id: id}})\n .then((arr) => Object.fromEntries(\n arr.map((content) => [content.id, content.content_id]),\n ));\n\n // Generate attributes list\n const contentMembers = members.map((d) => ({\n id: contentHash[d[idKey]],\n locale,\n name: d[labelKey],\n attributes: Object.fromEntries(\n attributes.map((attr) => [\n attr.name,\n attr.type === \"constant\" ? attr.value : d[attr.value] || \"\",\n ]),\n ),\n }));\n\n try {\n await SearchContent.bulkCreate(contentMembers);\n } catch (error) {\n const errorMsg = `[ERROR] Ingesting search content items for ${locale}`;\n console.error(errorMsg, error);\n throw new BackendError(500, errorMsg);\n }\n });\n\n await Promise.all(ingestions);\n }\n\n /**\n * @private\n */\n async function ingestDefaultMembers(\n variant: VariantModel,\n locale: string,\n members: Record<string, unknown>[],\n ) {\n const {id, dimension_id, slug} = variant;\n const {report_id} = variant.dimension;\n const {idKey, labelKey} = variant.config[locale];\n\n /**\n * Get all the slugs from the other members in variants from the same\n * parent Dimension, with the same slug ('levels' use case)\n * This procedure generates a SQL query like:\n * SELECT search.slug, COUNT(variant.id)\n * FROM bespoke_search as search\n * RIGHT OUTER JOIN bespoke_variant as variant\n * ON search.variant_id = variant.id\n * WHERE variant.dimension_id = $dimension_id\n * AND variant.slug = $slug\n * GROUP BY search.slug\n */\n const allSlugsFromOtherMembers = await Search.findAll({\n attributes: [\"slug\", [fn(\"COUNT\", col(\"variant.id\")), \"slugCount\"]],\n include: {\n association: \"variant\",\n attributes: [],\n required: false,\n right: true,\n where: {dimension_id, slug},\n },\n group: \"search.slug\",\n }).then((arr) => Object.fromEntries(arr.map((item) => {\n const count = item.getDataValue(\"slugCount\" as keyof SearchAttributes);\n return [item.slug, Number.parseInt(`${count}`, 10)];\n })));\n\n const searchMembers = members.map((member) => {\n const slug = slugify(member[labelKey]);\n const memberId = member[idKey] as string;\n return {\n id: memberId,\n slug: allSlugsFromOtherMembers[slug] > 1 ? `${slug}-${memberId}` : slug,\n variant_id: id,\n dimension_id,\n report_id,\n zvalue: Math.random(),\n };\n });\n\n // Clean and ingest members\n try {\n await Search.destroy({where: {variant_id: id}});\n await Search.bulkCreate(searchMembers);\n } catch (error) {\n console.error(`[ERROR] Ingesting search members for ${locale}`, error);\n throw new Error(error);\n }\n }\n}\n","import {Op} from \"sequelize\";\nimport {ReportsDB} from \"../../../db/models\";\nimport stripHTML from \"../../../libs/js/stripHTML\";\nimport {BackendError} from \"../../lib\";\nimport {ReadMemberParams, ReadMemberResponse} from \"../../types\";\n\nexport function readMemberFactory(db: ReportsDB) {\n const {search: Search} = db;\n\n return readMember;\n\n async function readMember(params: ReadMemberParams): Promise<ReadMemberResponse> {\n const {\n mode, ids, slugs, all, locale,\n } = params;\n\n // Start an empty where clause\n const whereClause = {\n content_id: [] as number[],\n };\n\n // Collect the content_id list by...\n if (mode === \"ids\") {\n // ... setting directly the ids from params\n whereClause.content_id = ids;\n } else if (mode === \"slugs\") {\n // ... iterating over the slugs and searching the content_id individually\n const entities = await Search.findAll({\n attributes: [\"content_id\"],\n where: {\n slug: slugs.map((item) => item.memberSlug),\n },\n include: {\n association: \"variant\",\n attributes: [\"id\", \"name\", \"slug\"],\n required: false,\n where: {\n slug: slugs.map((item) => item.variantSlug),\n },\n },\n });\n whereClause.content_id = entities.map((item) => item.content_id);\n }\n\n /**\n * Setup the where clause by locale for the contentByLocale model\n * If localeParam is LOCALE_ALL we need to get all results from all locales\n */\n const contentWhereClause = {\n locale: all ? {[Op.ne]: null} : locale,\n };\n\n /**\n * Find into the search table items with the results from the resultsIds\n * Filter by locale the associated models.\n */\n const memberSearchResults = await Search.findAll({\n where: whereClause,\n include: [{\n association: \"report\",\n attributes: [\"id\", \"name\"],\n }, {\n association: \"dimension\",\n attributes: [\"id\", \"name\", \"ordering\"],\n }, {\n association: \"variant\",\n attributes: [\"id\", \"name\", \"slug\"],\n }, {\n association: \"image\",\n attributes: [\"id\", \"author\", \"url\", \"license\"],\n include: [{\n association: \"contentByLocale\",\n where: contentWhereClause,\n }],\n }, {\n association: \"contentByLocale\",\n where: contentWhereClause,\n }],\n });\n\n // Validate the number of members requested with the final results\n // If it doesn't match return 404\n if (memberSearchResults.length !== (mode === \"ids\" ? ids.length : slugs.length)) {\n throw new BackendError(404, \"One of the members was not found.\");\n }\n\n // Sort results in the same order that they have been requested using the where clause as a guide\n memberSearchResults.sort(\n (a, b) => whereClause.content_id.indexOf(a.content_id) - whereClause.content_id.indexOf(b.content_id),\n );\n\n // Format the results to deliver\n const normalizedResults = memberSearchResults.map((item) => {\n const newItem: any = {\n ...item.toJSON(),\n report_name: item.report.name,\n dimension_name: item.dimension.name,\n variant_name: item.variant.name,\n variant_slug: item.variant.slug,\n };\n\n if (!all) {\n const localizedItem = item.getContent(locale);\n\n // Plain the localized object\n newItem.locale = localizedItem.locale;\n newItem.name = localizedItem.name;\n newItem.attributes = localizedItem.attributes;\n newItem.keywords = localizedItem.keywords;\n delete newItem.contentByLocale;\n\n // Plain the localized image meta\n if (item.image) {\n const localizedImage = item.image.getContent(locale);\n newItem.image = {\n ...item.image,\n meta: localizedImage.meta,\n };\n delete newItem.image.contentByLocale;\n }\n }\n\n delete newItem.report;\n delete newItem.dimension;\n delete newItem.variant;\n\n return newItem;\n });\n\n // When is called as a function I just need the json response\n return {\n meta: {\n locale: stripHTML(locale),\n mode,\n ids,\n slugs,\n },\n results: normalizedResults,\n };\n }\n}\n","import {ReportsDB} from \"../../../db\";\nimport {BackendError} from \"../../lib\";\n\nexport interface ReadMemberImageParams {\n member: number,\n size?: \"thumb\" | \"large\"\n}\n\nexport type ReadMemberImageResponse = Buffer | Blob;\n\nexport function readMemberImageFactory(db: ReportsDB) {\n const {search: Search} = db;\n\n return readMemberImage;\n\n async function readMemberImage(params: ReadMemberImageParams): Promise<ReadMemberImageResponse> {\n const member = await Search.findOne({\n where: {content_id: params.member},\n include: [{\n association: \"image\",\n attributes: [\"id\", \"author\", \"url\", \"license\", params.size as any],\n include: [{\n association: \"contentByLocale\",\n }],\n },\n {\n association: \"report\",\n attributes: [\"id\", \"name\"],\n },\n {\n association: \"dimension\",\n attributes: [\"id\", \"name\", \"ordering\"],\n },\n {\n association: \"variant\",\n attributes: [\"id\", \"name\", \"slug\"],\n },\n ],\n });\n\n if (member && member.image) {\n if (member.image[params.size as any]) {\n const image = member.image[params.size as any];\n return image;\n }\n } else {\n const emptyPixelImage = Buffer.from(\n \"iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAQAAAC1HAwCAAAAC0lEQVR42mNkkAQAAB8AG7jymN8AAAAASUVORK5CYII=\",\n \"base64\",\n );\n return emptyPixelImage;\n // TODO check parent with custom function and return parent image\n }\n\n throw new BackendError(404, \"error in image, member not found\");\n }\n}\n","import lunr from \"lunr\";\nimport {ReportsDB} from \"../db/models\";\nimport getLocales from \"../libs/configs/getLocales\";\nimport getLogging from \"../libs/configs/getLogging\";\n\nrequire(\"lunr-languages/lunr.stemmer.support\")(lunr);\n\nconst whitelist = [\"ar\", \"da\", \"de\", \"du\", \"en\", \"es\", \"fi\", \"hi\", \"hu\", \"it\", \"ja\", \"jp\", \"nl\", \"no\", \"pt\", \"ro\", \"ru\", \"sv\", \"ta\", \"th\", \"tr\", \"vi\", \"zh\"];\n\nconst verbose = getLogging();\n\nconst {locales} = getLocales();\n\nconst enabledLocales = locales.filter((d) => whitelist.includes(d));\n\nconst nonEnLocales = enabledLocales\n .filter((d) => whitelist.includes(d))\n .filter((d) => d !== \"en\");\n\nfor (const locale of nonEnLocales) {\n require(`lunr-languages/lunr.${locale}`)(lunr);\n}\n\nlet search: any;\n\nconst getSearchIndexByLocale = async (db:ReportsDB, forceRegenerate = false) => {\n if (forceRegenerate) {\n if (verbose) console.log(\"REGENERATING SEARCH INDEX\");\n search = undefined;\n }\n\n if (search) return search;\n\n try {\n if (verbose) console.log(\"INITIALIZING SEARCH INDEX\");\n const results = await db.search\n .findAll({include: [{association: \"contentByLocale\"}]})\n .then((arr) => arr.map((d) => d.toJSON()))\n .catch(() => []);\n\n const searchIndexByLocale = {};\n\n for (const locale of enabledLocales) {\n searchIndexByLocale[locale] = lunr(function () {\n if (locale && locale !== \"en\") this.use(lunr[locale]);\n\n this.ref(\"content_id\");\n\n this.field(\"id\");\n this.field(\"name\");\n this.field(\"keywords\");\n this.field(\"attr\");\n\n this.pipeline.reset();\n this.searchPipeline.reset();\n\n results.forEach((result) => {\n const content = result.contentByLocale.find((d) => d.locale === locale);\n if (content) {\n const payload = {\n id: result.id,\n content_id: result.content_id,\n name: content.name,\n keywords: content.keywords,\n attributes: content.attributes,\n };\n this.add(payload, {boost: result.zvalue});\n }\n }, this);\n });\n }\n\n search = searchIndexByLocale;\n } catch (e) {\n throw new Error(`\n Could not initialize Lunr search engine.\n Details:\n ${e.message}\n `);\n }\n\n return search;\n};\n\nexport default getSearchIndexByLocale;\n","import {\n Includeable, literal, Op, WhereOptions,\n} from \"sequelize\";\nimport {ReportsDB} from \"../../../db/models\";\nimport {SearchAttributes, SearchModel} from \"../../../db/models/search\";\nimport {SearchContentAttributes} from \"../../../db/models/search_content\";\nimport getLocales from \"../../../libs/configs/getLocales\";\nimport stripHTML from \"../../../libs/js/stripHTML\";\nimport getSearchIndexByLocale from \"../../../search\";\n\nexport interface SearchMemberParams {\n query: string;\n locale: string;\n limit: number;\n visible: boolean;\n includes: boolean;\n noImage: boolean;\n format: \"nested\" | \"plain\";\n variant: number[];\n dimension: number[];\n report: number[];\n all: boolean;\n sort?: string;\n direction?: string;\n}\n\nexport interface SearchMemberResponse {\n meta: {origin: string;} & {[K in keyof SearchMemberParams]?: string;};\n results: SearchAttributes[] | ExtendedSearchAttributes[];\n}\n\ninterface ExtendedSearchAttributes extends SearchAttributes {\n locale: SearchContentAttributes[\"locale\"];\n name: SearchContentAttributes[\"name\"];\n attributes: SearchContentAttributes[\"attributes\"];\n keywords: SearchContentAttributes[\"keywords\"];\n}\n\nconst {localeDefault} = getLocales();\n\nexport function dbSearchMemberFactory(db: ReportsDB) {\n const {search: Search} = db;\n\n return searchMember;\n\n async function searchMember(params: SearchMemberParams): Promise<SearchMemberResponse> {\n // Get pre-generated index by locale\n const searchIndexByLocale = await getSearchIndexByLocale(db);\n\n // Store here the results IDs\n let resultsIds: any[] = [];\n\n const {\n query, locale, limit, format, visible, variant, dimension, report, all,\n noImage, includes, sort, direction = \"ASC\",\n } = params;\n\n /**\n * If there is a defined query, ask the search index for results.\n * If locale param is all we use the default locale to search.\n */\n if (query && query !== \"\" && searchIndexByLocale[locale]) {\n const terms = query.split(\" \").map((d) => `+${d}*`).join(\" \");\n const lunrResults = searchIndexByLocale[locale].search(terms);\n resultsIds = lunrResults.map((d) => parseInt(d.ref, 10));\n }\n\n // Start the where clause with default parameters\n const whereClause: WhereOptions = {\n ...(visible ? {visible} : {}),\n ...(noImage ? {image_id: {[Op.eq]: null}} : {}),\n ...(variant.length ? {variant_id: variant} : {}),\n ...(dimension.length ? {dimension_id: dimension} : {}),\n ...(report.length ? {report_id: report} : {}),\n };\n\n /**\n * Setup the where clause by locale for the contentByLocale model\n * If localeParam is LOCALE_ALL we need to get all results from all locales\n */\n const contentWhereClause = {\n locale: all ? {[Op.ne]: null} : locale,\n };\n\n /**\n * No query param, get the top {limit} ranked examples per profile type.\n */\n if (query === \"\") {\n // Get all the members ranked by zvalue per report type\n const rank = await Search.findAll({\n attributes: [\n \"id\",\n \"content_id\",\n \"report_id\",\n [literal(\"rank() over(partition by report_id order by zvalue desc)\"), \"rank\"],\n ],\n where: whereClause,\n include: [{\n association: \"contentByLocale\",\n where: contentWhereClause,\n }],\n })\n .then((arr) => arr.map((d) => d.toJSON()));\n\n // Get the top {limit} results and store the IDs.\n resultsIds = rank\n .filter((item) => parseInt(item[\"rank\" as string], 10) <= limit)\n .map((d) => d.content_id);\n }\n\n // Add id filter to the where clause\n whereClause.content_id = resultsIds;\n\n const includeClause: Includeable[] = [{\n association: \"contentByLocale\",\n where: contentWhereClause,\n }];\n\n // Add includes for metadata editor\n if (includes) {\n includeClause.push({\n association: \"report\",\n attributes: [\"id\", \"name\"],\n }, {\n association: \"dimension\",\n attributes: [\"id\", \"name\"],\n }, {\n association: \"variant\",\n attributes: [\"id\", \"slug\", \"name\"],\n });\n }\n\n /** Setup order clause */\n const orderClause: [string, string][] = [[\"zvalue\", \"DESC NULLS LAST\"]];\n\n if (sort && sort !== \"name\") {\n orderClause.unshift([sort, direction.toUpperCase()]);\n }\n\n /**\n * Find the search table items with the results from the resultsIds\n * Filter by locale the associated model, if required.\n * Sort by selected field\n */\n const results = await Search.findAll({\n limit: query ? limit : undefined,\n where: whereClause,\n include: includeClause,\n order: orderClause,\n });\n\n if (sort === \"name\") {\n const sortDirection = direction.toUpperCase() === \"ASC\" ? 1 : -1;\n results.sort((a, b) => {\n const aValue = a.getContent(localeDefault);\n const bValue = b.getContent(localeDefault);\n if (aValue && bValue) {\n return aValue.name > bValue.name ? 1 * sortDirection : -1 * sortDirection;\n }\n return 0;\n });\n }\n\n /**\n * Format results based on the locale:\n * LOCALE_ALL: \"nested\" (as it is)\n * \"<any other locale>\": \"plain\"\n */\n const resultFormatter = format === \"nested\" ? nestedFormatter : plainFormatter;\n\n return {\n meta: {\n origin: \"lunr\",\n ...Object.fromEntries(\n Object.entries(params).map((entry) => [entry[0], stripHTML(entry[1])]),\n ),\n },\n results: results.map(resultFormatter),\n };\n\n function nestedFormatter(item: SearchModel): SearchAttributes {\n return item.toJSON();\n }\n\n function plainFormatter(item: SearchModel): ExtendedSearchAttributes {\n const localizedItem = item.getContent(locale);\n return {\n ...item.toJSON(),\n locale: localizedItem.locale,\n name: localizedItem.name,\n attributes: localizedItem.attributes,\n keywords: localizedItem.keywords,\n };\n }\n }\n}\n","import {ReportsDB} from \"../../../db/models\";\nimport {UpdateMemberParams, UpdateMemberResponse} from \"../../types\";\n\nexport function updateMemberFactory(db: ReportsDB) {\n const {\n image: Image, image_content: ImageContent,\n search: Search, search_content: SearchContent,\n } = db;\n\n return updateMember;\n\n async function updateMember(params: UpdateMemberParams): Promise<UpdateMemberResponse> {\n const {\n content_id, contentByLocale, image, image_id,\n } = params;\n\n let returnQuery = {where: {content_id}};\n\n // Grab old record form image reference\n const oldRecord = await Search.findOne(returnQuery);\n\n // Update\n await Search.update(params, {where: {content_id}});\n\n // Iterate over locales\n if (contentByLocale) {\n for (let index = 0; index < contentByLocale.length; index++) {\n const searchContent = contentByLocale[index];\n await SearchContent.update({\n name: searchContent.name,\n keywords: searchContent.keywords,\n }, {where: {id: searchContent.id, locale: searchContent.locale}});\n }\n const relevantInclude = {\n include: [\n {association: \"contentByLocale\", separate: true},\n ],\n };\n returnQuery = {...returnQuery, ...relevantInclude};\n }\n\n // Image and its locales\n if (image) {\n if (image.id) {\n await Image.update({\n ...image,\n }, {where: {id: image.id}});\n if (image.contentByLocale) {\n for (let index = 0; index < image.contentByLocale.length; index++) {\n const imageContent = image.contentByLocale[index];\n await ImageContent.update({\n meta: imageContent.meta,\n }, {where: {id: imageContent.id, locale: imageContent.locale}});\n }\n }\n }\n } else if (!image_id && oldRecord.image_id) { // Image was deleted\n // Detach image already happened with the image_id update in search member\n // Now, validate if there is another one, otherwise delete it\n const othersMembersSameImage = await db.search.findAll({\n where: {image_id: oldRecord.image_id},\n });\n if (othersMembersSameImage.length === 0) { // No other member is using it\n // Remove the image\n await Image.destroy({\n where: {id: oldRecord.image_id},\n });\n }\n }\n\n return Search.findOne(returnQuery);\n }\n}\n","import {ReportsDB} from \"../../../db/models\";\nimport {ingestMembersFactory} from \"./ingestMembers\";\nimport {readMemberFactory} from \"./readMember\";\nimport {readMemberImageFactory} from \"./readMemberImage\";\nimport {dbSearchMemberFactory} from \"./searchMember\";\nimport {updateMemberFactory} from \"./updateMember\";\n\nexport type MemberMethods = ReturnType<typeof dbMemberFactory>;\n\nexport function dbMemberFactory(db: ReportsDB) {\n return {\n ingestMembers: ingestMembersFactory(db),\n readMember: readMemberFactory(db),\n searchMember: dbSearchMemberFactory(db),\n updateMember: updateMemberFactory(db),\n readMemberImage: readMemberImageFactory(db),\n };\n}\n","export const blockQuery = {\n include: [\n {association: \"contentByLocale\", separate: true},\n {association: \"inputs\"},\n {association: \"consumers\"},\n ],\n};\n\nexport const dimensionQuery = {\n include: [\n {association: \"variants\", separate: true},\n ],\n};\n\nexport const sectionQuery = {\n include: [\n {association: \"blocks\", separate: true, ...blockQuery},\n ],\n};\n\nexport const reportQuery = {\n include: [\n {association: \"dimensions\", separate: true, ...dimensionQuery},\n {association: \"sections\", separate: true, ...sectionQuery},\n ],\n};\n\nexport const blockQueryWithInputs = {\n include: [\n {association: \"contentByLocale\", separate: true},\n {\n association: \"inputs\",\n include: [\n {association: \"contentByLocale\", separate: true},\n ],\n },\n ],\n};\n\nexport const imageQueryNoBlobs = [\n {\n association: \"image\",\n attributes: {exclude: [\"thumb\", \"splash\"]},\n include: [\n {association: \"contentByLocale\"},\n ],\n },\n {association: \"contentByLocale\"},\n];\n\nexport const imageQueryThumbOnly = [\n {\n association: \"image\",\n attributes: {\n exclude: [\"splash\"],\n },\n include: [\n {association: \"contentByLocale\"},\n ],\n },\n {association: \"contentByLocale\"},\n];\n\nexport const QUERY_MAP = {\n block: blockQuery,\n dimension: dimensionQuery,\n report: reportQuery,\n section: sectionQuery,\n variant: {},\n};\n","import {ReportsDB} from \"../../../db/models\";\nimport {BackendError} from \"../../lib\";\nimport {\n CreateParams, CreateResponse, DeleteParams, DeleteResponse,\n ReadParams, ReadResponse, UpdateParams, UpdateResponse,\n} from \"../../types\";\nimport {blockQuery} from \"../include\";\n\nexport type BlockMethods = ReturnType<typeof dbBlockFactory>;\n\nexport function dbBlockFactory(db: ReportsDB) {\n const {block: Block, block_content: BlockContent, block_input: BlockInput} = db;\n\n return {\n createBlock,\n readBlock,\n updateBlock,\n deleteBlock,\n };\n\n /**\n * Creates a new Block in the DB.\n * The creation parameters could contain partial properties for the entity,\n * but the returned value contains all the properties, including ID and\n * associations.\n */\n async function createBlock(data: CreateParams[\"block\"]): Promise<CreateResponse<\"block\">> {\n const {locale, ...blockData} = data;\n const entity = await Block.create({\n ...blockData,\n consumers: [],\n inputs: [],\n contentByLocale: [{locale}],\n }, {\n include: blockQuery.include,\n });\n return entity.toJSON();\n }\n\n /**\n * Gets one or many Blocks from the DB.\n * If `idList` is empty, returns the list of all Blocks available in the DB.\n * If there's at least one ID in the list, but one of them doesn't exist in\n * the database, the entire request fails.\n */\n async function readBlock({id, include}: ReadParams = {}): Promise<ReadResponse<\"block\">> {\n const idList = id == null ? [] : ([] as number[]).concat(id);\n const entities = await Block.findAll({\n where: idList.length > 0 ? {id: idList} : undefined,\n include: include ? blockQuery.include : undefined,\n });\n if (idList.length === 0 || entities.length === idList.length) {\n return entities.map((entity) => entity.toJSON());\n }\n const found = entities.map((entity) => entity.id);\n const missing = idList.filter((item) => !found.includes(item));\n throw new BackendError(404, `Block(id=[${missing}]) does not exist.`);\n }\n\n /**\n * Updates a Block in the DB.\n * This also takes care of the associations. Returns the updated entity.\n */\n async function updateBlock(data: UpdateParams[\"block\"]): Promise<UpdateResponse<\"block\">> {\n // Extract ID and associations from data corpus\n const {\n // eslint-disable-next-line @typescript-eslint/no-unused-vars\n id, contentByLocale, consumers, inputs, inputAction, ...blockData\n } = data;\n\n const entity = await Block.findByPk(id, {\n include: blockQuery.include,\n rejectOnEmpty: true,\n });\n entity.set(blockData);\n\n if (contentByLocale) {\n const contentList = Object.values(contentByLocale);\n await BlockContent.bulkCreate(contentList, {\n updateOnDuplicate: [\"content\"],\n });\n }\n if (inputAction) {\n if (inputAction.operation === \"create\") {\n await BlockInput.create(inputAction.input);\n } else {\n await BlockInput.destroy({where: inputAction.input});\n }\n }\n await entity.save();\n await entity.reload(); // To retrieve associations updated indirectly\n return entity.toJSON();\n }\n\n /**\n * Delete a Variant from the DB.\n * Returns information of the deleted item and its parent entity.\n */\n async function deleteBlock(id: DeleteParams): Promise<DeleteResponse> {\n const entity = await Block.findByPk(id, {rejectOnEmpty: true});\n await entity.destroy();\n return {id, parentType: \"section\", parentId: entity.section_id};\n }\n}\n","import {ReportsDB} from \"../../../db/models\";\nimport {BackendError} from \"../../lib\";\nimport {\n CreateParams, CreateResponse, DeleteParams, DeleteResponse,\n ReadParams, ReadResponse, UpdateParams, UpdateResponse,\n} from \"../../types\";\nimport {dimensionQuery} from \"../include\";\n\nexport type DimensionMethods = ReturnType<typeof dbDimensionFactory>;\n\nexport function dbDimensionFactory(db: ReportsDB) {\n const {dimension: Dimension} = db;\n\n return {\n createDimension,\n readDimension,\n updateDimension,\n deleteDimension,\n };\n\n async function createDimension(data: CreateParams[\"dimension\"]): Promise<CreateResponse<\"dimension\">> {\n const entity = await Dimension.create({\n name: data.name,\n report_id: data.report_id,\n variants: [],\n }, {\n include: dimensionQuery.include,\n });\n return entity.toJSON();\n }\n\n async function readDimension({id, include}: ReadParams = {}): Promise<ReadResponse<\"dimension\">> {\n const idList = id == null ? [] : ([] as number[]).concat(id);\n const entities = await Dimension.findAll({\n where: idList.length > 0 ? {id: idList} : undefined,\n include: include ? dimensionQuery.include : undefined,\n });\n if (idList.length === 0 || entities.length === idList.length) {\n return entities.map((entity) => entity.toJSON());\n }\n const found = entities.map((entity) => entity.id);\n const missing = idList.filter((item) => !found.includes(item));\n throw new BackendError(404, `Dimension(id=[${missing}]) does not exist.`);\n }\n\n async function updateDimension(data: UpdateParams[\"dimension\"]): Promise<UpdateResponse<\"dimension\">> {\n // Extract ID and associations from data corpus\n const {id, variants, ...dimensionData} = data;\n const entity = await Dimension.findByPk(id, {\n include: dimensionQuery.include,\n rejectOnEmpty: true,\n });\n entity.set(dimensionData);\n // TODO: do something with `variants`\n await entity.save();\n return entity.toJSON();\n }\n\n async function deleteDimension(id: DeleteParams): Promise<DeleteResponse> {\n const entity = await Dimension.findByPk(id, {rejectOnEmpty: true});\n await entity.destroy();\n return {id, parentType: \"report\", parentId: entity.report_id};\n }\n}\n","import {ReportsDB} from \"../../../db/models\";\nimport {BackendError} from \"../../lib\";\nimport {\n CreateParams, CreateResponse, DeleteParams, DeleteResponse,\n ReadParams, ReadResponse, UpdateParams, UpdateResponse,\n} from \"../../types\";\n\nexport type FormatterMethods = ReturnType<typeof dbFormatterFactory>;\n\nexport function dbFormatterFactory(db: ReportsDB) {\n const {formatter: Formatter} = db;\n\n return {\n createFormatter,\n readFormatter,\n updateFormatter,\n deleteFormatter,\n };\n\n /**\n * Creates a new Formatter in the DB.\n * The creation parameters could contain partial properties for the entity,\n * but the returned value contains all the properties, including ID.\n */\n async function createFormatter(data: CreateParams[\"formatter\"]): Promise<CreateResponse<\"formatter\">> {\n const entity = await Formatter.create(data);\n return entity.toJSON();\n }\n\n /**\n * Gets one or many Formatters from the DB.\n * If `idList` is empty, returns the list of all Formatters available in the DB.\n * If there's at least one ID in the list, but one of them doesn't exist in\n * the database, the entire request fails.\n */\n async function readFormatter({id}: ReadParams = {}): Promise<ReadResponse<\"formatter\">> {\n const idList = id == null ? [] : ([] as number[]).concat(id);\n const entities = await Formatter.findAll({\n where: idList.length > 0 ? {id: idList} : undefined,\n });\n if (idList.length === 0 || entities.length === idList.length) {\n return entities.map((entity) => entity.toJSON());\n }\n const found = entities.map((entity) => entity.id);\n const missing = idList.filter((item) => !found.includes(item));\n throw new BackendError(404, `Formatter(id=[${missing}]) does not exist.`);\n }\n\n /**\n * Updates a Formatter in the DB.\n * Returns the full updated entity.\n */\n async function updateFormatter(data: UpdateParams[\"formatter\"]): Promise<UpdateResponse<\"formatter\">> {\n const {id, ...formatterData} = data;\n const entity = await Formatter.findByPk(id, {rejectOnEmpty: true});\n await entity.update(formatterData);\n return entity.toJSON();\n }\n\n /**\n * Delete a Formatter from the DB.\n * Returns the ID of the deleted Formatter.\n */\n async function deleteFormatter(id: DeleteParams): Promise<DeleteResponse> {\n const entity = await Formatter.findByPk(id, {rejectOnEmpty: true});\n await entity.destroy();\n return {id};\n }\n}\n","import {ReportsDB} from \"../../../db/models\";\nimport {BackendError} from \"../../lib\";\nimport {\n CreateParams, CreateResponse, DeleteParams, DeleteResponse,\n ReadParams, ReadResponse, UpdateParams, UpdateResponse,\n} from \"../../types\";\nimport {reportQuery} from \"../include\";\n\nexport type ReportMethods = ReturnType<typeof dbReportFactory>;\n\nexport function dbReportFactory(db: ReportsDB) {\n const {report: Report} = db;\n\n return {\n createReport,\n readReport,\n updateReport,\n deleteReport,\n };\n\n /**\n * Creates a new Report in the DB.\n * The creation parameters could contain partial properties for the entity,\n * but the returned value contains all the properties, including associations.\n */\n async function createReport(data: CreateParams[\"report\"]): Promise<CreateResponse<\"report\">> {\n const entity = await Report.create({\n name: data.name,\n sections: [],\n dimensions: [],\n }, {\n include: reportQuery.include,\n });\n return entity.toJSON();\n }\n\n /**\n * Gets a list of Reports from the DB.\n * If `idList` is empty, returns the list of all Reports available in the DB.\n * If there's at least one ID in the list, but one of them doesn't exist in\n * the database, the entire request fails.\n */\n async function readReport({id, include}: ReadParams = {}): Promise<ReadResponse<\"report\">> {\n const idList = id == null ? [] : ([] as number[]).concat(id);\n const entities = await Report.findAll({\n where: idList.length > 0 ? {id: idList} : undefined,\n include: include ? reportQuery.include : undefined,\n });\n if (idList.length === 0 || entities.length === idList.length) {\n return entities.map((entity) => entity.toJSON());\n }\n const found = entities.map((entity) => entity.id);\n const missing = idList.filter((item) => !found.includes(item));\n throw new BackendError(404, `Report(id=${missing}) does not exist.`);\n }\n\n /**\n * Updates a Report in the DB.\n * This also takes care of the associations. Returns the updated entity.\n */\n async function updateReport(data: UpdateParams[\"report\"]): Promise<UpdateResponse<\"report\">> {\n // Extract ID and associations from data corpus\n const {\n id, dimensions, sections, ...reportData\n } = data;\n\n const entity = await Report.findByPk(id, {\n include: reportQuery.include,\n rejectOnEmpty: true,\n });\n\n entity.set(reportData);\n // TODO: do something with `dimensions`, `sections`\n await entity.save();\n await entity.reload();\n return entity.toJSON();\n }\n\n /**\n * Delete a Report from the DB.\n * Returns the ID of the deleted Report.\n */\n async function deleteReport(id: DeleteParams): Promise<DeleteResponse> {\n const entity = await Report.findByPk(id, {rejectOnEmpty: true});\n await entity.destroy();\n return {id};\n }\n}\n","import {ReportsDB} from \"../../../db/models\";\nimport {BackendError} from \"../../lib\";\nimport {\n CreateParams, CreateResponse, DeleteParams, DeleteResponse,\n ReadParams, ReadResponse, UpdateParams, UpdateResponse,\n} from \"../../types\";\nimport {sectionQuery} from \"../include\";\n\nexport type SectionMethods = ReturnType<typeof dbSectionFactory>;\n\nexport function dbSectionFactory(db: ReportsDB) {\n const {section: Section} = db;\n\n return {\n createSection,\n readSection,\n updateSection,\n deleteSection,\n };\n\n /**\n * Creates a new Section in the DB.\n * The creation parameters could contain partial properties for the entity,\n * but the returned value contains all the properties, including associations.\n */\n async function createSection(data: CreateParams[\"section\"]): Promise<CreateResponse<\"section\">> {\n const entity = await Section.create({\n ordering: data.ordering,\n report_id: data.report_id,\n blocks: [],\n }, {\n include: sectionQuery.include,\n });\n return entity.toJSON();\n }\n\n /**\n * Gets a list of Sections from the DB.\n * If `idList` is empty, returns the list of all Sections available in the DB.\n * If there's at least one ID in the list, but one of them doesn't exist in\n * the database, the entire request fails.\n */\n async function readSection({id, include}: ReadParams = {}): Promise<ReadResponse<\"section\">> {\n const idList = id == null ? [] : ([] as number[]).concat(id);\n const entities = await Section.findAll({\n where: idList.length > 0 ? {id: idList} : undefined,\n include: include ? sectionQuery.include : undefined,\n });\n if (idList.length === 0 || entities.length === idList.length) {\n return entities.map((entity) => entity.toJSON());\n }\n const found = entities.map((entity) => entity.id);\n const missing = idList.filter((item) => !found.includes(item));\n throw new BackendError(404, `Section(id=${missing}) does not exist.`);\n }\n\n /**\n * Updates a Section in the DB.\n * This also takes care of the associations. Returns the updated entity.\n */\n async function updateSection(data: UpdateParams[\"section\"]): Promise<UpdateResponse<\"section\">> {\n // Extract ID and associations from data corpus\n const {id, blocks, ...sectionData} = data;\n\n const entity = await Section.findByPk(id, {\n include: sectionQuery.include,\n rejectOnEmpty: true,\n });\n entity.set(sectionData);\n // TODO: do something with `blocks`\n await entity.save();\n await entity.reload();\n return entity.toJSON();\n }\n\n /**\n * Delete a Section from the DB.\n * Returns information of the deleted item and its parent entity.\n */\n async function deleteSection(id: DeleteParams): Promise<DeleteResponse> {\n const entity = await Section.findByPk(id, {rejectOnEmpty: true});\n await entity.destroy();\n return {id, parentType: \"report\", parentId: entity.report_id};\n }\n}\n","import {col, fn, Op} from \"sequelize\";\nimport {ReportsDB} from \"../../../db/models\";\nimport {VariantAttributes} from \"../../../db/models/report_dimension_variant\";\nimport getSearchIndexByLocale from \"../../../search\";\nimport {BackendError} from \"../../lib\";\nimport {\n CreateParams, CreateResponse, DeleteParams, DeleteResponse,\n ReadParams, ReadResponse, UpdateParams, UpdateResponse,\n ValidateVariantSlugParams, ValidateVariantSlugResponse,\n} from \"../../types\";\nimport {MemberMethods} from \"../member\";\n\nexport type VariantMethods = ReturnType<typeof dbVariantFactory>;\n\nexport function dbVariantFactory(db: ReportsDB, crud: MemberMethods) {\n const {variant: Variant} = db;\n\n return {\n createVariant,\n readVariant,\n updateVariant,\n deleteVariant,\n validateVariantSlug,\n };\n\n /**\n * Creates a new Variant in the DB.\n * The creation parameters could contain partial properties for the entity,\n * but the returned value contains all the properties, including associations.\n */\n async function createVariant(\n body: CreateParams[\"variant\"],\n ): Promise<CreateResponse<\"variant\">> {\n const {dimension_id: dimension, name, slug} = body;\n // Validate slug\n const validSlug = await validateVariantSlug({dimension, slug});\n // Create variant\n const entity = await Variant.create({\n dimension_id: dimension,\n name,\n slug: validSlug.valid ? validSlug.candidate : validSlug.suggestion,\n });\n return entity.toJSON();\n }\n\n /**\n * Gets a list of Variants from the DB.\n * If `idList` is empty, returns the list of all Variants available in the DB.\n * If there's at least one ID in the list, but one of them doesn't exist in\n * the database, the entire request fails.\n */\n async function readVariant(\n {id}: ReadParams = {},\n ): Promise<ReadResponse<\"variant\">> {\n const idList = id == null ? [] : ([] as number[]).concat(id);\n const entities = await Variant.findAll({\n where: idList.length > 0 ? {id: idList} : undefined,\n });\n if (idList.length === 0 || entities.length === idList.length) {\n return entities.map((entity) => entity.toJSON());\n }\n const found = entities.map((entity) => entity.id);\n const missing = idList.filter((item) => !found.includes(item));\n throw new BackendError(404, `Variant(id=${missing}) does not exist.`);\n }\n\n /**\n * Updates a Variant in the DB, then forces a reingestion of its members, and\n * sends a signal to update the search index.\n * Returns the updated entity.\n */\n async function updateVariant(\n data: UpdateParams[\"variant\"],\n ): Promise<UpdateResponse<\"variant\">> {\n const {id, ...variantData} = data;\n\n const entity = await Variant.findByPk(id, {\n include: [{association: \"dimension\"}],\n rejectOnEmpty: true,\n });\n entity.update(variantData);\n\n // Reingest variant members in search cache\n await crud.ingestMembers(entity);\n\n // Force to regenerate search index after ingestions\n await getSearchIndexByLocale(db, true);\n\n await entity.reload();\n return entity.toJSON();\n }\n\n /**\n * Delete a Variant from the DB.\n * Returns information of the deleted item and its parent entity.\n */\n async function deleteVariant(id: DeleteParams): Promise<DeleteResponse> {\n const entity = await Variant.findByPk(id, {rejectOnEmpty: true});\n await entity.destroy();\n // Force to regenerate search index after deletion\n getSearchIndexByLocale(db, true);\n return {id, parentType: \"dimension\", parentId: entity.dimension_id};\n }\n\n /**\n * Validates the uniqueness of the proposed slug for a Variant, considering\n * all the Dimensions for whose said Variant doesn't belong to.\n */\n async function validateVariantSlug(\n {dimension, slug}: ValidateVariantSlugParams,\n ): Promise<ValidateVariantSlugResponse> {\n // Get all the slugs from ANY OTHER dimensions\n const allSlugsFromOtherDimensions = await Variant.findAll({\n attributes: [\"slug\", [fn(\"COUNT\", col(\"id\")), \"slugCount\"]],\n where: {\n dimension_id: {[Op.ne]: dimension},\n },\n group: \"slug\",\n }).then((arr) => Object.fromEntries(arr.map((item) => {\n const count = item.getDataValue(\"slugCount\" as keyof VariantAttributes);\n return [item.slug, Number.parseInt(`${count}`, 10)];\n })));\n // Check the existence of a slug that broke the constraint in any OTHER dimension\n let suggestion = slug;\n let iteration = 1;\n let valid = true;\n // Iterate until a valid name is available\n while (allSlugsFromOtherDimensions[suggestion]) {\n valid = false;\n suggestion = `${slug}-${iteration}`;\n iteration++;\n }\n return {\n candidate: slug,\n dimension_id: dimension,\n suggestion,\n valid,\n };\n }\n}\n","import {ReportsDB} from \"../../../db\";\nimport {resultWrapper} from \"../../lib\";\nimport {\n CreateMethod, DeleteMethod, ReadMethod, UpdateMethod,\n} from \"../../types\";\nimport {dbMemberFactory} from \"../member\";\nimport {dbBlockFactory} from \"./block\";\nimport {dbDimensionFactory} from \"./dimension\";\nimport {dbFormatterFactory} from \"./formatter\";\nimport {dbReportFactory} from \"./report\";\nimport {dbSectionFactory} from \"./section\";\nimport {dbVariantFactory} from \"./variant\";\n\nexport function dbEntityFactory(dbModels: ReportsDB) {\n const simpleFactories = {\n ...dbBlockFactory(dbModels),\n ...dbDimensionFactory(dbModels),\n ...dbFormatterFactory(dbModels),\n ...dbMemberFactory(dbModels),\n ...dbReportFactory(dbModels),\n ...dbSectionFactory(dbModels),\n };\n const crud = {\n ...simpleFactories,\n ...dbVariantFactory(dbModels, simpleFactories),\n };\n\n return {\n createFormatter: resultWrapper(crud.createFormatter) as CreateMethod<\"formatter\">,\n deleteFormatter: resultWrapper(crud.deleteFormatter) as DeleteMethod,\n readFormatter: resultWrapper(crud.readFormatter) as ReadMethod<\"formatter\">,\n updateFormatter: resultWrapper(crud.updateFormatter) as UpdateMethod<\"formatter\">,\n\n createReport: resultWrapper(crud.createReport) as CreateMethod<\"report\">,\n deleteReport: resultWrapper(crud.deleteReport) as DeleteMethod,\n readReport: resultWrapper(crud.readReport) as ReadMethod<\"report\">,\n updateReport: resultWrapper(crud.updateReport) as UpdateMethod<\"report\">,\n\n createDimension: resultWrapper(crud.createDimension) as CreateMethod<\"dimension\">,\n deleteDimension: resultWrapper(crud.deleteDimension) as DeleteMethod,\n readDimension: resultWrapper(crud.readDimension) as ReadMethod<\"dimension\">,\n updateDimension: resultWrapper(crud.updateDimension) as UpdateMethod<\"dimension\">,\n\n createVariant: resultWrapper(crud.createVariant) as CreateMethod<\"variant\">,\n readVariant: resultWrapper(crud.readVariant) as ReadMethod<\"variant\">,\n updateVariant: resultWrapper(crud.updateVariant) as UpdateMethod<\"variant\">,\n deleteVariant: resultWrapper(crud.deleteVariant) as DeleteMethod,\n validateVariantSlug: resultWrapper(crud.validateVariantSlug),\n\n createSection: resultWrapper(crud.createSection) as CreateMethod<\"section\">,\n readSection: resultWrapper(crud.readSection) as ReadMethod<\"section\">,\n updateSection: resultWrapper(crud.updateSection) as UpdateMethod<\"section\">,\n deleteSection: resultWrapper(crud.deleteSection) as DeleteMethod,\n\n createBlock: resultWrapper(crud.createBlock) as CreateMethod<\"block\">,\n deleteBlock: resultWrapper(crud.deleteBlock) as DeleteMethod,\n readBlock: resultWrapper(crud.readBlock) as ReadMethod<\"block\">,\n updateBlock: resultWrapper(crud.updateBlock) as UpdateMethod<\"block\">,\n\n readMember: resultWrapper(crud.readMember),\n searchMember: resultWrapper(crud.searchMember),\n updateMember: resultWrapper(crud.updateMember),\n readMemberImage: resultWrapper(crud.readMemberImage),\n };\n}\n","import sharp from \"sharp\";\n\nconst catcher = (e) => {\n console.error(\"/methods/helpers/uploadImage.ts:\", e);\n throw new Error(e.message);\n};\n\nconst splashWidth = Number(process.env.NEXT_PUBLIC_IMAGE_SPLASH_WIDTH) || 1400;\nconst thumbWidth = Number(process.env.NEXT_PUBLIC_IMAGE_THUMB_WIDTH) || 400;\n\n/**\n * Given a db connection, image id, and image buffer, attempt to upload the image to google cloud.\n * If the upload to cloud fails, store buffer data in psql row\n */\nconst uploadImage = async (db, id, imageData) => {\n const configs = [\n {type: \"splash\", res: splashWidth},\n {type: \"thumb\", res: thumbWidth},\n ];\n for (const config of configs) {\n const buffer = await sharp(imageData)\n .resize(config.res)\n .toFormat(\"jpeg\")\n .jpeg({force: true})\n .toBuffer()\n .catch(catcher);\n await db.image\n .update({[config.type]: buffer}, {where: {id}})\n .catch(catcher);\n }\n};\n\nexport default uploadImage;\n","import axios from \"axios\";\nimport Base58 from \"base58\";\nimport FlickrSDK from \"flickr-sdk\";\nimport {ReportsDB} from \"../../../../db\";\nimport getLocales from \"../../../../libs/configs/getLocales\";\nimport stripHTML from \"../../../../libs/js/stripHTML\";\nimport {imageQueryThumbOnly} from \"../../include\";\nimport uploadImage from \"../helpers/uploadImage\";\nimport {ImageSaveParams, ImageSaveResponse} from \"../imageSave\";\nimport {ImageSearchParams, ImageSearchResponse} from \"../imageSearch\";\n\nconst validLicenses = [\"4\", \"5\", \"7\", \"8\", \"9\", \"10\"];\nconst validLicensesString = validLicenses.join();\n\nconst {locales} = getLocales();\n\n// Build Flickr api object\nlet flickr;\nif (process.env.FLICKR_API_KEY) {\n try {\n flickr = new FlickrSDK(process.env.FLICKR_API_KEY);\n } catch (e) {\n console.error(\"Flickr ERROR:\", e);\n throw new Error(e.message);\n }\n}\n\nexport async function searchFlickrProvider(db: ReportsDB, params: ImageSearchParams): Promise<ImageSearchResponse> {\n try {\n const searchParams = {\n prompt: params.prompt || \"\",\n };\n\n // Test Flickr api object\n if (!flickr) {\n console.log(\"Flickr is not initialized. Check the credentials\");\n throw new Error(\"Flickr is not initialized. Check the credentials\");\n }\n\n const q = searchParams.prompt;\n const result = await flickr.photos\n .search({\n text: q,\n license: validLicensesString,\n sort: \"relevance\",\n })\n .then((resp) => resp.body);\n\n const photos = result.photos.photo;\n const fetches = photos.reduce(\n (acc, d) => acc.concat(flickr.photos.getSizes({photo_id: d.id})),\n [],\n );\n const results = await Promise.all(fetches)\n .then((results) => results);\n\n const imagesResults = results.reduce((acc, d, i) => {\n const small = d.body.sizes.size.find((s) => s.label === \"Small 320\");\n if (small) {\n acc.push({\n id: photos[i].id,\n source: small.source,\n });\n }\n return acc;\n }, []);\n\n return {\n meta: {\n prompt: stripHTML(searchParams.prompt),\n },\n results: imagesResults,\n };\n } catch (error) {\n console.log(error);\n throw new Error(\"Error in search flickr provider\");\n }\n}\n\nexport async function saveFlickrProvider(db: ReportsDB, params: ImageSaveParams): Promise<ImageSaveResponse> {\n try {\n // Parse params\n const {content_id, image_id} = params;\n\n const searchParams = {\n content_id: stripHTML(`${content_id}`) || \"\",\n id: stripHTML(`${image_id}`) || \"\",\n };\n\n const shortid = Base58.int_to_base58(image_id);\n const url = `https://flic.kr/p/${shortid}`;\n\n // Test Flickr api object\n if (!flickr) {\n throw new Error(\"Flickr API Key not configured\");\n }\n\n const info = await flickr.photos\n .getInfo({photo_id: image_id})\n .then((resp) => resp.body);\n\n let newRow;\n\n if (info) {\n if (validLicenses.includes(info.photo.license)) {\n const searchRow = await db.search\n .findOne({where: {content_id}});\n const imageRow = await db.image\n .findOne({where: {url}});\n if (searchRow) {\n if (imageRow) {\n await db.search\n .update({image_id: imageRow.id}, {where: {content_id}});\n } else {\n // To add a new image, first fetch the image data\n const sizeObj = await flickr.photos\n .getSizes({photo_id: image_id})\n .then((resp) => resp.body);\n let image = sizeObj.sizes.size.find(\n (d) => parseInt(d.width, 10) >= 1600,\n );\n if (!image) {\n image = sizeObj.sizes.size.find(\n (d) => parseInt(d.width, 10) >= 1000,\n );\n }\n if (!image) {\n image = sizeObj.sizes.size.find(\n (d) => parseInt(d.width, 10) >= 500,\n );\n }\n if (!image || !image.source) {\n throw new Error(\"Flickr Source Error, try another image.\");\n }\n const imageData = await axios\n .get(image.source, {responseType: \"arraybuffer\"})\n .then((d) => d.data);\n\n // Get license name\n const allLicenses = await flickr.photos.licenses.getInfo().then((resp) => resp.body.licenses.license);\n const currentPhotoLicense = allLicenses.find((l) => l.id === parseInt(info.photo.license, 10));\n\n // Then add a row to the image table with the metadata.\n const payload = {\n url,\n author: info.photo.owner.realname || info.photo.owner.username,\n license: currentPhotoLicense ? `${currentPhotoLicense.name}: ${currentPhotoLicense.url}` : \"\",\n };\n const newImage = await db.image.create(payload);\n\n // Clear old meta\n await db.image_content.destroy({where: {id: newImage.id}});\n\n // Create new content meta\n const contentPayload = locales.map((locale) => ({\n id: newImage.id,\n locale,\n meta: info.photo.title._content, // TODO include tags\n }));\n\n // Insert new content meta\n await db.image_content.bulkCreate(contentPayload);\n\n // Update search reference\n await db.search\n .update({image_id: newImage.id}, {where: {content_id}});\n\n // Finally, upload splash and thumb version to psql\n await uploadImage(db, newImage.id, imageData);\n }\n const newRow:any = await db.search\n .findOne({\n where: {content_id},\n include: imageQueryThumbOnly,\n });\n if (newRow && newRow.image) {\n newRow.image.thumb = Boolean(newRow.image.thumb);\n }\n } else {\n throw new Error(\"Error updating Search\");\n }\n } else {\n throw new Error(\"Bad License\");\n }\n } else {\n throw new Error(\"Malformed URL\");\n }\n\n return {\n meta: {\n ...searchParams,\n },\n results: newRow,\n };\n } catch (error) {\n console.log(error);\n throw new Error(\"Error in save flickr provider\");\n }\n}\n","import {NextApiRequest} from \"next\";\n\nimport {BackendError} from \"../lib\";\nimport {Endpoint, HttpMethod} from \"../types\";\n\nexport function endpoint<P extends string, T>(\n method: HttpMethod,\n path: P,\n handler: (req: NextApiRequest) => Promise<T>,\n): Endpoint<P, T> {\n return {method, path, handler};\n}\n\n/**\n * Parses a value as a single finite number.\n * Throws an error if the value can't be parsed as such.\n */\nexport function parseFiniteNumber(value: string | string[] | undefined): number {\n const num = Number.parseInt(`${value || \"\"}`, 10);\n if (Number.isNaN(num) || !Number.isFinite(num)) {\n throw new BackendError(400, `Invalid numeric parameter: ${value}`);\n }\n return num;\n}\n\n/**\n * Ensures a parsed parameter list of strings contains valid useful values.\n */\nexport function normalizeList(value: string | string[] | undefined): string[] {\n return value == null || value === \"\" ? [] : value.toString().split(\",\");\n}\n","import {NextApiRequest} from \"next\";\nimport yn from \"yn\";\nimport getLocales from \"../../libs/configs/getLocales\";\nimport {PublicAPI} from \"../db\";\nimport {SearchMemberParams} from \"../db/member/searchMember\";\nimport {BackendError} from \"../lib\";\nimport {ReadMemberParams} from \"../types\";\nimport {endpoint, normalizeList, parseFiniteNumber} from \"./lib\";\n\nconst {localeDefault} = getLocales();\n\n/**\n * Endpoints specific to the member entity.\n */\nexport function endpointMemberFactory(operations: PublicAPI) {\n const {\n readMember, searchMember, updateMember, readMemberImage,\n } = operations;\n\n return [\n /**\n * Retrieve search members based on:\n * - ids (id1,id2,id3,...) \"content_id\"\n * or\n * - slugs(variantSlug1/memberSlug1,variantSlug2/memberSlug2,...)\n * for profile\n *\n * Example queries:\n * /api/cms/read/members?slugs=hs/material,country/arg\n * OR\n * /api/cms/read/members?ids=2342,1224\n */\n endpoint(\"GET\", \"read/members\", async (req) => {\n // Parse params and ensure values\n const params = parseReadMemberParams(req.query);\n // Validate values\n if (params.ids.length > 1 && params.slugs.length > 1) {\n throw new BackendError(400, \"Both 'ids' and 'slugs' are filled. Pick one.\");\n }\n if (params.ids.length === 0 && params.slugs.length === 0) {\n throw new BackendError(400, \"Params 'ids' and 'slugs' are missing. Fill one.\");\n }\n if ((params.mode === \"ids\" ? params.ids.length : params.slugs.length) > 5) {\n throw new BackendError(400, \"Too many 'ids' and 'slugs' in the request. Try with less than 5.\");\n }\n // Perform request and return result\n return readMember(params);\n }),\n\n /**\n * Query entities in search table\n * Example queries:\n * /api/cms/search/members?q=bar&limit=2&locale=es\n * /api/cms/search/members?query=foo&limit=10&locale=all\n * /api/cms/search/members?query=&limit=5&locale=en&report=1\n */\n endpoint(\"GET\", \"search/members\", (req) => {\n // Parse params and ensure values\n const params = parseSearchMemberParams(req.query);\n // Perform request and return result\n return searchMember(params);\n }),\n\n endpoint(\"POST\", \"update/member\", (req) => {\n const {body} = req;\n // Update metadata element\n return updateMember(body);\n }),\n\n /*\n * Get image file itself\n * Example queries:\n * /api/cms/member/image.png?member=1&format=thumb\n */\n endpoint(\"GET\", \"member/image.png\", (req) => {\n const size = normalizeList(req.query.size)[0];\n return readMemberImage({\n member: parseFiniteNumber(req.query.member),\n size: size && size === \"large\" ? \"large\" : \"thumb\",\n });\n }),\n ] as const;\n}\n\nfunction parseReadMemberParams(query: NextApiRequest[\"query\"]): ReadMemberParams {\n const ids = normalizeList(query.ids).map(parseFiniteNumber);\n const locale = normalizeList(query.locale)[0] || localeDefault || \"en\";\n const localeIsAll = locale === \"all\";\n return {\n all: localeIsAll,\n ids,\n locale: localeIsAll ? localeDefault : locale,\n mode: ids.length > 0 ? \"ids\" : \"slugs\",\n slugs: normalizeList(query.slugs).map((token) => {\n const [variantSlug, memberSlug] = token.split(\"/\");\n return {variantSlug, memberSlug};\n }),\n };\n}\n\nexport function parseSearchMemberParams(query: NextApiRequest[\"query\"]): SearchMemberParams {\n const locale = normalizeList(query.locale)[0] || localeDefault || \"en\";\n const localeIsAll = locale === \"all\";\n const format = normalizeList(query.format)[0];\n const formatIsNested = format ? format === \"nested\" : localeIsAll;\n return {\n query: normalizeList(query.query || query.q)[0] || \"\",\n locale: localeIsAll ? localeDefault : locale,\n limit: normalizeList(query.limit).map(parseFiniteNumber)[0] ?? 5,\n format: formatIsNested ? \"nested\" : \"plain\",\n includes: yn(query.includes, {default: true}),\n visible: yn(query.visible, {default: true}),\n noImage: yn(query.noImage, {default: false}),\n variant: normalizeList(query.variant).map(parseFiniteNumber),\n dimension: normalizeList(query.dimension).map(parseFiniteNumber),\n report: normalizeList(query.report).map(parseFiniteNumber),\n all: localeIsAll,\n sort: normalizeList(query.sort)[0],\n direction: normalizeList(query.direction)[0],\n };\n}\n","import {ReportsDB} from \"../../../../db\";\nimport stripHTML from \"../../../../libs/js/stripHTML\";\nimport {parseSearchMemberParams} from \"../../../endpoints/member\";\nimport {imageQueryThumbOnly} from \"../../include\";\nimport {dbSearchMemberFactory} from \"../../member/searchMember\";\nimport {ImageSaveParams, ImageSaveResponse} from \"../imageSave\";\nimport {ImageSearchParams, ImageSearchResponse} from \"../imageSearch\";\n\nexport async function searchLocalProvider(db: ReportsDB, params: ImageSearchParams): Promise<ImageSearchResponse> {\n const dbSearchMember = dbSearchMemberFactory(db);\n\n const searchParams = parseSearchMemberParams({\n query: params.prompt,\n limit: \"50\",\n visible: \"false\",\n });\n const resultsFromProfiles = await dbSearchMember(searchParams);\n\n const imagesResults = resultsFromProfiles.results\n .filter((member) => member.image_id)\n .map((member) => ({\n id: member.image_id,\n source: `/api/cms/member/image.png?member=${member.content_id}&size=thumb`,\n }));\n\n // TODO search into image metadata, from content by locale and combine, de-duplicate results\n\n return {\n meta: {\n prompt: stripHTML(searchParams.query),\n },\n results: imagesResults,\n };\n}\n\nexport async function saveLocalProvider(db: ReportsDB, params: ImageSaveParams): Promise<ImageSaveResponse> {\n const {search: Search} = db;\n\n // Parse params\n const {content_id, image_id} = params;\n\n // Update search reference\n await Search.update({image_id}, {where: {content_id}});\n\n const item = await Search.findOne({\n where: {content_id},\n include: imageQueryThumbOnly,\n }).then((item) => {\n if (!item) return null;\n const plainItem = item.toJSON();\n return {\n ...plainItem,\n image: {\n ...item.image.toJSON(),\n thumb: !!(item.image.thumb),\n },\n };\n });\n\n return {\n meta: {\n id: image_id,\n content_id,\n },\n results: item,\n };\n}\n","import axios from \"axios\";\nimport {createApi} from \"unsplash-js\";\nimport {ReportsDB} from \"../../../../db\";\nimport getLocales from \"../../../../libs/configs/getLocales\";\nimport stripHTML from \"../../../../libs/js/stripHTML\";\nimport {imageQueryThumbOnly} from \"../../include\";\nimport uploadImage from \"../helpers/uploadImage\";\nimport {ImageSaveParams, ImageSaveResponse} from \"../imageSave\";\nimport {ImageSearchParams, ImageSearchResponse} from \"../imageSearch\";\n\nconst {locales} = getLocales();\n\n// Build Flickr api object\nlet unsplash;\nif (process.env.UNSPLASH_API_KEY) {\n try {\n unsplash = createApi({\n accessKey: process.env.UNSPLASH_API_KEY,\n });\n } catch (e) {\n console.error(\"Unsplash error:\", e);\n throw new Error(e.message);\n }\n}\n\nexport async function searchUnsplashProvider(db: ReportsDB, params: ImageSearchParams): Promise<ImageSearchResponse> {\n try {\n const searchParams = {\n prompt: params.prompt || \"\",\n };\n\n // Test Unsplash api object\n if (!unsplash) {\n throw new Error(\"Unsplash API Key not configured\");\n }\n\n const q = searchParams.prompt;\n const result = await unsplash.search\n .getPhotos({\n query: q,\n perPage: 30, // max\n })\n .then((resp) => resp.response.results);\n\n const imagesResults = result.map((image) => ({\n id: image.id,\n source: image.urls.thumb,\n }));\n\n return {\n meta: {\n prompt: stripHTML(searchParams.prompt),\n },\n results: imagesResults,\n };\n } catch (error) {\n console.log(error);\n throw new Error(\"Error in search unsplash provider\");\n }\n}\n\nexport async function saveUnsplashProvider(db: ReportsDB, params: ImageSaveParams): Promise<ImageSaveResponse> {\n try {\n // Parse params\n const {content_id, image_id} = params;\n\n const saveParams = {\n content_id: stripHTML(`${content_id}`) || \"\",\n id: stripHTML(`${image_id}`) || \"\",\n };\n\n // Test Unsplash api object\n if (!unsplash) {\n console.log(\"Unsplash is not initialized. Check the credentials\");\n throw new Error(\"Unsplash is not initialized. Check the credentials\");\n }\n\n const info = await unsplash.photos\n .get({photoId: image_id})\n .then((resp) => resp.response);\n\n let newRow;\n\n if (info) {\n // if (validLicenses.includes(info.photo.license)) {\n if (true) { // evaluate license\n const searchRow = await db.search\n .findOne({where: {content_id}});\n\n const url = info.links.html;\n\n const imageRow = await db.image\n .findOne({where: {url}});\n\n if (searchRow) {\n if (imageRow) {\n await db.search\n .update({image_id: imageRow.id}, {where: {content_id}});\n } else {\n const imageData = await axios\n .get(info.urls.full, {responseType: \"arraybuffer\"})\n .then((d) => d.data);\n\n // Then add a row to the image table with the metadata.\n const payload = {\n url,\n author: info.user.name || info.user.username,\n license: \"Free Unsplash license: https://unsplash.com/license\",\n };\n const newImage = await db.image.create(payload);\n\n // Clear old meta\n await db.image_content.destroy({where: {id: newImage.id}});\n\n // Create new content meta\n const contentPayload = locales.map((locale) => ({\n id: newImage.id,\n locale,\n meta: info.description || info.alt_description, // TODO include tags\n }));\n\n // Insert new content meta\n await db.image_content.bulkCreate(contentPayload);\n\n // Update search reference\n await db.search\n .update({image_id: newImage.id}, {where: {content_id}});\n\n // Finally, upload splash and thumb version to psql\n await uploadImage(db, newImage.id, imageData);\n }\n const newRow:any = await db.search\n .findOne({\n where: {content_id},\n include: imageQueryThumbOnly,\n });\n\n if (newRow && newRow.image) {\n newRow.image.thumb = Boolean(newRow.image.thumb);\n }\n } else {\n throw new Error(\"Error updating Search\");\n }\n } else {\n throw new Error(\"Bad License\");\n }\n } else {\n throw new Error(\"Malformed URL\");\n }\n\n return {\n meta: {\n ...saveParams,\n },\n results: newRow,\n };\n } catch (error) {\n console.log(error);\n throw new Error(\"Error in save unsplash provider\");\n }\n}\n","import fs from \"fs\";\nimport {ReportsDB} from \"../../../../db\";\nimport getLocales from \"../../../../libs/configs/getLocales\";\nimport stripHTML from \"../../../../libs/js/stripHTML\";\nimport {imageQueryThumbOnly} from \"../../include\";\nimport uploadImage from \"../helpers/uploadImage\";\nimport {ImageSaveParams, ImageSaveResponse} from \"../imageSave\";\n\nconst {locales} = getLocales();\n\nexport async function saveUploadProvider(db: ReportsDB, params: ImageSaveParams): Promise<ImageSaveResponse> {\n try {\n // Parse params\n const {content_id, image_source, files} = params;\n\n const saveParams = {\n content_id: stripHTML(`${content_id}`) || \"\",\n };\n\n const searchRow = await db.search\n .findOne({where: {content_id}});\n\n if (searchRow && files) {\n const imageData = await fs.readFileSync(files.file.path);\n\n // Then add a row to the image table with empty metadata.\n const payload = {\n url: image_source,\n author: \"\",\n license: \"\",\n };\n const newImage = await db.image.create(payload);\n\n // Clear old meta\n await db.image_content.destroy({where: {id: newImage.id}});\n\n // Create new content meta\n const contentPayload = locales.map((locale) => ({\n id: newImage.id,\n locale,\n meta: \"\",\n }));\n\n // Insert new content meta\n await db.image_content.bulkCreate(contentPayload);\n\n // Update search reference\n await db.search\n .update({image_id: newImage.id}, {where: {content_id}});\n\n // Finally, upload splash and thumb version to psql\n await uploadImage(db, newImage.id, imageData);\n }\n\n const newRow:any = await db.search\n .findOne({\n where: {content_id},\n include: imageQueryThumbOnly,\n });\n\n if (newRow && newRow.image) {\n newRow.image.thumb = Boolean(newRow.image.thumb);\n }\n\n return {\n meta: {\n ...saveParams,\n },\n results: newRow,\n };\n } catch (error) {\n console.log(error);\n throw new Error(\"Error in save upload provider\");\n }\n}\n","import {ReportsDB} from \"../../../db\";\nimport {BackendError, resultWrapper} from \"../../lib\";\nimport {saveFlickrProvider} from \"./providers/flickr\";\nimport {saveLocalProvider} from \"./providers/local\";\nimport {saveUnsplashProvider} from \"./providers/unsplash\";\nimport {saveUploadProvider} from \"./providers/upload\";\n\nexport interface ImageSaveParams {\n content_id: number;\n image_id: number;\n image_source?: string;\n files?: Record<string, any>;\n prompt?: string;\n}\n\nexport interface ImageSaveResponse {\n meta: Record<string, string | number>;\n results: any;\n}\n\nexport type ImageSaveProvider = keyof typeof saveProviders;\n\nconst saveProviders = {\n local: saveLocalProvider,\n flickr: saveFlickrProvider,\n unsplash: saveUnsplashProvider,\n upload: saveUploadProvider,\n};\n\nexport function dbImageSaveFactory(db: ReportsDB, provider: ImageSaveProvider) {\n const saveProvider = saveProviders[provider];\n if (!saveProvider) {\n throw new BackendError(500, `Wrong provider dbImageSaveFactory.ts: ${provider}`);\n }\n return resultWrapper((params: ImageSaveParams) => saveProvider(db, params));\n}\n","import {ReportsDB} from \"../../../db/models\";\nimport {BackendError, resultWrapper} from \"../../lib\";\nimport {searchFlickrProvider} from \"./providers/flickr\";\nimport {searchLocalProvider} from \"./providers/local\";\nimport {searchUnsplashProvider} from \"./providers/unsplash\";\n\nexport interface ImageSearchParams {\n prompt: string,\n}\n\nexport interface ImageSearchResponse {\n meta: { [key: string]: string },\n results: {\n id: number,\n source: string,\n }[]\n}\n\nexport type ImageSearchProvider = keyof typeof searchProviders;\n\nconst searchProviders = {\n local: searchLocalProvider,\n flickr: searchFlickrProvider,\n unsplash: searchUnsplashProvider,\n};\n\nexport function dbImageSearchFactory(db: ReportsDB, provider: ImageSearchProvider) {\n const searchProvider = searchProviders[provider];\n if (!searchProvider) {\n throw new BackendError(500, `Wrong provider dbImageSearchFactory.ts: ${provider}`);\n }\n return resultWrapper((params: ImageSearchParams) => searchProvider(db, params));\n}\n","import {ReadMetadataParams, ReadMetadataResponse} from \"../types\";\nimport {ReportsDB} from \"../../db\";\nimport {REPORT_MODES} from \"../../types/cms\";\n\n/** Retrieve all metadata (report, dimension, variant) */\nexport function dbReadMetadataFactory(db: ReportsDB) {\n const {report: Report} = db;\n\n return dbReadMetadata;\n\n async function dbReadMetadata(_params?: ReadMetadataParams): Promise<ReadMetadataResponse> {\n const results = await Report.findAll({\n attributes: [\"id\", \"name\"],\n include: [{\n attributes: [\"id\", \"name\"],\n association: \"dimensions\",\n separate: true,\n include: [\n {\n attributes: [\"id\", \"name\", \"slug\"],\n association: \"variants\",\n separate: true,\n },\n ],\n }],\n });\n\n return {\n data: results.map((report) => ({\n ...report.toJSON(),\n mode: report.dimensions.length === 1\n ? REPORT_MODES.UNILATERAL\n : REPORT_MODES.MULTILATERAL,\n })),\n };\n }\n}\n","import {ReportsDB} from \"../../db/models\";\nimport getSearchIndexByLocale from \"../../search\";\n\nexport interface RegenerateSearchParams {}\n\nexport interface RegenerateSearchResponse {\n error: boolean\n}\n\nexport function dbRegenerateSearchFactory(db: ReportsDB) {\n return async (_params?: RegenerateSearchParams): Promise<RegenerateSearchResponse> => {\n // Force to regenerate search index after ingestions\n await getSearchIndexByLocale(db, true);\n return {error: false};\n };\n}\n","import {ReportsDB} from \"../../db\";\nimport getLocales from \"../../libs/configs/getLocales\";\nimport stripHTML from \"../../libs/js/stripHTML\";\nimport {REPORT_MODES} from \"../../types/cms\";\nimport {SearchReportParams, SearchReportResponse} from \"../types\";\nimport {dbSearchMemberFactory} from \"./member/searchMember\";\nimport {dbReadMetadataFactory} from \"./readMetadata\";\n\nconst {locales, localeDefault} = getLocales();\n\n/** Generate profile structure for \"profiles\" and \"grouped\" */\nconst addProfilesData = (items, metadata) => {\n if (!items) return [];\n let profileResults = [];\n metadata.forEach((report) => {\n const results = items.filter((result) => result.metadata.report.id === report.id);\n if (results.length > 0) {\n if (report.mode === REPORT_MODES.UNILATERAL) {\n const dimension = report.dimensions[0]; // The only one\n dimension.variants.forEach((variant) => {\n const members = results\n .filter(\n (result) => result.metadata.dimension.id === dimension.id && result.metadata.variant.id === variant.id,\n );\n if (members.length > 0) {\n profileResults = profileResults.concat(members.map((member) => ({\n path: `/${variant.slug}/${member.slug}`,\n name: member.name,\n report: {\n id: report.id,\n name: report.name,\n mode: report.mode,\n },\n members: [member],\n id: `r-${report.id}-${[member].map((m) => `${m.id}`).join(\"-\")}`,\n })));\n }\n });\n } else if (report.mode === REPORT_MODES.MULTILATERAL) {\n // TO-DO MULTILATERAL RESULTS\n }\n }\n });\n return profileResults;\n};\n\n/** Format the items in a nested way, for \"results\" */\nconst formatNested = (items, metadata) => {\n if (!items) return [];\n let report; let dimension; let variant;\n return items.map((item) => {\n report = {...metadata.find((r) => r.id === item.report_id)};\n dimension = {...report.dimensions.find((d) => d.id === item.dimension_id)};\n variant = {...dimension.variants.find((v) => v.id === item.variant_id)};\n delete report.dimensions;\n delete dimension.variants;\n return {\n name: item.name,\n confidence: item.zvalue,\n metadata: {\n id: item.id,\n slug: item.slug,\n report,\n dimension,\n variant,\n },\n id: item.content_id,\n slug: item.slug,\n };\n });\n};\n\nexport function dbSearchReportFactory(db: ReportsDB) {\n const dbSearchMember = dbSearchMemberFactory(db);\n const dbReadMetadata = dbReadMetadataFactory(db);\n\n return dbSearchReport;\n\n async function dbSearchReport(params: SearchReportParams): Promise<SearchReportResponse> {\n const format = params.format || \"results\"; // \"results\", \"profiles\", \"grouped\"\n const locale = locales.includes(params.locale as string) ? params.locale : localeDefault;\n\n // First step run entity search handler\n const memberSearchResponse = await dbSearchMember({\n ...params,\n format: \"plain\",\n locale: stripHTML(locale),\n visible: true,\n });\n\n let reportSearchResults = memberSearchResponse.results ? memberSearchResponse.results : [];\n\n let tempResults;\n\n // Grab all metadata\n const metadataResponse = await dbReadMetadata();\n const metadata = metadataResponse.data;\n\n // Format \"results\", \"profiles\", \"grouped\"\n switch (format) {\n /* case \"results\":\n // Fill results with metadata in a nested format\n tempResults = formatNested(memberSearchResponse.results, metadata);\n // Group results by profile name\n reportSearchResults = tempResults.reduce(\n (groups, item) => {\n const key = item.metadata.report.name;\n if (!groups[key]) { groups[key] = []; }\n groups[key].push(item);\n return groups;\n },\n {},\n );\n break; */\n\n case \"profiles\":\n // Fill results with metadata in a nested format\n tempResults = formatNested(reportSearchResults, metadata);\n // Group entities as profiles\n reportSearchResults = addProfilesData(tempResults, metadata);\n break;\n\n /* case \"grouped\":\n // Fill results with metadata in a nested format\n tempResults = formatNested(memberSearchResponse.results, metadata);\n // Group entities as profiles\n tempResults = addProfilesData(tempResults, metadata);\n // Group results by dimension|variant name\n reportSearchResults = tempResults.reduce(\n (groups, item) => {\n const key = item.profile;\n if (!groups[key]) { groups[key] = []; }\n groups[key].push(item);\n return groups;\n },\n {},\n );\n break; */\n\n default:\n break;\n }\n\n // When is called as a function I just need the json response\n return {\n meta: {\n ...memberSearchResponse.meta,\n format, // Override format\n },\n results: reportSearchResults,\n };\n }\n}\n","import axios from \"axios\";\nimport {BackendError} from \"../lib\";\nimport {Result} from \"../types\";\n\ntype ProxyRequestParams = string | {\n url: string;\n method?: \"GET\"|\"POST\";\n}\n\nexport function dbUrlProxyFactory() {\n return async (request: ProxyRequestParams): Promise<Result<any>> => {\n const config = typeof request === \"string\" ? {url: request} : request;\n try {\n const response = await axios.request(config);\n return ({\n ok: true,\n status: response.status,\n data: response.data,\n });\n } catch (err) {\n throw new BackendError(err.response?.status || 500, err.message);\n }\n };\n}\n","import {getDB, ReportsDB} from \"../../db\";\nimport {resultWrapper} from \"../lib\";\n\nimport {dbEntityFactory} from \"./entityCRUD\";\nimport {dbImageSaveFactory} from \"./image/imageSave\";\nimport {dbImageSearchFactory} from \"./image/imageSearch\";\nimport {dbReadMetadataFactory} from \"./readMetadata\";\nimport {dbRegenerateSearchFactory} from \"./regenerateSearch\";\nimport {dbSearchReportFactory} from \"./searchReport\";\nimport {dbUrlProxyFactory} from \"./urlProxy\";\n\nexport type PublicAPI = ReturnType<typeof apiFactory>;\n\nexport function useDatabaseApi(_, __, api) {\n return getDB().then((dbModels) => {\n Object.assign(api, apiFactory(dbModels));\n });\n}\n\nexport function apiFactory(dbModels: ReportsDB) {\n return {\n ...dbEntityFactory(dbModels),\n\n searchReport: resultWrapper(dbSearchReportFactory(dbModels)),\n\n readMetadata: resultWrapper(dbReadMetadataFactory(dbModels)),\n\n regenerateSearch: resultWrapper(dbRegenerateSearchFactory(dbModels)),\n\n imageFlickrSearch: dbImageSearchFactory(dbModels, \"flickr\"),\n imageLocalSearch: dbImageSearchFactory(dbModels, \"local\"),\n imageUnsplashSearch: dbImageSearchFactory(dbModels, \"unsplash\"),\n\n imageFlickrSave: dbImageSaveFactory(dbModels, \"flickr\"),\n imageLocalSave: dbImageSaveFactory(dbModels, \"local\"),\n imageUnsplashSave: dbImageSaveFactory(dbModels, \"unsplash\"),\n imageUploadSave: dbImageSaveFactory(dbModels, \"upload\"),\n\n urlProxy: dbUrlProxyFactory(),\n };\n}\n","import formidable from \"formidable\";\n\nexport default async function parseBody(req) {\n const form = new formidable.IncomingForm();\n form.encoding = \"utf-8\";\n const bodyData = await new Promise<{ fields: { [key: string]: any }, files: File[] }>((resolve, reject) => {\n form.parse(req, (err, fields, files) => {\n if (err) {\n reject(err);\n return;\n }\n resolve({fields, files});\n });\n });\n return {\n ...bodyData.fields,\n files: bodyData.files,\n };\n}\n","import yn from \"yn\";\n\nimport slugify from \"../../libs/js/slugify\";\nimport {PublicAPI} from \"../db\";\nimport {pickMethod} from \"../lib\";\nimport {EntityType} from \"../types\";\nimport {endpoint, normalizeList, parseFiniteNumber} from \"./lib\";\n\n/**\n * Generates 4 basic endpoints for the common CRUD operations.\n */\nexport function endpointCRUDFactory<T extends EntityType>(api: PublicAPI, entity: T) {\n const crudCreate = pickMethod(api, \"create\", entity);\n const crudRead = pickMethod(api, \"read\", entity);\n const crudUpdate = pickMethod(api, \"update\", entity);\n const crudDelete = pickMethod(api, \"delete\", entity);\n\n return [\n endpoint(\"POST\", `create/${entity}`, (req) => {\n // TODO: maybe strip unknown parameters\n const {body} = req;\n return crudCreate(body);\n }),\n endpoint(\"GET\", `read/${entity}`, (req) => {\n const params = req.query;\n const id = normalizeList(params.id).map(parseFiniteNumber);\n return crudRead({id, include: yn(params.include)});\n }),\n endpoint(\"POST\", `update/${entity}`, (req) => {\n // TODO: maybe strip unknown parameters\n const {body} = req;\n return crudUpdate(body);\n }),\n endpoint(\"DELETE\", `delete/${entity}`, (req) => {\n const id = parseFiniteNumber(req.body.id);\n return crudDelete(id);\n }),\n ] as const;\n}\n\n/**\n * Additionally to the 4 CRUD operations, this function also generates some\n * extra endpoints specific to the Variant entity type.\n */\nexport function endpointVariantCRUDFactory(api: PublicAPI) {\n const {validateVariantSlug} = api;\n return [\n ...endpointCRUDFactory(api, \"variant\"),\n\n endpoint(\"GET\", \"validate/variant\", (req) => {\n const params = req.query;\n const dimension = parseFiniteNumber(params.dimension);\n return validateVariantSlug({dimension, slug: slugify(params.slug)});\n }),\n ] as const;\n}\n","import {PublicAPI} from \"../../db\";\nimport {ImageSaveParams, ImageSaveProvider} from \"../../db/image/imageSave\";\nimport {BackendError, capitalize} from \"../../lib\";\nimport {endpoint} from \"../lib\";\n\n/*\n* Get image file itself\n* Example queries:\n* /api/cms/member/image.png?member=1&format=thumb\n*/\nexport function endpointImageSaveFactory(operations: PublicAPI, provider: ImageSaveProvider) {\n const saveMethodKey = `image${capitalize(provider)}Save` as const;\n const saveMethod = operations[saveMethodKey];\n\n return endpoint(\"POST\", `images/save/${provider}`, (req) => {\n const params = req.body as ImageSaveParams;\n if (!params.content_id) {\n throw new BackendError(400, \"Missing 'content_id' parameter.\");\n }\n if (!params.image_id) {\n throw new BackendError(400, \"Missing 'image_id' parameter.\");\n }\n return saveMethod(params);\n });\n}\n","import {PublicAPI} from \"../../db\";\nimport {ImageSearchProvider} from \"../../db/image/imageSearch\";\nimport {BackendError, capitalize} from \"../../lib\";\nimport {endpoint, normalizeList} from \"../lib\";\n\n/*\n* Get image file itself\n* Example queries:\n* /api/cms/member/image.png?member=1&format=thumb\n*/\nexport function endpointImageSearchFactory(operations: PublicAPI, provider: ImageSearchProvider) {\n const searchMethodKey = `image${capitalize(provider)}Search` as const;\n const searchMethod = operations[searchMethodKey];\n\n return endpoint(\"GET\", `images/search/${provider}`, async (req) => {\n const prompt = normalizeList(req.query.prompt)[0];\n\n // Return error if there is a missing param\n if (!prompt) {\n throw new BackendError(400, \"Empty 'prompt' param.\");\n }\n\n return searchMethod({prompt});\n });\n}\n","import {PublicAPI} from \"../db\";\nimport {endpoint} from \"./lib\";\n\n/**\n * Retrieve all metadata\n *\n * Example query:\n * /api/cms/read/metadata\n */\nexport function endpointReadMetadataFactory(operations: PublicAPI) {\n const {readMetadata} = operations;\n return endpoint(\"GET\", \"read/metadata\", () => readMetadata({}));\n}\n","import {PublicAPI} from \"../db\";\nimport {endpoint} from \"./lib\";\n\n/**\n * Force to regenerate the search index on demand\n *\n * Example queries:\n * /api/cms/search/regenerate\n */\nexport function endpointRegenerateSearchFactory(operations: PublicAPI) {\n const {regenerateSearch} = operations;\n return endpoint(\"POST\", \"search/regenerate\", () => regenerateSearch(undefined));\n}\n","import {NextApiRequest} from \"next\";\nimport {PublicAPI} from \"../db\";\nimport {SearchReportParams} from \"../types\";\nimport {endpoint, normalizeList} from \"./lib\";\nimport {parseSearchMemberParams} from \"./member\";\n\n/**\n * Retrieve visible members as profiles\n * Example queries:\n * /api/cms/search/reports?query=al&locale=en&limit=5&format=results\n * /api/cms/search/reports?query=al&locale=en&limit=5&format=profiles\n * /api/cms/search/reports?query=al&locale=es&limit=5&format=grouped\n */\nexport function endpointSearchReportFactory(operations: PublicAPI) {\n const {searchReport} = operations;\n\n return endpoint(\"GET\", \"search/reports\", (req) => {\n const params = parseSearchReportParams(req.query);\n return searchReport(params);\n });\n}\n\nexport function parseSearchReportParams(query: NextApiRequest[\"query\"]): SearchReportParams {\n return {\n ...parseSearchMemberParams(query),\n // TODO: setup a default value if parameter is not one of these values\n format: normalizeList(query.format)[0] as \"results\" | \"profiles\" | \"grouped\",\n };\n}\n","import {PublicAPI} from \"../db\";\nimport {endpoint, normalizeList} from \"./lib\";\n\n/**\n * Wrap url\n * Example query:\n * /api/cms/url/proxy\n */\nexport function endpointUrlProxyFactory(operations: PublicAPI) {\n const {urlProxy} = operations;\n\n return endpoint(\"GET\", \"url/proxy\", (req) => {\n const {url, method} = req.query;\n console.log(\"endpointUrlProxy\", url);\n\n return urlProxy({\n url: normalizeList(url)[0],\n method: normalizeList(method)[0] === \"POST\" ? \"POST\" : \"GET\",\n });\n });\n}\n","import {NextApiRequest, NextApiResponse} from \"next\";\nimport NextCors from \"nextjs-cors\";\n\nimport {getDB, ReportsDB} from \"../../db\";\nimport {apiFactory} from \"../db\";\nimport parseBody from \"../helpers/parseBody\";\nimport {BackendError} from \"../lib\";\n\nimport {endpointCRUDFactory, endpointVariantCRUDFactory} from \"./entityCRUD\";\nimport {endpointImageSaveFactory} from \"./image/imageSave\";\nimport {endpointImageSearchFactory} from \"./image/imageSearch\";\nimport {endpointMemberFactory} from \"./member\";\nimport {endpointReadMetadataFactory} from \"./readMetadata\";\nimport {endpointRegenerateSearchFactory} from \"./regenerateSearch\";\nimport {endpointSearchReportFactory} from \"./searchReport\";\nimport {endpointUrlProxyFactory} from \"./urlProxy\";\n\nimport getLogging from \"../../libs/configs/getLogging\";\n\nconst verbose = getLogging();\n\nexport function endpointKey(method: string, path: string) {\n return `${method.toUpperCase()} ${path.toLowerCase()}`;\n}\n\nexport type Endpoints = ReturnType<typeof getEndpointMap>;\n\nfunction getEndpointMap(db: ReportsDB) {\n const api = apiFactory(db);\n\n return Object.fromEntries([\n ...endpointCRUDFactory(api, \"block\"),\n ...endpointCRUDFactory(api, \"dimension\"),\n ...endpointCRUDFactory(api, \"formatter\"),\n ...endpointCRUDFactory(api, \"report\"),\n ...endpointCRUDFactory(api, \"section\"),\n ...endpointVariantCRUDFactory(api),\n\n ...endpointMemberFactory(api),\n\n endpointSearchReportFactory(api),\n\n endpointReadMetadataFactory(api),\n\n endpointRegenerateSearchFactory(api),\n\n endpointImageSaveFactory(api, \"flickr\"),\n endpointImageSaveFactory(api, \"local\"),\n endpointImageSaveFactory(api, \"unsplash\"),\n endpointImageSaveFactory(api, \"upload\"),\n\n endpointImageSearchFactory(api, \"flickr\"),\n endpointImageSearchFactory(api, \"local\"),\n endpointImageSearchFactory(api, \"unsplash\"),\n\n endpointUrlProxyFactory(api),\n\n ].map(({handler, method, path}) => [endpointKey(method, path), handler]));\n}\n\nconst endpointMap = getDB().then(getEndpointMap);\n\nexport async function endpointNextJsHandlerFactory(req: NextApiRequest, res: NextApiResponse): Promise<void> {\n await NextCors(req, res, {\n methods: [\"GET\", \"HEAD\", \"PUT\", \"PATCH\", \"POST\", \"DELETE\"],\n origin: \"*\",\n });\n\n const {query: queryParams, method} = req;\n const {path, ...query} = queryParams;\n\n if (path && method) {\n const handler = await endpointMap.then((map) => {\n const pathString = ([] as string[]).concat(path).join(\"/\");\n const key = endpointKey(method, pathString);\n return map[key];\n });\n\n if (handler) {\n /*\n * Because we set the parseBody to false at entrypoint level\n * We force here to parse the POST info by a third party lib,\n * including files to upload.\n */\n if ([\"POST\", \"DELETE\"].includes(method)) {\n req.body = await parseBody(req);\n }\n return Promise.resolve(req)\n .then(handler)\n .then((result) => {\n if (\"error\" in result) {\n throw new BackendError(result.status, result.error);\n }\n if (result.data instanceof Buffer) {\n const image = result.data;\n res.writeHead(result.status, {\"Content-Type\": \"image/png\"}).end(image, \"binary\");\n } else {\n res.status(result.status).json({data: result.data});\n }\n })\n .catch((err: BackendError) => {\n // Best case we remove all console.error from code and\n // throw errors to be collected here\n // Also maybe add external error monitoring here\n if (verbose) console.trace(err);\n res.status(err.code).json({error: err.message});\n });\n }\n } else if (!path) {\n // print on console the list of set up methods\n await endpointMap.then(console.log);\n }\n\n return res.status(404).json({error: \"No matching route\", path, query});\n}\n","import {NextApiRequest, NextApiResponse} from \"next\";\n\nconst reportsCrosswalkEntrypointFn = crosswalk => {\n const crosswalkFn = crosswalk;\n return async function (req: NextApiRequest, res: NextApiResponse): Promise<void> {\n const response = await crosswalkFn({test:'pala'});\n //TO-DO, validate response\n return res.json(response);\n }\n}\n\nexport default reportsCrosswalkEntrypointFn;\n"],"names":["__spreadProps","initModel","__spreadValues","date","libs","logicFactory","n","verbose","block","block_content","block_input","formatter","image","image_content","report","dimension","variant","search","search_content","section","SequelizeError","localeDefault","locales","config","path","accessor","idKey","labelKey","memberFetch","members","slug","__objRest","results","newRow","item"],"mappings":"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"}
|