akanjs 2.2.4-rc.3 → 2.2.4-rc.4
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/constant/getDefault.ts
CHANGED
|
@@ -6,7 +6,7 @@ export const getDefault = <T>(fieldObj: FieldObject): DefaultOf<T> => {
|
|
|
6
6
|
const result: Record<string, unknown> = {};
|
|
7
7
|
for (const [key, field] of Object.entries(fieldObj)) {
|
|
8
8
|
if (field.fieldType === "hidden") result[key] = null;
|
|
9
|
-
else if (field.default) {
|
|
9
|
+
else if (field.default !== undefined && field.default !== null) {
|
|
10
10
|
if (typeof field.default === "function") result[key] = (field.default as () => object)();
|
|
11
11
|
else result[key] = field.default as object;
|
|
12
12
|
} else if (field.isArray) result[key] = [];
|
package/package.json
CHANGED
|
@@ -4,7 +4,7 @@ import { mkdir } from "node:fs/promises";
|
|
|
4
4
|
import path from "node:path";
|
|
5
5
|
import type { InArgs, InValue, Client as LibsqlClient } from "@libsql/client";
|
|
6
6
|
import { type BaseEnv, dayjs, FIELD_META, type PromiseOrObject } from "akanjs/base";
|
|
7
|
-
import type
|
|
7
|
+
import { type ConstantModel, getDefault } from "akanjs/constant";
|
|
8
8
|
import {
|
|
9
9
|
createDocumentId,
|
|
10
10
|
type DatabaseModel,
|
|
@@ -773,6 +773,9 @@ export class SqliteDocumentStore {
|
|
|
773
773
|
} else {
|
|
774
774
|
doc[key] = value;
|
|
775
775
|
}
|
|
776
|
+
if ((props.isClass as boolean) && (props.isScalar as boolean) && doc[key] !== undefined && doc[key] !== null) {
|
|
777
|
+
doc[key] = this.applyNestedDefaults(doc[key], props);
|
|
778
|
+
}
|
|
776
779
|
if (props.enum && doc[key] !== undefined && doc[key] !== null) {
|
|
777
780
|
const values = Array.isArray(doc[key]) ? doc[key] : [doc[key]];
|
|
778
781
|
const fieldEnum = props.enum as { has: (value: unknown) => boolean } | undefined;
|
|
@@ -958,12 +961,28 @@ export class SqliteDocumentStore {
|
|
|
958
961
|
|
|
959
962
|
private decodeDocumentPayload(payload: Record<string, unknown>) {
|
|
960
963
|
const fields = this.database.doc[FIELD_META] as unknown as FieldMap;
|
|
961
|
-
|
|
962
|
-
|
|
963
|
-
|
|
964
|
-
|
|
965
|
-
|
|
966
|
-
|
|
964
|
+
const result: Record<string, unknown> = {};
|
|
965
|
+
for (const [key, fieldMeta] of Object.entries(fields)) {
|
|
966
|
+
if (BASE_COLUMNS.has(key)) continue;
|
|
967
|
+
const props = fieldMeta.getProps();
|
|
968
|
+
const value = payload[key];
|
|
969
|
+
if (value === undefined) {
|
|
970
|
+
const def = props.default;
|
|
971
|
+
if (def !== undefined && def !== null) {
|
|
972
|
+
result[key] = typeof def === "function" ? (def as (data: unknown) => unknown)(payload) : def;
|
|
973
|
+
} else if (props.nullable) {
|
|
974
|
+
result[key] = null;
|
|
975
|
+
}
|
|
976
|
+
} else {
|
|
977
|
+
result[key] = this.decodeFieldValue(value, props);
|
|
978
|
+
}
|
|
979
|
+
}
|
|
980
|
+
for (const [key, value] of Object.entries(payload)) {
|
|
981
|
+
if (key in result || BASE_COLUMNS.has(key)) continue;
|
|
982
|
+
const props = fields[key]?.getProps?.();
|
|
983
|
+
result[key] = props ? this.decodeFieldValue(value, props) : value;
|
|
984
|
+
}
|
|
985
|
+
return result;
|
|
967
986
|
}
|
|
968
987
|
|
|
969
988
|
private decodeFieldValue(value: unknown, props: Record<string, unknown>): unknown {
|
|
@@ -991,12 +1010,39 @@ export class SqliteDocumentStore {
|
|
|
991
1010
|
if (!props.isClass || !props.isScalar) return value;
|
|
992
1011
|
const scalarFields = (props.modelRef as { [FIELD_META]?: FieldMap } | undefined)?.[FIELD_META];
|
|
993
1012
|
if (!scalarFields) return value;
|
|
994
|
-
|
|
995
|
-
|
|
996
|
-
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1013
|
+
const source = value as Record<string, unknown>;
|
|
1014
|
+
const defaults = getDefault(scalarFields as never) as Record<string, unknown>;
|
|
1015
|
+
const result: Record<string, unknown> = {};
|
|
1016
|
+
for (const [key, fieldMeta] of Object.entries(scalarFields)) {
|
|
1017
|
+
const nestedProps = fieldMeta.getProps();
|
|
1018
|
+
const nested = source[key];
|
|
1019
|
+
result[key] = nested === undefined ? defaults[key] : this.decodeFieldValue(nested, nestedProps);
|
|
1020
|
+
}
|
|
1021
|
+
for (const [key, nested] of Object.entries(source)) {
|
|
1022
|
+
if (!(key in result)) result[key] = nested;
|
|
1023
|
+
}
|
|
1024
|
+
return result;
|
|
1025
|
+
}
|
|
1026
|
+
|
|
1027
|
+
private applyNestedDefaults(value: unknown, props: Record<string, unknown>): unknown {
|
|
1028
|
+
if (value === undefined || value === null) return value;
|
|
1029
|
+
if (!props.isClass || !props.isScalar) return value;
|
|
1030
|
+
if (Array.isArray(value)) return value.map((item) => this.fillScalarDefaults(item, props));
|
|
1031
|
+
return this.fillScalarDefaults(value, props);
|
|
1032
|
+
}
|
|
1033
|
+
|
|
1034
|
+
private fillScalarDefaults(value: unknown, props: Record<string, unknown>): unknown {
|
|
1035
|
+
if (!value || typeof value !== "object") return value;
|
|
1036
|
+
const scalarFields = (props.modelRef as { [FIELD_META]?: FieldMap } | undefined)?.[FIELD_META];
|
|
1037
|
+
if (!scalarFields) return value;
|
|
1038
|
+
const defaults = getDefault(scalarFields as never) as Record<string, unknown>;
|
|
1039
|
+
const result = { ...(value as Record<string, unknown>) };
|
|
1040
|
+
for (const [key, fieldMeta] of Object.entries(scalarFields)) {
|
|
1041
|
+
const nestedProps = fieldMeta.getProps();
|
|
1042
|
+
if (result[key] === undefined) result[key] = defaults[key];
|
|
1043
|
+
else result[key] = this.applyNestedDefaults(result[key], nestedProps);
|
|
1044
|
+
}
|
|
1045
|
+
return result;
|
|
1000
1046
|
}
|
|
1001
1047
|
|
|
1002
1048
|
hydrate(data: DocumentRecord, originalData: DocumentRecord = data) {
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { Database } from "bun:sqlite";
|
|
2
2
|
import type { Client as LibsqlClient } from "@libsql/client";
|
|
3
3
|
import { type BaseEnv, type PromiseOrObject } from "akanjs/base";
|
|
4
|
-
import type
|
|
4
|
+
import { type ConstantModel } from "akanjs/constant";
|
|
5
5
|
import { type DatabaseModel, type DocumentQuery, type DocumentSchema, type DocumentUpdate, type DocumentUpdateOptions, type SchemaOf } from "akanjs/document";
|
|
6
6
|
import type { Sql } from "postgres";
|
|
7
7
|
export interface SqliteDatabaseConfig {
|
|
@@ -256,6 +256,8 @@ export declare class SqliteDocumentStore {
|
|
|
256
256
|
private decodeFieldValue;
|
|
257
257
|
private decodeMapValue;
|
|
258
258
|
private decodeNestedValue;
|
|
259
|
+
private applyNestedDefaults;
|
|
260
|
+
private fillScalarDefaults;
|
|
259
261
|
hydrate(data: DocumentRecord, originalData?: DocumentRecord): any;
|
|
260
262
|
private runHooks;
|
|
261
263
|
private insertStmt;
|
package/ui/Dialog/Modal.tsx
CHANGED
|
@@ -185,7 +185,7 @@ export const Modal = ({ className, bodyClassName, confirmClose, children, onCanc
|
|
|
185
185
|
return createPortal(
|
|
186
186
|
<>
|
|
187
187
|
<div
|
|
188
|
-
className={clsx("fixed inset-0 z-10", showBackground && "animate-fadeIn bg-
|
|
188
|
+
className={clsx("fixed inset-0 z-10", showBackground && "animate-fadeIn bg-black/50 backdrop-blur-md")}
|
|
189
189
|
onClick={(event) => {
|
|
190
190
|
if (event.target !== event.currentTarget) return;
|
|
191
191
|
requestClose();
|