Skip to content

Commit e5c8235

Browse files
authored
Merge recent fixes and features (#14)
2 parents 706c542 + 3eef235 commit e5c8235

File tree

11 files changed

+139
-22
lines changed

11 files changed

+139
-22
lines changed

deno.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@inspatial/cloud",
3-
"version": "0.1.6",
3+
"version": "0.1.7",
44
"license": "Apache-2.0",
55
"exports": {
66
".": "./mod.ts",

extensions/flutter/actions/generate-models.ts

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,35 @@ function generateFlutterModel(
112112
lines.push(...constructorClass);
113113
lines.push("}");
114114

115+
if (type === "Entry") {
116+
const listModelLines = generateListModel(entryOrChildType as EntryType);
117+
lines.push(...listModelLines);
118+
}
119+
return lines;
120+
}
121+
122+
function generateListModel(entryType: EntryType): Array<string> {
123+
const listFields = new Map();
124+
entryType.defaultListFields.forEach((fieldKey) => {
125+
listFields.set(fieldKey, entryType.fields.get(fieldKey));
126+
});
127+
const listType = {
128+
...entryType,
129+
name: entryType.name + "List",
130+
fields: listFields,
131+
children: undefined,
132+
} as EntryType;
133+
const className = convertString(listType.name, "pascal", true);
134+
const lines: string[] = [
135+
`final class ${className} extends Entry {`,
136+
];
137+
const fields = generateFieldDefs(listType.fields);
138+
lines.push(...fields);
139+
const converting = generateJsonConverting(listType, "Entry");
140+
lines.push(...converting);
141+
const constructorClass = generateConstructor(listType, "Entry");
142+
lines.push(...constructorClass);
143+
lines.push("}");
115144
return lines;
116145
}
117146
function shouldIgnoreField(field: InField) {

src/orm/child-entry/child-entry.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -225,7 +225,7 @@ export class ChildEntryList<T extends Record<string, unknown> = any> {
225225
}
226226

227227
await this.deleteStaleRecords();
228-
this.load(this._parentId);
228+
await this.load(this._parentId);
229229
}
230230
async #refreshFetchedFields(child: ChildEntry): Promise<void> {
231231
for (const field of this._fields.values()) {

src/orm/db/db-types.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,11 @@ export interface ListOptions<T extends EntryBase = EntryBase> {
124124
order?: "asc" | "desc";
125125
}
126126

127-
export type DBFilter = Array<
128-
InFilter
129-
>;
127+
export type DBFilter =
128+
| Array<
129+
InFilter
130+
>
131+
| Record<string, string | number | null | boolean>;
130132

131133
export interface DBListOptions {
132134
columns?:

src/orm/db/filters.ts

Lines changed: 20 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
1-
import type { DBFilter, FilterAll } from "#/orm/db/db-types.ts";
1+
import type { DBFilter, FilterAll, InFilter } from "#/orm/db/db-types.ts";
22
import { raiseORMException } from "#/orm/orm-exception.ts";
33
import { formatColumnName, formatDbValue } from "#/orm/db/utils.ts";
44

5-
export function makeFilterQuery(filters: DBFilter): Array<string> {
5+
export function makeFilterQuery(dbFilter: DBFilter): Array<string> {
66
const filterQ: Array<string> = [];
7+
const filters: Array<InFilter> = [];
8+
if (Array.isArray(dbFilter)) {
9+
filters.push(...dbFilter);
10+
} else if (typeof dbFilter === "object") {
11+
Object.entries(dbFilter).map(([key, value]) => {
12+
if (value === null) {
13+
return {
14+
field: key,
15+
op: "isEmpty",
16+
};
17+
}
18+
return {
19+
field: key,
20+
op: "=",
21+
value,
22+
};
23+
}) as Array<InFilter>;
24+
}
725
for (const filter of filters) {
826
let filterString = "";
927
const strings: Array<string> = [];

src/orm/entry/entry-type.ts

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@ export class EntryType<
2424
FK extends PropertyKey = ExtractFieldKeys<E>,
2525
> extends BaseType<N> {
2626
config: EntryTypeConfig;
27-
defaultListFields: Set<string> = new Set(["id", "createdAt", "updatedAt"]);
27+
defaultListFields: Set<string> = new Set(["id"]);
2828
defaultSortField?: FK;
2929
defaultSortDirection?: "asc" | "desc" = "asc";
3030
actions: Map<string, EntryActionDefinition> = new Map();
@@ -40,7 +40,7 @@ export class EntryType<
4040
};
4141
constructor(
4242
name: N,
43-
config: BaseConfig & {
43+
config: BaseConfig<FK> & {
4444
/**
4545
* The field to use as the display value instead of the ID.
4646
*/
@@ -57,8 +57,8 @@ export class EntryType<
5757
},
5858
) {
5959
super(name, config);
60-
this.defaultSortField = config.defaultSortField;
61-
this.defaultSortDirection = config.defaultSortDirection;
60+
this.defaultSortField = config.defaultSortField || "id" as FK;
61+
this.defaultSortDirection = config.defaultSortDirection || "asc";
6262
this.fields.set("id", {
6363
key: "id",
6464
type: "IDField",
@@ -112,6 +112,8 @@ export class EntryType<
112112
this.defaultListFields.add(fieldKey);
113113
}
114114
}
115+
this.defaultListFields.add("updatedAt");
116+
this.defaultListFields.add("createdAt");
115117
if (this.config.titleField) {
116118
this.defaultListFields.add(this.config.titleField);
117119
}

src/orm/inspatial-orm.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ import { inLog } from "#/in-log/in-log.ts";
3535
import { ConnectionRegistry } from "#/orm/registry/connection-registry.ts";
3636
import type { InValue } from "#/orm/field/types.ts";
3737
import { registerFetchFields } from "#/orm/setup/setup-utils.ts";
38+
import { IDValue } from "./entry/types.ts";
3839

3940
export class InSpatialORM {
4041
db: InSpatialDB;
@@ -287,7 +288,7 @@ export class InSpatialORM {
287288
*/
288289
async getEntry<E extends EntryBase = GenericEntry>(
289290
entryType: string,
290-
id: string,
291+
id: IDValue,
291292
user?: SessionData,
292293
): Promise<E> {
293294
const entry = this.#getEntryInstance(entryType, user) as E;

src/orm/migrate/entry-type/entry-type-migrator.ts

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -160,7 +160,6 @@ export class EntryTypeMigrator<T extends EntryType | ChildEntryType>
160160
continue;
161161
}
162162
const titleField = this.entryType.connectionTitleFields.get(field.key);
163-
164163
if (titleField) {
165164
const ormTitleField = this.orm._getFieldType(titleField.type);
166165
const dbTitleColumn = ormTitleField.generateDbColumn(titleField);
@@ -209,12 +208,12 @@ export class EntryTypeMigrator<T extends EntryType | ChildEntryType>
209208
}
210209
async #checkTableInfo(): Promise<void> {
211210
const tableExists = await this.db.tableExists(this.#tableName);
212-
const newDescription = this.entryType.config.description;
211+
const newDescription = this.entryType.config.description || null;
213212
if (!tableExists) {
214213
this.migrationPlan.table.create = true;
215214
this.migrationPlan.table.updateDescription = {
216215
from: "",
217-
to: newDescription,
216+
to: newDescription ?? "",
218217
};
219218
return;
220219
}
@@ -223,7 +222,7 @@ export class EntryTypeMigrator<T extends EntryType | ChildEntryType>
223222
if (existingDescription != newDescription) {
224223
this.migrationPlan.table.updateDescription = {
225224
from: existingDescription,
226-
to: newDescription,
225+
to: newDescription ?? "",
227226
};
228227
}
229228
}

src/orm/setup/setup-utils.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -137,7 +137,7 @@ function buildConnectionTitleField(
137137
connectionEntryType: EntryType,
138138
): InField | undefined {
139139
const titleFieldKey = connectionEntryType.config.titleField;
140-
if (!titleFieldKey) {
140+
if (!titleFieldKey || titleFieldKey === "id") {
141141
return;
142142
}
143143

src/orm/shared/base-type-class.ts

Lines changed: 53 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,21 @@
11
import { raiseORMException } from "#/orm/orm-exception.ts";
22
import convertString from "#/utils/convert-string.ts";
33
import type { ChildEntryType } from "#/orm/child-entry/child-entry.ts";
4-
import type { BaseTypeInfo } from "#/orm/shared/shared-types.ts";
4+
import type {
5+
BaseTypeInfo,
6+
FieldGroup,
7+
FieldGroupConfig,
8+
} from "#/orm/shared/shared-types.ts";
59
import type { InField } from "#/orm/field/field-def-types.ts";
610

711
export class BaseType<N extends string = string> {
812
name: N;
913
label: string;
1014

1115
description: string;
12-
/**
13-
* The fields of the settings type.
14-
*/
1516
fields: Map<string, InField> = new Map();
1617
displayFields: Map<string, InField> = new Map();
18+
fieldGroups: Map<string, FieldGroup> = new Map();
1719
connectionTitleFields: Map<string, InField> = new Map();
1820
children?: Map<string, ChildEntryType<any>>;
1921
#baseInfo: BaseTypeInfo;
@@ -22,6 +24,7 @@ export class BaseType<N extends string = string> {
2224
name: N,
2325
config: {
2426
fields: Array<InField>;
27+
fieldGroups?: Array<FieldGroupConfig>;
2528
label?: string;
2629
description?: string;
2730
children?: Array<ChildEntryType<any>>;
@@ -52,13 +55,15 @@ export class BaseType<N extends string = string> {
5255
}
5356

5457
this.#setDisplayFields();
58+
this.#addFieldGroups(config.fieldGroups);
5559
this.#baseInfo = {
5660
name: this.name,
5761
label: this.label,
5862
description: this.description,
5963
fields: Array.from(this.fields.values()),
6064
titleFields: Array.from(this.connectionTitleFields.values()),
6165
displayFields: Array.from(this.displayFields.values()),
66+
fieldGroups: Array.from(this.fieldGroups.values()),
6267
};
6368
this.#addChildren(config.children);
6469
}
@@ -97,6 +102,50 @@ export class BaseType<N extends string = string> {
97102
);
98103
}
99104

105+
#addFieldGroups(fieldGroups?: Array<FieldGroupConfig>): void {
106+
const allFields = new Set(Array.from(this.fields.keys()));
107+
for (const group of fieldGroups || []) {
108+
this.#addFieldGroup(group, allFields);
109+
}
110+
if (allFields.size > 0) {
111+
const defaultGroup: FieldGroupConfig = {
112+
key: "default",
113+
label: "",
114+
fields: Array.from(allFields),
115+
};
116+
this.#addFieldGroup(defaultGroup, allFields);
117+
}
118+
}
119+
#addFieldGroup(fieldGroupConfig: FieldGroupConfig, allFields: Set<string>) {
120+
const fieldGroup: FieldGroup = {
121+
...fieldGroupConfig,
122+
label: fieldGroupConfig.label === undefined
123+
? convertString(fieldGroupConfig.key, "title", true)
124+
: fieldGroupConfig.label,
125+
fields: [],
126+
displayFields: [],
127+
};
128+
if (this.fieldGroups.has(fieldGroupConfig.key)) {
129+
raiseORMException(
130+
`Field group ${fieldGroupConfig.key} already exists in ${this.name}`,
131+
);
132+
}
133+
for (const fieldKey of fieldGroupConfig.fields) {
134+
const field = this.fields.get(fieldKey as string);
135+
if (!field) {
136+
raiseORMException(
137+
`field ${fieldKey as string} does not exists in ${this.name}`,
138+
);
139+
}
140+
allFields.delete(field.key);
141+
fieldGroup.fields.push(field);
142+
const displayField = this.displayFields.get(field.key);
143+
if (displayField) {
144+
fieldGroup.displayFields.push(displayField);
145+
}
146+
}
147+
this.fieldGroups.set(fieldGroup.key, fieldGroup);
148+
}
100149
set info(info: Record<string, any>) {
101150
this.#info = info;
102151
}

0 commit comments

Comments
 (0)