Skip to content

Commit 1d9af20

Browse files
authored
feat: add connection references info and related api calls + minor fixes (#30)
1 parent 6c5c2b6 commit 1d9af20

File tree

13 files changed

+125
-10
lines changed

13 files changed

+125
-10
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.5.5",
3+
"version": "0.5.6",
44
"license": "Apache-2.0",
55
"exports": {
66
".": "./mod.ts",

src/auth/entries/user/fields/google-fields.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,7 @@ export const googleFields: Array<InField> = [{
3838
key: "googleAuthStatus",
3939
type: "ChoicesField",
4040
label: "Google Auth Status",
41+
readOnly: true,
4142
choices: [{
4243
key: "authenticated",
4344
label: "Authenticated",

src/auth/entries/user/user-entry.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,22 @@ export const userEntry = new EntryType<User>("user", {
1818
...userFields,
1919
...googleFields,
2020
],
21+
fieldGroups: [{
22+
key: "personal",
23+
label: "Personal Information",
24+
description: "Basic information about the user",
25+
fields: ["profilePicture", "firstName", "lastName", "fullName", "email"],
26+
}, {
27+
key: "security",
28+
label: "Security",
29+
description: "Security related information",
30+
fields: ["systemAdmin", "apiToken"],
31+
}, {
32+
key: "google",
33+
label: "Google Account",
34+
description: "Google account information",
35+
fields: ["googlePicture", "googleAuthStatus"],
36+
}],
2137
actions: [
2238
setPassword,
2339
validatePassword,

src/extension/core-extension.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ export const coreExtension = new CloudExtension("core", {
8181
onboardingStep,
8282
],
8383
middleware: [corsMiddleware, authMiddleware, inLiveMiddleware],
84-
pathHandlers: [apiPathHandler, staticFilesHandler],
84+
pathHandlers: [apiPathHandler],
8585
requestLifecycle: {
8686
setup: [authLifecycle],
8787
},

src/orm/api-actions/entries-group.ts

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -213,6 +213,28 @@ export const getEntryTypeInfoAction = new CloudAPIAction("getEntryTypeInfo", {
213213
}],
214214
});
215215

216+
export const countConnections = new CloudAPIAction("countConnections", {
217+
label: "Count Entry Connections",
218+
description:
219+
"Count the total entries referencing the provided entry id, grouped by entry type",
220+
params: [{
221+
key: "entryType",
222+
type: "DataField",
223+
label: "Entry Type",
224+
description: "The Entry Type to count connections for",
225+
required: true,
226+
}, {
227+
key: "id",
228+
type: "DataField",
229+
label: "ID",
230+
description: "The ID of the Entry to count connections for",
231+
required: true,
232+
}],
233+
async run({ orm, params: { entryType, id } }) {
234+
return await orm.countConnections(entryType, id);
235+
},
236+
});
237+
216238
export const sum = new CloudAPIAction("sum", {
217239
label: "Get the sum of the selected fields for a given Entry Type",
218240
params: [{

src/orm/api-actions/groups.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { CloudAPIGroup } from "../../api/cloud-group.ts";
22
import {
33
count,
4+
countConnections,
45
createEntryAction,
56
deleteEntryAction,
67
getEntryAction,
@@ -35,6 +36,7 @@ export const entriesGroup = new CloudAPIGroup("entry", {
3536
createEntryAction,
3637
deleteEntryAction,
3738
getEntryListAction,
39+
countConnections,
3840
sum,
3941
count,
4042
],

src/orm/entry/entry-type.ts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@ import type {
33
EntryActionConfig,
44
EntryActionDefinition,
55
EntryConfig,
6+
EntryConnection,
67
EntryHookDefinition,
78
EntryIndex,
89
EntryTypeConfig,
@@ -35,6 +36,7 @@ export class EntryType<
3536
defaultSortField?: FK;
3637
defaultSortDirection?: "asc" | "desc" = "asc";
3738
actions: Map<string, EntryActionDefinition> = new Map();
39+
connections: Array<EntryConnection> = [];
3840
hooks: Record<EntryHookName, Array<EntryHookDefinition<E>>> = {
3941
beforeUpdate: [],
4042
afterCreate: [],
@@ -163,6 +165,7 @@ export class EntryType<
163165
defaultListFields: Array.from(this.defaultListFields).map((f) =>
164166
this.fields.get(f)!
165167
),
168+
connections: Array.from(this.connections.values()),
166169
};
167170
}
168171
#setChildrenParent() {

src/orm/entry/types.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -164,3 +164,11 @@ export type EntryIndex<FK extends PropertyKey = PropertyKey> = {
164164
fields: Array<FK>;
165165
unique?: boolean;
166166
};
167+
168+
export interface EntryConnection {
169+
referencingEntry: string;
170+
referencingEntryLabel: string;
171+
referencingField: string;
172+
referencingFieldLabel: string;
173+
listFields: Array<InField>;
174+
}

src/orm/inspatial-orm.ts

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -400,6 +400,38 @@ export class InSpatialORM {
400400
return entry;
401401
}
402402

403+
async countConnections<E extends EntryBase = GenericEntry>(
404+
entryName: E["_name"],
405+
id: string,
406+
): Promise<
407+
Array<{
408+
entryType: string;
409+
label: string;
410+
fieldKey: string;
411+
fieldLabel: string;
412+
count: number;
413+
}>
414+
> {
415+
const entryTypeObj = this.getEntryType(entryName);
416+
const results = [];
417+
for (const connection of entryTypeObj.connections) {
418+
const count = await this.count(connection.referencingEntry, {
419+
filter: [{
420+
field: connection.referencingField,
421+
op: "=",
422+
value: id,
423+
}],
424+
});
425+
results.push({
426+
entryType: connection.referencingEntry,
427+
label: connection.referencingEntryLabel,
428+
fieldKey: connection.referencingField,
429+
fieldLabel: connection.referencingFieldLabel,
430+
count,
431+
});
432+
}
433+
return results;
434+
}
403435
async findEntry<E extends EntryBase = GenericEntry>(
404436
entryType: E["_name"],
405437
filter: DBFilter,

src/orm/roles/role.ts

Lines changed: 32 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ import type {
2626
} from "~/orm/settings/settings-base.ts";
2727
import type { InField } from "~/orm/field/field-def-types.ts";
2828
import type { Choice } from "~/orm/field/types.ts";
29-
import type { EntryConfig } from "~/orm/entry/types.ts";
29+
import type { EntryConfig, EntryConnection } from "~/orm/entry/types.ts";
3030
import type { SettingsConfig } from "~/orm/settings/types.ts";
3131

3232
import type { UserID } from "~/auth/types.ts";
@@ -137,6 +137,37 @@ export class Role {
137137
validateEntryType(this, entryType);
138138
registerFetchFields(this, entryType);
139139
}
140+
this.#setupEntryConnections();
141+
}
142+
#setupEntryConnections(): void {
143+
const connections = new Map<string, Array<EntryConnection>>();
144+
for (const entryType of this.entryTypes.values()) {
145+
const connectionsFields = entryType.fields.values().filter((field) =>
146+
field.type === "ConnectionField"
147+
);
148+
for (const field of connectionsFields) {
149+
if (!connections.has(field.entryType)) {
150+
connections.set(field.entryType, []);
151+
}
152+
// const connectionEntryType = this.getEntryType(field.entryType);
153+
connections.get(field.entryType)!.push({
154+
referencingEntry: entryType.name,
155+
referencingEntryLabel: entryType.label,
156+
referencingField: field.key,
157+
referencingFieldLabel: field.label || field.key,
158+
listFields: entryType.info.defaultListFields,
159+
});
160+
}
161+
}
162+
for (const [entryName, connectionFields] of connections.entries()) {
163+
const entryType = this.getEntryType(entryName);
164+
165+
entryType.connections = connectionFields;
166+
entryType.info = {
167+
...entryType.info,
168+
connections: connectionFields,
169+
};
170+
}
140171
}
141172
#setupSettingsTypes(): void {
142173
for (const settingsType of this.settingsTypes.values()) {

0 commit comments

Comments
 (0)