|
1 | 1 | import forgetKeys from "./lib/forgetKeys"; |
2 | | -import type { Config, ConfigDefinition, Model } from "./types"; |
| 2 | +import type { |
| 3 | + CastFunction, |
| 4 | + Config, |
| 5 | + ConfigDefinition, |
| 6 | + DefaultCasts, |
| 7 | + Model, |
| 8 | +} from "./types"; |
| 9 | + |
| 10 | +const defaultCasts: Record<DefaultCasts, CastFunction> = { |
| 11 | + date: (date) => |
| 12 | + typeof date === "string" || typeof date === "number" |
| 13 | + ? new Date(date) |
| 14 | + : date, |
| 15 | + float: (float) => |
| 16 | + typeof float === "number" |
| 17 | + ? float |
| 18 | + : typeof float === "string" |
| 19 | + ? parseFloat(float) |
| 20 | + : float, |
| 21 | + int: (int) => |
| 22 | + typeof int === "number" |
| 23 | + ? int |
| 24 | + : typeof int === "string" |
| 25 | + ? parseInt(int) |
| 26 | + : int, |
| 27 | + string: (string) => (!string ? string : String(string)), |
| 28 | +}; |
3 | 29 |
|
4 | 30 | let globalConfig: Config = { |
| 31 | + casts: {}, |
5 | 32 | models: {}, |
6 | 33 | ignoreAttributes: [], |
7 | 34 | resolveModelName: (model) => (model as any)?.type || "", |
@@ -35,36 +62,49 @@ const resolveConfig = (baseConfig: Config, ...config: ConfigDefinition[]) => |
35 | 62 | ); |
36 | 63 |
|
37 | 64 | export const createModel = <Data extends object = {}>( |
38 | | - modelConfig: ConfigDefinition = {} |
| 65 | + modelConfig: ConfigDefinition<keyof Data> = {} |
39 | 66 | ) => |
40 | 67 | class BaseModel { |
41 | | - constructor(data: Data, localConfig: ConfigDefinition = {}) { |
| 68 | + constructor(data: Data, localConfig: ConfigDefinition<keyof Data> = {}) { |
42 | 69 | const { |
43 | 70 | resolveModelName, |
44 | 71 | resolveRelationshipNames, |
45 | 72 | ignoreAttributes, |
46 | 73 | models, |
| 74 | + casts, |
47 | 75 | } = resolveConfig(globalConfig, modelConfig, localConfig); |
48 | 76 | const relationships = resolveRelationshipNames(data); |
49 | 77 | const attributes = forgetKeys(data, [ |
50 | 78 | ...relationships, |
51 | 79 | ...ignoreAttributes, |
52 | 80 | ]); |
53 | 81 |
|
| 82 | + for (const [key, cast] of Object.entries(casts)) { |
| 83 | + const resolvedCast = |
| 84 | + typeof cast === "string" ? defaultCasts[cast] : cast || (() => null); |
| 85 | + if ((attributes as any)[key]) { |
| 86 | + (attributes as any)[key] = resolvedCast((attributes as any)[key]); |
| 87 | + } |
| 88 | + } |
| 89 | + |
54 | 90 | Object.assign(this, attributes); |
55 | 91 |
|
56 | 92 | for (const relationship of relationships) { |
57 | 93 | const relationData = data[relationship as keyof Data]; |
58 | 94 | const isMany = Array.isArray(relationData); |
59 | 95 | const RelationshipModel = |
60 | | - models[resolveModelName(isMany ? relationData?.[0] : relationData)]; |
| 96 | + models[ |
| 97 | + resolveModelName( |
| 98 | + isMany ? relationData?.[0] : relationData |
| 99 | + ) as string |
| 100 | + ]; |
61 | 101 |
|
62 | 102 | if (isMany ? !relationData.length : !relationData) { |
63 | 103 | return; |
64 | 104 | } |
65 | 105 |
|
66 | 106 | if (!RelationshipModel) { |
67 | | - console.error(`Model ${relationship} not registred.`); |
| 107 | + console.error(`Model ${relationship as string} not registred.`); |
68 | 108 | return; |
69 | 109 | } |
70 | 110 |
|
|
0 commit comments