@apisr/drizzle-model 0.0.4 → 2.0.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/DISCLAIMER.md +5 -0
- package/TODO.md +8 -61
- package/package.json +2 -1
- package/src/core/dialect.ts +81 -0
- package/src/core/index.ts +24 -0
- package/src/core/query/error.ts +15 -0
- package/src/core/query/joins.ts +596 -0
- package/src/core/query/projection.ts +136 -0
- package/src/core/query/where.ts +449 -0
- package/src/core/result.ts +297 -0
- package/src/core/runtime.ts +612 -0
- package/src/core/transform.ts +119 -0
- package/src/model/builder.ts +40 -6
- package/src/model/config.ts +9 -9
- package/src/model/format.ts +20 -8
- package/src/model/methods/exclude.ts +1 -7
- package/src/model/methods/return.ts +11 -11
- package/src/model/methods/select.ts +2 -8
- package/src/model/model.ts +10 -16
- package/src/model/query/error.ts +1 -0
- package/src/model/result.ts +134 -21
- package/src/types.ts +38 -0
- package/tests/base/count.test.ts +47 -0
- package/tests/base/delete.test.ts +90 -0
- package/tests/base/find.test.ts +209 -0
- package/tests/base/insert.test.ts +152 -0
- package/tests/base/safe.test.ts +91 -0
- package/tests/base/update.test.ts +88 -0
- package/tests/base/upsert.test.ts +121 -0
- package/tests/base.ts +21 -0
- package/src/model/core/joins.ts +0 -364
- package/src/model/core/projection.ts +0 -61
- package/src/model/core/runtime.ts +0 -334
- package/src/model/core/thenable.ts +0 -94
- package/src/model/core/transform.ts +0 -65
- package/src/model/core/where.ts +0 -249
- package/src/model/core/with.ts +0 -28
- package/tests/builder-v2-mysql.type-test.ts +0 -51
- package/tests/builder-v2.type-test.ts +0 -336
- package/tests/builder.test.ts +0 -63
- package/tests/find.test.ts +0 -166
- package/tests/insert.test.ts +0 -247
|
@@ -1,334 +0,0 @@
|
|
|
1
|
-
import { and } from "drizzle-orm";
|
|
2
|
-
import type { ModelDialect, ReturningIdDialects } from "../dialect.ts";
|
|
3
|
-
import type { MethodWhereValue } from "../methods/query/where.ts";
|
|
4
|
-
import type { MethodUpsertValue } from "../methods/upsert.ts";
|
|
5
|
-
import type { MethodWithValue } from "../methods/with.ts";
|
|
6
|
-
import type { ModelOptions } from "../options.ts";
|
|
7
|
-
import { buildSelectProjection } from "./projection.ts";
|
|
8
|
-
import type { MutateState, QueryState } from "./thenable.ts";
|
|
9
|
-
import { MutateResult, QueryResult } from "./thenable.ts";
|
|
10
|
-
import { applyExclude, applyFormat, applySelect } from "./transform.ts";
|
|
11
|
-
import { compileWhere } from "./where.ts";
|
|
12
|
-
import { runWithJoins } from "./with.ts";
|
|
13
|
-
|
|
14
|
-
type AnyObj = Record<string, any>;
|
|
15
|
-
|
|
16
|
-
type MutateKind = "insert" | "update" | "delete" | "upsert";
|
|
17
|
-
|
|
18
|
-
type BaseState = {
|
|
19
|
-
db: any;
|
|
20
|
-
where: unknown;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
// TODO: can be broken...
|
|
24
|
-
function compileEffectiveWhere(
|
|
25
|
-
table: AnyObj,
|
|
26
|
-
optionsWhere: unknown,
|
|
27
|
-
stateWhere: unknown
|
|
28
|
-
) {
|
|
29
|
-
const base = compileWhere(table, optionsWhere);
|
|
30
|
-
const extra = compileWhere(table, stateWhere);
|
|
31
|
-
if (base && extra) {
|
|
32
|
-
return and(base as any, extra as any);
|
|
33
|
-
}
|
|
34
|
-
return (base ?? extra) as any;
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
function isReturningIdDialect(dialect: string): dialect is ReturningIdDialects {
|
|
38
|
-
return (
|
|
39
|
-
dialect === "MySQL" ||
|
|
40
|
-
dialect === "SingleStore" ||
|
|
41
|
-
dialect === "CockroachDB"
|
|
42
|
-
);
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
async function execReturn(
|
|
46
|
-
q: any,
|
|
47
|
-
mState: MutateState,
|
|
48
|
-
dialect: string
|
|
49
|
-
): Promise<any> {
|
|
50
|
-
if (typeof q?.returning === "function") {
|
|
51
|
-
return await (mState.returnSelect
|
|
52
|
-
? q.returning(mState.returnSelect)
|
|
53
|
-
: q.returning());
|
|
54
|
-
}
|
|
55
|
-
if (isReturningIdDialect(dialect) && typeof q?.$returningId === "function") {
|
|
56
|
-
return await q.$returningId();
|
|
57
|
-
}
|
|
58
|
-
return await q;
|
|
59
|
-
}
|
|
60
|
-
|
|
61
|
-
function normalizeUpsertTarget(table: AnyObj, target: any): any {
|
|
62
|
-
if (!target) {
|
|
63
|
-
return target;
|
|
64
|
-
}
|
|
65
|
-
if (typeof target === "string") {
|
|
66
|
-
return (table as any)[target] ?? target;
|
|
67
|
-
}
|
|
68
|
-
if (Array.isArray(target)) {
|
|
69
|
-
return target.map((t) =>
|
|
70
|
-
typeof t === "string" ? ((table as any)[t] ?? t) : t
|
|
71
|
-
);
|
|
72
|
-
}
|
|
73
|
-
return target;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export function makeModelRuntime(config: {
|
|
77
|
-
db: any;
|
|
78
|
-
schema: Record<string, any>;
|
|
79
|
-
relations: Record<string, any>;
|
|
80
|
-
tableName: string;
|
|
81
|
-
dialect: ModelDialect;
|
|
82
|
-
options: ModelOptions<any, any, any, any>;
|
|
83
|
-
}): any {
|
|
84
|
-
const baseState: BaseState = {
|
|
85
|
-
db: config.db,
|
|
86
|
-
where: undefined as unknown,
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
const build = (state: BaseState): any => {
|
|
90
|
-
const modelObj: AnyObj = {
|
|
91
|
-
$model: "model",
|
|
92
|
-
$modelName: config.tableName,
|
|
93
|
-
$format: config.options.format,
|
|
94
|
-
$formatValue: undefined,
|
|
95
|
-
where(value: MethodWhereValue<any, any>) {
|
|
96
|
-
return build({ ...state, where: value });
|
|
97
|
-
},
|
|
98
|
-
include(value: MethodWithValue<any, any>) {
|
|
99
|
-
return value;
|
|
100
|
-
},
|
|
101
|
-
extend(nextOptions: any) {
|
|
102
|
-
return makeModelRuntime({
|
|
103
|
-
...config,
|
|
104
|
-
options: {
|
|
105
|
-
...config.options,
|
|
106
|
-
...nextOptions,
|
|
107
|
-
methods: {
|
|
108
|
-
...(nextOptions?.methods ?? {}),
|
|
109
|
-
...(config.options?.methods ?? {}),
|
|
110
|
-
},
|
|
111
|
-
format: nextOptions?.format ?? config.options?.format,
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
},
|
|
115
|
-
db(db: any) {
|
|
116
|
-
return makeModelRuntime({ ...config, db });
|
|
117
|
-
},
|
|
118
|
-
};
|
|
119
|
-
|
|
120
|
-
const attachMethods = (methods: AnyObj | undefined) => {
|
|
121
|
-
if (!methods) {
|
|
122
|
-
return;
|
|
123
|
-
}
|
|
124
|
-
for (const [key, fn] of Object.entries(methods)) {
|
|
125
|
-
if (typeof fn === "function") {
|
|
126
|
-
(modelObj as any)[key] = fn.bind(modelObj);
|
|
127
|
-
}
|
|
128
|
-
}
|
|
129
|
-
};
|
|
130
|
-
|
|
131
|
-
attachMethods(config.options.methods);
|
|
132
|
-
|
|
133
|
-
modelObj.findMany = () => {
|
|
134
|
-
const runner = async (qState: QueryState) => {
|
|
135
|
-
const table = (config.schema as any)[config.tableName];
|
|
136
|
-
const whereSql = compileEffectiveWhere(
|
|
137
|
-
table as AnyObj,
|
|
138
|
-
config.options.where,
|
|
139
|
-
state.where
|
|
140
|
-
);
|
|
141
|
-
|
|
142
|
-
let result: any;
|
|
143
|
-
if (qState.with) {
|
|
144
|
-
result = await runWithJoins({
|
|
145
|
-
db: config.db,
|
|
146
|
-
schema: config.schema,
|
|
147
|
-
relations: config.relations,
|
|
148
|
-
tableName: config.tableName,
|
|
149
|
-
table,
|
|
150
|
-
dialect: config.dialect,
|
|
151
|
-
whereSql,
|
|
152
|
-
qState,
|
|
153
|
-
kind: "many",
|
|
154
|
-
});
|
|
155
|
-
} else {
|
|
156
|
-
const { selectMap } = buildSelectProjection(
|
|
157
|
-
table as AnyObj,
|
|
158
|
-
qState.select as any,
|
|
159
|
-
qState.exclude as any
|
|
160
|
-
);
|
|
161
|
-
let q = (config.db as any).select(selectMap).from(table);
|
|
162
|
-
if (whereSql) {
|
|
163
|
-
q = q.where(whereSql);
|
|
164
|
-
}
|
|
165
|
-
result = await q;
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
let out: any = result;
|
|
169
|
-
if (qState.select) {
|
|
170
|
-
out = applySelect(out, qState.select);
|
|
171
|
-
}
|
|
172
|
-
if (qState.exclude) {
|
|
173
|
-
out = applyExclude(out, qState.exclude);
|
|
174
|
-
}
|
|
175
|
-
if (!qState.raw) {
|
|
176
|
-
out = applyFormat(out, config.options.format);
|
|
177
|
-
}
|
|
178
|
-
return out;
|
|
179
|
-
};
|
|
180
|
-
|
|
181
|
-
return new QueryResult({} as QueryState, runner) as any;
|
|
182
|
-
};
|
|
183
|
-
|
|
184
|
-
modelObj.findFirst = () => {
|
|
185
|
-
const runner = async (qState: QueryState) => {
|
|
186
|
-
const table = (config.schema as any)[config.tableName];
|
|
187
|
-
const whereSql = compileEffectiveWhere(
|
|
188
|
-
table as AnyObj,
|
|
189
|
-
config.options.where,
|
|
190
|
-
state.where
|
|
191
|
-
);
|
|
192
|
-
|
|
193
|
-
let result: any;
|
|
194
|
-
if (qState.with) {
|
|
195
|
-
result = await runWithJoins({
|
|
196
|
-
db: config.db,
|
|
197
|
-
schema: config.schema,
|
|
198
|
-
relations: config.relations,
|
|
199
|
-
tableName: config.tableName,
|
|
200
|
-
table,
|
|
201
|
-
dialect: config.dialect,
|
|
202
|
-
whereSql,
|
|
203
|
-
qState,
|
|
204
|
-
kind: "one",
|
|
205
|
-
});
|
|
206
|
-
} else {
|
|
207
|
-
const { selectMap } = buildSelectProjection(
|
|
208
|
-
table as AnyObj,
|
|
209
|
-
qState.select as any,
|
|
210
|
-
qState.exclude as any
|
|
211
|
-
);
|
|
212
|
-
let q = (config.db as any).select(selectMap).from(table);
|
|
213
|
-
if (whereSql) {
|
|
214
|
-
q = q.where(whereSql);
|
|
215
|
-
}
|
|
216
|
-
q = q.limit(1);
|
|
217
|
-
const rows = await q;
|
|
218
|
-
result = rows[0];
|
|
219
|
-
}
|
|
220
|
-
|
|
221
|
-
let out: any = result;
|
|
222
|
-
if (qState.select) {
|
|
223
|
-
out = applySelect(out, qState.select);
|
|
224
|
-
}
|
|
225
|
-
if (qState.exclude) {
|
|
226
|
-
out = applyExclude(out, qState.exclude);
|
|
227
|
-
}
|
|
228
|
-
if (!qState.raw) {
|
|
229
|
-
out = applyFormat(out, config.options.format);
|
|
230
|
-
}
|
|
231
|
-
return out;
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
return new QueryResult({} as QueryState, runner) as any;
|
|
235
|
-
};
|
|
236
|
-
|
|
237
|
-
modelObj.insert = (value: any) => {
|
|
238
|
-
const runner = async (mState: MutateState) => {
|
|
239
|
-
const table = (config.schema as any)[config.tableName];
|
|
240
|
-
const q = (config.db as any).insert(table).values(mState.value);
|
|
241
|
-
const result = await execReturn(q, mState, config.dialect);
|
|
242
|
-
if (!Array.isArray(mState.value) && Array.isArray(result)) {
|
|
243
|
-
return result[0];
|
|
244
|
-
}
|
|
245
|
-
return result;
|
|
246
|
-
};
|
|
247
|
-
|
|
248
|
-
return new MutateResult(
|
|
249
|
-
{ kind: "insert" as MutateKind, value } as MutateState,
|
|
250
|
-
runner
|
|
251
|
-
) as any;
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
modelObj.update = (value: any) => {
|
|
255
|
-
const runner = async (mState: MutateState) => {
|
|
256
|
-
const table = (config.schema as any)[config.tableName];
|
|
257
|
-
const whereSql = compileEffectiveWhere(
|
|
258
|
-
table as AnyObj,
|
|
259
|
-
config.options.where,
|
|
260
|
-
state.where
|
|
261
|
-
);
|
|
262
|
-
let q = (config.db as any).update(table).set(mState.value);
|
|
263
|
-
if (whereSql) {
|
|
264
|
-
q = q.where(whereSql);
|
|
265
|
-
}
|
|
266
|
-
return await execReturn(q, mState, config.dialect);
|
|
267
|
-
};
|
|
268
|
-
|
|
269
|
-
return new MutateResult(
|
|
270
|
-
{ kind: "update" as MutateKind, value } as MutateState,
|
|
271
|
-
runner
|
|
272
|
-
) as any;
|
|
273
|
-
};
|
|
274
|
-
|
|
275
|
-
modelObj.delete = () => {
|
|
276
|
-
const runner = async (mState: MutateState) => {
|
|
277
|
-
const table = (config.schema as any)[config.tableName];
|
|
278
|
-
const whereSql = compileEffectiveWhere(
|
|
279
|
-
table as AnyObj,
|
|
280
|
-
config.options.where,
|
|
281
|
-
state.where
|
|
282
|
-
);
|
|
283
|
-
let q = (config.db as any).delete(table);
|
|
284
|
-
if (whereSql) {
|
|
285
|
-
q = q.where(whereSql);
|
|
286
|
-
}
|
|
287
|
-
return await execReturn(q, mState, config.dialect);
|
|
288
|
-
};
|
|
289
|
-
|
|
290
|
-
return new MutateResult(
|
|
291
|
-
{ kind: "delete" as MutateKind } as MutateState,
|
|
292
|
-
runner
|
|
293
|
-
) as any;
|
|
294
|
-
};
|
|
295
|
-
|
|
296
|
-
modelObj.upsert = (value: MethodUpsertValue<any>) => {
|
|
297
|
-
const runner = async (mState: MutateState) => {
|
|
298
|
-
const table = (config.schema as any)[config.tableName];
|
|
299
|
-
const insertValues = (mState.value as any).insert;
|
|
300
|
-
const updateCfg = (mState.value as any).update;
|
|
301
|
-
const target = normalizeUpsertTarget(
|
|
302
|
-
table as AnyObj,
|
|
303
|
-
(mState.value as any).target
|
|
304
|
-
);
|
|
305
|
-
let updateSet = updateCfg;
|
|
306
|
-
if (typeof updateCfg === "function") {
|
|
307
|
-
updateSet = updateCfg({
|
|
308
|
-
excluded: (field: string) => (table as any)[field],
|
|
309
|
-
inserted: (field: string) => (table as any)[field],
|
|
310
|
-
});
|
|
311
|
-
}
|
|
312
|
-
|
|
313
|
-
let q = (config.db as any).insert(table).values(insertValues);
|
|
314
|
-
if (q.onConflictDoUpdate) {
|
|
315
|
-
q = q.onConflictDoUpdate({
|
|
316
|
-
target,
|
|
317
|
-
set: updateSet,
|
|
318
|
-
});
|
|
319
|
-
}
|
|
320
|
-
|
|
321
|
-
return await execReturn(q, mState, config.dialect);
|
|
322
|
-
};
|
|
323
|
-
|
|
324
|
-
return new MutateResult(
|
|
325
|
-
{ kind: "upsert" as MutateKind, value } as MutateState,
|
|
326
|
-
runner
|
|
327
|
-
) as any;
|
|
328
|
-
};
|
|
329
|
-
|
|
330
|
-
return modelObj;
|
|
331
|
-
};
|
|
332
|
-
|
|
333
|
-
return build(baseState);
|
|
334
|
-
}
|
|
@@ -1,94 +0,0 @@
|
|
|
1
|
-
import type { MethodExcludeValue } from "../methods/exclude.ts";
|
|
2
|
-
import type { MethodSelectValue } from "../methods/select.ts";
|
|
3
|
-
import type { MethodWithValue } from "../methods/with.ts";
|
|
4
|
-
|
|
5
|
-
type AnyObj = Record<string, any>;
|
|
6
|
-
|
|
7
|
-
type QueryState = {
|
|
8
|
-
where?: unknown;
|
|
9
|
-
with?: unknown;
|
|
10
|
-
raw?: boolean;
|
|
11
|
-
select?: AnyObj;
|
|
12
|
-
exclude?: AnyObj;
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
type MutateKind = "insert" | "update" | "delete" | "upsert";
|
|
16
|
-
|
|
17
|
-
type MutateState = {
|
|
18
|
-
kind: MutateKind;
|
|
19
|
-
where?: unknown;
|
|
20
|
-
value?: unknown;
|
|
21
|
-
returnSelect?: AnyObj;
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
export class ThenableResult<T> implements PromiseLike<T> {
|
|
25
|
-
protected _execute: () => Promise<T>;
|
|
26
|
-
|
|
27
|
-
constructor(execute: () => Promise<T>) {
|
|
28
|
-
this._execute = execute;
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
then<TResult1 = T, TResult2 = never>(
|
|
32
|
-
onfulfilled?: ((value: T) => TResult1 | PromiseLike<TResult1>) | null,
|
|
33
|
-
onrejected?: ((reason: any) => TResult2 | PromiseLike<TResult2>) | null
|
|
34
|
-
): Promise<TResult1 | TResult2> {
|
|
35
|
-
return this._execute().then(onfulfilled as any, onrejected as any);
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
export class QueryResult<T> extends ThenableResult<T> {
|
|
40
|
-
private state: QueryState;
|
|
41
|
-
private runner: (state: QueryState) => Promise<T>;
|
|
42
|
-
|
|
43
|
-
constructor(state: QueryState, runner: (state: QueryState) => Promise<T>) {
|
|
44
|
-
super(() => runner(state));
|
|
45
|
-
this.state = state;
|
|
46
|
-
this.runner = runner;
|
|
47
|
-
}
|
|
48
|
-
|
|
49
|
-
with(value: MethodWithValue<any, any>): any {
|
|
50
|
-
return new QueryResult({ ...this.state, with: value }, this.runner) as any;
|
|
51
|
-
}
|
|
52
|
-
|
|
53
|
-
select(value: MethodSelectValue<any>): any {
|
|
54
|
-
return new QueryResult(
|
|
55
|
-
{ ...this.state, select: value as any },
|
|
56
|
-
this.runner
|
|
57
|
-
) as any;
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
exclude(value: MethodExcludeValue<any>): any {
|
|
61
|
-
return new QueryResult(
|
|
62
|
-
{ ...this.state, exclude: value as any },
|
|
63
|
-
this.runner
|
|
64
|
-
) as any;
|
|
65
|
-
}
|
|
66
|
-
|
|
67
|
-
raw(): any {
|
|
68
|
-
return new QueryResult({ ...this.state, raw: true }, this.runner) as any;
|
|
69
|
-
}
|
|
70
|
-
|
|
71
|
-
debug(): any {
|
|
72
|
-
return this.state;
|
|
73
|
-
}
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
export class MutateResult<T> extends ThenableResult<T> {
|
|
77
|
-
private state: MutateState;
|
|
78
|
-
private runner: (state: MutateState) => Promise<T>;
|
|
79
|
-
|
|
80
|
-
constructor(state: MutateState, runner: (state: MutateState) => Promise<T>) {
|
|
81
|
-
super(() => runner(state));
|
|
82
|
-
this.state = state;
|
|
83
|
-
this.runner = runner;
|
|
84
|
-
}
|
|
85
|
-
|
|
86
|
-
return(value?: AnyObj): any {
|
|
87
|
-
return new MutateResult(
|
|
88
|
-
{ ...this.state, returnSelect: value },
|
|
89
|
-
this.runner
|
|
90
|
-
) as any;
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
|
|
94
|
-
export type { QueryState, MutateState, MutateKind };
|
|
@@ -1,65 +0,0 @@
|
|
|
1
|
-
type AnyObj = Record<string, any>;
|
|
2
|
-
|
|
3
|
-
export function applySelect(value: any, select: AnyObj): any {
|
|
4
|
-
if (value == null) {
|
|
5
|
-
return value;
|
|
6
|
-
}
|
|
7
|
-
if (Array.isArray(value)) {
|
|
8
|
-
return value.map((v) => applySelect(v, select));
|
|
9
|
-
}
|
|
10
|
-
if (typeof value !== "object") {
|
|
11
|
-
return value;
|
|
12
|
-
}
|
|
13
|
-
|
|
14
|
-
const out: AnyObj = {};
|
|
15
|
-
for (const [key, sel] of Object.entries(select)) {
|
|
16
|
-
if (sel === true) {
|
|
17
|
-
out[key] = (value as any)[key];
|
|
18
|
-
continue;
|
|
19
|
-
}
|
|
20
|
-
if (sel && typeof sel === "object") {
|
|
21
|
-
out[key] = applySelect((value as any)[key], sel as AnyObj);
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
return out;
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
export function applyExclude(value: any, exclude: AnyObj): any {
|
|
28
|
-
if (value == null) {
|
|
29
|
-
return value;
|
|
30
|
-
}
|
|
31
|
-
if (Array.isArray(value)) {
|
|
32
|
-
return value.map((v) => applyExclude(v, exclude));
|
|
33
|
-
}
|
|
34
|
-
if (typeof value !== "object") {
|
|
35
|
-
return value;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
const out: AnyObj = { ...(value as AnyObj) };
|
|
39
|
-
for (const [key, ex] of Object.entries(exclude)) {
|
|
40
|
-
if (ex === true) {
|
|
41
|
-
delete out[key];
|
|
42
|
-
continue;
|
|
43
|
-
}
|
|
44
|
-
if (ex && typeof ex === "object" && key in out) {
|
|
45
|
-
out[key] = applyExclude(out[key], ex as AnyObj);
|
|
46
|
-
}
|
|
47
|
-
}
|
|
48
|
-
return out;
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
export function applyFormat(value: any, format: any): any {
|
|
52
|
-
if (!format) {
|
|
53
|
-
return value;
|
|
54
|
-
}
|
|
55
|
-
if (value == null) {
|
|
56
|
-
return value;
|
|
57
|
-
}
|
|
58
|
-
if (Array.isArray(value)) {
|
|
59
|
-
return value.map((v) => applyFormat(v, format));
|
|
60
|
-
}
|
|
61
|
-
if (typeof value !== "object") {
|
|
62
|
-
return value;
|
|
63
|
-
}
|
|
64
|
-
return format(value);
|
|
65
|
-
}
|