source: imaps-frontend/node_modules/ajv-keywords/src/definitions/transform.ts

main
Last change on this file was 79a0317, checked in by stefan toskovski <stefantoska84@…>, 4 days ago

F4 Finalna Verzija

  • Property mode set to 100644
File size: 3.0 KB
Line 
1import type {CodeKeywordDefinition, AnySchemaObject, KeywordCxt, Code, Name} from "ajv"
2import {_, stringify, getProperty} from "ajv/dist/compile/codegen"
3
4type TransformName =
5 | "trimStart"
6 | "trimEnd"
7 | "trimLeft"
8 | "trimRight"
9 | "trim"
10 | "toLowerCase"
11 | "toUpperCase"
12 | "toEnumCase"
13
14interface TransformConfig {
15 hash: Record<string, string | undefined>
16}
17
18type Transform = (s: string, cfg?: TransformConfig) => string
19
20const transform: {[key in TransformName]: Transform} = {
21 trimStart: (s) => s.trimStart(),
22 trimEnd: (s) => s.trimEnd(),
23 trimLeft: (s) => s.trimStart(),
24 trimRight: (s) => s.trimEnd(),
25 trim: (s) => s.trim(),
26 toLowerCase: (s) => s.toLowerCase(),
27 toUpperCase: (s) => s.toUpperCase(),
28 toEnumCase: (s, cfg) => cfg?.hash[configKey(s)] || s,
29}
30
31const getDef: (() => CodeKeywordDefinition) & {
32 transform: typeof transform
33} = Object.assign(_getDef, {transform})
34
35function _getDef(): CodeKeywordDefinition {
36 return {
37 keyword: "transform",
38 schemaType: "array",
39 before: "enum",
40 code(cxt: KeywordCxt) {
41 const {gen, data, schema, parentSchema, it} = cxt
42 const {parentData, parentDataProperty} = it
43 const tNames: string[] = schema
44 if (!tNames.length) return
45 let cfg: Name | undefined
46 if (tNames.includes("toEnumCase")) {
47 const config = getEnumCaseCfg(parentSchema)
48 cfg = gen.scopeValue("obj", {ref: config, code: stringify(config)})
49 }
50 gen.if(_`typeof ${data} == "string" && ${parentData} !== undefined`, () => {
51 gen.assign(data, transformExpr(tNames.slice()))
52 gen.assign(_`${parentData}[${parentDataProperty}]`, data)
53 })
54
55 function transformExpr(ts: string[]): Code {
56 if (!ts.length) return data
57 const t = ts.pop() as string
58 if (!(t in transform)) throw new Error(`transform: unknown transformation ${t}`)
59 const func = gen.scopeValue("func", {
60 ref: transform[t as TransformName],
61 code: _`require("ajv-keywords/dist/definitions/transform").transform${getProperty(t)}`,
62 })
63 const arg = transformExpr(ts)
64 return cfg && t === "toEnumCase" ? _`${func}(${arg}, ${cfg})` : _`${func}(${arg})`
65 }
66 },
67 metaSchema: {
68 type: "array",
69 items: {type: "string", enum: Object.keys(transform)},
70 },
71 }
72}
73
74function getEnumCaseCfg(parentSchema: AnySchemaObject): TransformConfig {
75 // build hash table to enum values
76 const cfg: TransformConfig = {hash: {}}
77
78 // requires `enum` in the same schema as transform
79 if (!parentSchema.enum) throw new Error('transform: "toEnumCase" requires "enum"')
80 for (const v of parentSchema.enum) {
81 if (typeof v !== "string") continue
82 const k = configKey(v)
83 // requires all `enum` values have unique keys
84 if (cfg.hash[k]) {
85 throw new Error('transform: "toEnumCase" requires all lowercased "enum" values to be unique')
86 }
87 cfg.hash[k] = v
88 }
89
90 return cfg
91}
92
93function configKey(s: string): string {
94 return s.toLowerCase()
95}
96
97export default getDef
98module.exports = getDef
Note: See TracBrowser for help on using the repository browser.