@graphprotocol/hypergraph 0.10.5 → 0.10.6
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.
|
@@ -1,6 +1,9 @@
|
|
|
1
1
|
import * as EffectSchema from 'effect/Schema';
|
|
2
|
+
export declare const SpaceTypeSchema: EffectSchema.Union<[EffectSchema.Literal<["PERSONAL"]>, EffectSchema.Literal<["DAO"]>]>;
|
|
3
|
+
export type SpaceType = typeof SpaceTypeSchema.Type;
|
|
2
4
|
export declare const PublicSpaceSchema: EffectSchema.Struct<{
|
|
3
5
|
id: typeof EffectSchema.String;
|
|
6
|
+
type: EffectSchema.Union<[EffectSchema.Literal<["PERSONAL"]>, EffectSchema.Literal<["DAO"]>]>;
|
|
4
7
|
name: typeof EffectSchema.String;
|
|
5
8
|
avatar: EffectSchema.optional<typeof EffectSchema.String>;
|
|
6
9
|
editorIds: EffectSchema.Array$<typeof EffectSchema.String>;
|
|
@@ -10,6 +13,7 @@ export type PublicSpace = typeof PublicSpaceSchema.Type;
|
|
|
10
13
|
type SpacesQueryResult = {
|
|
11
14
|
spaces?: {
|
|
12
15
|
id: string;
|
|
16
|
+
type: 'PERSONAL' | 'DAO';
|
|
13
17
|
page: {
|
|
14
18
|
name?: string | null;
|
|
15
19
|
relationsList?: {
|
|
@@ -33,6 +37,7 @@ export declare const parseSpacesQueryResult: (queryResult: SpacesQueryResult) =>
|
|
|
33
37
|
data: {
|
|
34
38
|
readonly name: string;
|
|
35
39
|
readonly id: string;
|
|
40
|
+
readonly type: "PERSONAL" | "DAO";
|
|
36
41
|
readonly avatar?: string | undefined;
|
|
37
42
|
readonly editorIds: readonly string[];
|
|
38
43
|
readonly memberIds: readonly string[];
|
|
@@ -42,20 +47,26 @@ export declare const parseSpacesQueryResult: (queryResult: SpacesQueryResult) =>
|
|
|
42
47
|
export type FindManyPublicFilter = Readonly<{
|
|
43
48
|
memberId: string;
|
|
44
49
|
editorId?: never;
|
|
50
|
+
spaceType?: SpaceType;
|
|
45
51
|
}> | Readonly<{
|
|
46
52
|
editorId: string;
|
|
47
53
|
memberId?: never;
|
|
54
|
+
spaceType?: SpaceType;
|
|
48
55
|
}> | Readonly<{
|
|
49
56
|
memberId?: undefined;
|
|
50
57
|
editorId?: undefined;
|
|
58
|
+
spaceType?: SpaceType;
|
|
51
59
|
}>;
|
|
52
60
|
export type FindManyPublicParams = Readonly<{
|
|
53
61
|
filter?: FindManyPublicFilter;
|
|
54
62
|
}>;
|
|
63
|
+
export declare const buildFilterString: (filter?: FindManyPublicFilter) => string | undefined;
|
|
64
|
+
export declare const buildSpacesQuery: (filter?: FindManyPublicFilter) => string;
|
|
55
65
|
export declare const findManyPublic: (params?: FindManyPublicParams) => Promise<{
|
|
56
66
|
data: {
|
|
57
67
|
readonly name: string;
|
|
58
68
|
readonly id: string;
|
|
69
|
+
readonly type: "PERSONAL" | "DAO";
|
|
59
70
|
readonly avatar?: string | undefined;
|
|
60
71
|
readonly editorIds: readonly string[];
|
|
61
72
|
readonly memberIds: readonly string[];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-many-public.d.ts","sourceRoot":"","sources":["../../src/space/find-many-public.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,YAAY,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"find-many-public.d.ts","sourceRoot":"","sources":["../../src/space/find-many-public.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,YAAY,MAAM,eAAe,CAAC;AA8B9C,eAAO,MAAM,eAAe,yFAAoF,CAAC;AAEjH,MAAM,MAAM,SAAS,GAAG,OAAO,eAAe,CAAC,IAAI,CAAC;AAEpD,eAAO,MAAM,iBAAiB;;;;;;;EAO5B,CAAC;AAEH,MAAM,MAAM,WAAW,GAAG,OAAO,iBAAiB,CAAC,IAAI,CAAC;AAExD,KAAK,iBAAiB,GAAG;IACvB,MAAM,CAAC,EAAE;QACP,EAAE,EAAE,MAAM,CAAC;QACX,IAAI,EAAE,UAAU,GAAG,KAAK,CAAC;QACzB,IAAI,EAAE;YACJ,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;YACrB,aAAa,CAAC,EAAE;gBACd,QAAQ,CAAC,EAAE;oBACT,UAAU,CAAC,EAAE;wBACX,UAAU,EAAE,MAAM,CAAC;wBACnB,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;qBACvB,EAAE,CAAC;iBACL,GAAG,IAAI,CAAC;aACV,EAAE,CAAC;SACL,GAAG,IAAI,CAAC;QACT,WAAW,CAAC,EAAE;YACZ,aAAa,EAAE,MAAM,CAAC;SACvB,EAAE,CAAC;QACJ,WAAW,CAAC,EAAE;YACZ,aAAa,EAAE,MAAM,CAAC;SACvB,EAAE,CAAC;KACL,EAAE,CAAC;CACL,CAAC;AAwBF,eAAO,MAAM,sBAAsB,GAAI,aAAa,iBAAiB;;;;;;;;;;CAyBpE,CAAC;AAEF,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC,GACvE,QAAQ,CAAC;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,CAAC,EAAE,KAAK,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC,GACvE,QAAQ,CAAC;IAAE,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,QAAQ,CAAC,EAAE,SAAS,CAAC;IAAC,SAAS,CAAC,EAAE,SAAS,CAAA;CAAE,CAAC,CAAC;AAEpF,MAAM,MAAM,oBAAoB,GAAG,QAAQ,CAAC;IAC1C,MAAM,CAAC,EAAE,oBAAoB,CAAC;CAC/B,CAAC,CAAC;AAUH,eAAO,MAAM,iBAAiB,GAAI,SAAS,oBAAoB,KAAG,MAAM,GAAG,SA0B1E,CAAC;AAEF,eAAO,MAAM,gBAAgB,GAAI,SAAS,oBAAoB,KAAG,MAWhE,CAAC;AAEF,eAAO,MAAM,cAAc,GAAU,SAAS,oBAAoB;;;;;;;;;;EAajE,CAAC"}
|
|
@@ -3,8 +3,10 @@ import { Config } from '@graphprotocol/hypergraph';
|
|
|
3
3
|
import * as Either from 'effect/Either';
|
|
4
4
|
import * as EffectSchema from 'effect/Schema';
|
|
5
5
|
import { request } from 'graphql-request';
|
|
6
|
+
import { parseGeoId } from '../utils/geo-id.js';
|
|
6
7
|
const spaceFields = `
|
|
7
8
|
id
|
|
9
|
+
type
|
|
8
10
|
page {
|
|
9
11
|
name
|
|
10
12
|
relationsList(filter: {
|
|
@@ -27,29 +29,10 @@ const spaceFields = `
|
|
|
27
29
|
memberSpaceId
|
|
28
30
|
}
|
|
29
31
|
`;
|
|
30
|
-
const
|
|
31
|
-
query spaces {
|
|
32
|
-
spaces {
|
|
33
|
-
${spaceFields}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
`;
|
|
37
|
-
const memberSpacesQueryDocument = `
|
|
38
|
-
query memberSpaces($accountId: UUID!) {
|
|
39
|
-
spaces(filter: {members: {some: {memberSpaceId: {is: $accountId}}}}) {
|
|
40
|
-
${spaceFields}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
`;
|
|
44
|
-
const editorSpacesQueryDocument = `
|
|
45
|
-
query editorSpaces($accountId: UUID!) {
|
|
46
|
-
spaces(filter: {editors: {some: {memberSpaceId: {is: $accountId}}}}) {
|
|
47
|
-
${spaceFields}
|
|
48
|
-
}
|
|
49
|
-
}
|
|
50
|
-
`;
|
|
32
|
+
export const SpaceTypeSchema = /*#__PURE__*/EffectSchema.Union(/*#__PURE__*/EffectSchema.Literal('PERSONAL'), /*#__PURE__*/EffectSchema.Literal('DAO'));
|
|
51
33
|
export const PublicSpaceSchema = /*#__PURE__*/EffectSchema.Struct({
|
|
52
34
|
id: EffectSchema.String,
|
|
35
|
+
type: SpaceTypeSchema,
|
|
53
36
|
name: EffectSchema.String,
|
|
54
37
|
avatar: /*#__PURE__*/EffectSchema.optional(EffectSchema.String),
|
|
55
38
|
editorIds: /*#__PURE__*/EffectSchema.Array(EffectSchema.String),
|
|
@@ -78,6 +61,7 @@ export const parseSpacesQueryResult = queryResult => {
|
|
|
78
61
|
for (const space of spaces) {
|
|
79
62
|
const rawSpace = {
|
|
80
63
|
id: space.id,
|
|
64
|
+
type: space.type,
|
|
81
65
|
name: space.page?.name ?? undefined,
|
|
82
66
|
avatar: getAvatarFromSpace(space),
|
|
83
67
|
editorIds: getEditorIdsFromSpace(space),
|
|
@@ -95,6 +79,46 @@ export const parseSpacesQueryResult = queryResult => {
|
|
|
95
79
|
invalidSpaces
|
|
96
80
|
};
|
|
97
81
|
};
|
|
82
|
+
const validateSpaceType = spaceType => {
|
|
83
|
+
const result = EffectSchema.decodeUnknownEither(SpaceTypeSchema)(spaceType);
|
|
84
|
+
if (Either.isLeft(result)) {
|
|
85
|
+
throw new Error(`Invalid spaceType: ${spaceType}. Must be 'PERSONAL' or 'DAO'.`);
|
|
86
|
+
}
|
|
87
|
+
return result.right;
|
|
88
|
+
};
|
|
89
|
+
export const buildFilterString = filter => {
|
|
90
|
+
const conditions = [];
|
|
91
|
+
if (filter?.memberId) {
|
|
92
|
+
// Validate memberId is a valid GeoId to prevent injection attacks
|
|
93
|
+
const validatedMemberId = parseGeoId(filter.memberId);
|
|
94
|
+
conditions.push(`members: {some: {memberSpaceId: {is: "${validatedMemberId}"}}}`);
|
|
95
|
+
}
|
|
96
|
+
if (filter?.editorId) {
|
|
97
|
+
// Validate editorId is a valid GeoId to prevent injection attacks
|
|
98
|
+
const validatedEditorId = parseGeoId(filter.editorId);
|
|
99
|
+
conditions.push(`editors: {some: {memberSpaceId: {is: "${validatedEditorId}"}}}`);
|
|
100
|
+
}
|
|
101
|
+
if (filter?.spaceType) {
|
|
102
|
+
// Validate spaceType at runtime to ensure it's a valid value
|
|
103
|
+
const validatedSpaceType = validateSpaceType(filter.spaceType);
|
|
104
|
+
conditions.push(`type: {is: ${validatedSpaceType}}`);
|
|
105
|
+
}
|
|
106
|
+
if (conditions.length === 0) {
|
|
107
|
+
return undefined;
|
|
108
|
+
}
|
|
109
|
+
return `filter: {${conditions.join(', ')}}`;
|
|
110
|
+
};
|
|
111
|
+
export const buildSpacesQuery = filter => {
|
|
112
|
+
const filterString = buildFilterString(filter);
|
|
113
|
+
const filterClause = filterString ? `(${filterString})` : '';
|
|
114
|
+
return `
|
|
115
|
+
query spaces {
|
|
116
|
+
spaces${filterClause} {
|
|
117
|
+
${spaceFields}
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
`;
|
|
121
|
+
};
|
|
98
122
|
export const findManyPublic = async params => {
|
|
99
123
|
const filter = params?.filter;
|
|
100
124
|
const memberId = filter?.memberId;
|
|
@@ -103,19 +127,8 @@ export const findManyPublic = async params => {
|
|
|
103
127
|
throw new Error('Provide only one of memberId or editorId when calling findManyPublic().');
|
|
104
128
|
}
|
|
105
129
|
const endpoint = `${Config.getApiOrigin()}/v2/graphql`;
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
accountId: memberId
|
|
109
|
-
});
|
|
110
|
-
return parseSpacesQueryResult(queryResult);
|
|
111
|
-
}
|
|
112
|
-
if (editorId) {
|
|
113
|
-
const queryResult = await request(endpoint, editorSpacesQueryDocument, {
|
|
114
|
-
accountId: editorId
|
|
115
|
-
});
|
|
116
|
-
return parseSpacesQueryResult(queryResult);
|
|
117
|
-
}
|
|
118
|
-
const queryResult = await request(endpoint, spacesQueryDocument);
|
|
130
|
+
const queryDocument = buildSpacesQuery(filter);
|
|
131
|
+
const queryResult = await request(endpoint, queryDocument);
|
|
119
132
|
return parseSpacesQueryResult(queryResult);
|
|
120
133
|
};
|
|
121
134
|
//# sourceMappingURL=find-many-public.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"find-many-public.js","names":["ContentIds","SystemIds","Config","Either","EffectSchema","request","spaceFields","AVATAR_PROPERTY","IMAGE_URL_PROPERTY","
|
|
1
|
+
{"version":3,"file":"find-many-public.js","names":["ContentIds","SystemIds","Config","Either","EffectSchema","request","parseGeoId","spaceFields","AVATAR_PROPERTY","IMAGE_URL_PROPERTY","SpaceTypeSchema","Union","Literal","PublicSpaceSchema","Struct","id","String","type","name","avatar","optional","editorIds","Array","memberIds","decodeSpace","decodeUnknownEither","getAvatarFromSpace","space","firstRelation","page","relationsList","firstValue","toEntity","valuesList","string","undefined","getEditorIdsFromSpace","editorsList","map","e","memberSpaceId","filter","getMemberIdsFromSpace","membersList","m","parseSpacesQueryResult","queryResult","data","invalidSpaces","spaces","rawSpace","decodedSpace","isRight","push","right","validateSpaceType","spaceType","result","isLeft","Error","buildFilterString","conditions","memberId","validatedMemberId","editorId","validatedEditorId","validatedSpaceType","length","join","buildSpacesQuery","filterString","filterClause","findManyPublic","params","endpoint","getApiOrigin","queryDocument"],"sources":["../../src/space/find-many-public.ts"],"sourcesContent":[null],"mappings":"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","ignoreList":[]}
|
package/package.json
CHANGED
|
@@ -3,9 +3,11 @@ import { Config } from '@graphprotocol/hypergraph';
|
|
|
3
3
|
import * as Either from 'effect/Either';
|
|
4
4
|
import * as EffectSchema from 'effect/Schema';
|
|
5
5
|
import { request } from 'graphql-request';
|
|
6
|
+
import { parseGeoId } from '../utils/geo-id.js';
|
|
6
7
|
|
|
7
8
|
const spaceFields = `
|
|
8
9
|
id
|
|
10
|
+
type
|
|
9
11
|
page {
|
|
10
12
|
name
|
|
11
13
|
relationsList(filter: {
|
|
@@ -29,32 +31,13 @@ const spaceFields = `
|
|
|
29
31
|
}
|
|
30
32
|
`;
|
|
31
33
|
|
|
32
|
-
const
|
|
33
|
-
query spaces {
|
|
34
|
-
spaces {
|
|
35
|
-
${spaceFields}
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
`;
|
|
34
|
+
export const SpaceTypeSchema = EffectSchema.Union(EffectSchema.Literal('PERSONAL'), EffectSchema.Literal('DAO'));
|
|
39
35
|
|
|
40
|
-
|
|
41
|
-
query memberSpaces($accountId: UUID!) {
|
|
42
|
-
spaces(filter: {members: {some: {memberSpaceId: {is: $accountId}}}}) {
|
|
43
|
-
${spaceFields}
|
|
44
|
-
}
|
|
45
|
-
}
|
|
46
|
-
`;
|
|
47
|
-
|
|
48
|
-
const editorSpacesQueryDocument = `
|
|
49
|
-
query editorSpaces($accountId: UUID!) {
|
|
50
|
-
spaces(filter: {editors: {some: {memberSpaceId: {is: $accountId}}}}) {
|
|
51
|
-
${spaceFields}
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
`;
|
|
36
|
+
export type SpaceType = typeof SpaceTypeSchema.Type;
|
|
55
37
|
|
|
56
38
|
export const PublicSpaceSchema = EffectSchema.Struct({
|
|
57
39
|
id: EffectSchema.String,
|
|
40
|
+
type: SpaceTypeSchema,
|
|
58
41
|
name: EffectSchema.String,
|
|
59
42
|
avatar: EffectSchema.optional(EffectSchema.String),
|
|
60
43
|
editorIds: EffectSchema.Array(EffectSchema.String),
|
|
@@ -66,6 +49,7 @@ export type PublicSpace = typeof PublicSpaceSchema.Type;
|
|
|
66
49
|
type SpacesQueryResult = {
|
|
67
50
|
spaces?: {
|
|
68
51
|
id: string;
|
|
52
|
+
type: 'PERSONAL' | 'DAO';
|
|
69
53
|
page: {
|
|
70
54
|
name?: string | null;
|
|
71
55
|
relationsList?: {
|
|
@@ -86,10 +70,6 @@ type SpacesQueryResult = {
|
|
|
86
70
|
}[];
|
|
87
71
|
};
|
|
88
72
|
|
|
89
|
-
type SpacesQueryVariables = {
|
|
90
|
-
accountId: string;
|
|
91
|
-
};
|
|
92
|
-
|
|
93
73
|
type SpaceQueryEntry = NonNullable<SpacesQueryResult['spaces']>[number];
|
|
94
74
|
|
|
95
75
|
const decodeSpace = EffectSchema.decodeUnknownEither(PublicSpaceSchema);
|
|
@@ -120,6 +100,7 @@ export const parseSpacesQueryResult = (queryResult: SpacesQueryResult) => {
|
|
|
120
100
|
for (const space of spaces) {
|
|
121
101
|
const rawSpace: Record<string, unknown> = {
|
|
122
102
|
id: space.id,
|
|
103
|
+
type: space.type,
|
|
123
104
|
name: space.page?.name ?? undefined,
|
|
124
105
|
avatar: getAvatarFromSpace(space),
|
|
125
106
|
editorIds: getEditorIdsFromSpace(space),
|
|
@@ -139,14 +120,63 @@ export const parseSpacesQueryResult = (queryResult: SpacesQueryResult) => {
|
|
|
139
120
|
};
|
|
140
121
|
|
|
141
122
|
export type FindManyPublicFilter =
|
|
142
|
-
| Readonly<{ memberId: string; editorId?: never }>
|
|
143
|
-
| Readonly<{ editorId: string; memberId?: never }>
|
|
144
|
-
| Readonly<{ memberId?: undefined; editorId?: undefined }>;
|
|
123
|
+
| Readonly<{ memberId: string; editorId?: never; spaceType?: SpaceType }>
|
|
124
|
+
| Readonly<{ editorId: string; memberId?: never; spaceType?: SpaceType }>
|
|
125
|
+
| Readonly<{ memberId?: undefined; editorId?: undefined; spaceType?: SpaceType }>;
|
|
145
126
|
|
|
146
127
|
export type FindManyPublicParams = Readonly<{
|
|
147
128
|
filter?: FindManyPublicFilter;
|
|
148
129
|
}>;
|
|
149
130
|
|
|
131
|
+
const validateSpaceType = (spaceType: SpaceType): SpaceType => {
|
|
132
|
+
const result = EffectSchema.decodeUnknownEither(SpaceTypeSchema)(spaceType);
|
|
133
|
+
if (Either.isLeft(result)) {
|
|
134
|
+
throw new Error(`Invalid spaceType: ${spaceType}. Must be 'PERSONAL' or 'DAO'.`);
|
|
135
|
+
}
|
|
136
|
+
return result.right;
|
|
137
|
+
};
|
|
138
|
+
|
|
139
|
+
export const buildFilterString = (filter?: FindManyPublicFilter): string | undefined => {
|
|
140
|
+
const conditions: string[] = [];
|
|
141
|
+
|
|
142
|
+
if (filter?.memberId) {
|
|
143
|
+
// Validate memberId is a valid GeoId to prevent injection attacks
|
|
144
|
+
const validatedMemberId = parseGeoId(filter.memberId);
|
|
145
|
+
conditions.push(`members: {some: {memberSpaceId: {is: "${validatedMemberId}"}}}`);
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
if (filter?.editorId) {
|
|
149
|
+
// Validate editorId is a valid GeoId to prevent injection attacks
|
|
150
|
+
const validatedEditorId = parseGeoId(filter.editorId);
|
|
151
|
+
conditions.push(`editors: {some: {memberSpaceId: {is: "${validatedEditorId}"}}}`);
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
if (filter?.spaceType) {
|
|
155
|
+
// Validate spaceType at runtime to ensure it's a valid value
|
|
156
|
+
const validatedSpaceType = validateSpaceType(filter.spaceType);
|
|
157
|
+
conditions.push(`type: {is: ${validatedSpaceType}}`);
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
if (conditions.length === 0) {
|
|
161
|
+
return undefined;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
return `filter: {${conditions.join(', ')}}`;
|
|
165
|
+
};
|
|
166
|
+
|
|
167
|
+
export const buildSpacesQuery = (filter?: FindManyPublicFilter): string => {
|
|
168
|
+
const filterString = buildFilterString(filter);
|
|
169
|
+
const filterClause = filterString ? `(${filterString})` : '';
|
|
170
|
+
|
|
171
|
+
return `
|
|
172
|
+
query spaces {
|
|
173
|
+
spaces${filterClause} {
|
|
174
|
+
${spaceFields}
|
|
175
|
+
}
|
|
176
|
+
}
|
|
177
|
+
`;
|
|
178
|
+
};
|
|
179
|
+
|
|
150
180
|
export const findManyPublic = async (params?: FindManyPublicParams) => {
|
|
151
181
|
const filter = params?.filter;
|
|
152
182
|
const memberId = filter?.memberId;
|
|
@@ -157,21 +187,7 @@ export const findManyPublic = async (params?: FindManyPublicParams) => {
|
|
|
157
187
|
}
|
|
158
188
|
|
|
159
189
|
const endpoint = `${Config.getApiOrigin()}/v2/graphql`;
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
const queryResult = await request<SpacesQueryResult, SpacesQueryVariables>(endpoint, memberSpacesQueryDocument, {
|
|
163
|
-
accountId: memberId,
|
|
164
|
-
});
|
|
165
|
-
return parseSpacesQueryResult(queryResult);
|
|
166
|
-
}
|
|
167
|
-
|
|
168
|
-
if (editorId) {
|
|
169
|
-
const queryResult = await request<SpacesQueryResult, SpacesQueryVariables>(endpoint, editorSpacesQueryDocument, {
|
|
170
|
-
accountId: editorId,
|
|
171
|
-
});
|
|
172
|
-
return parseSpacesQueryResult(queryResult);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
const queryResult = await request<SpacesQueryResult>(endpoint, spacesQueryDocument);
|
|
190
|
+
const queryDocument = buildSpacesQuery(filter);
|
|
191
|
+
const queryResult = await request<SpacesQueryResult>(endpoint, queryDocument);
|
|
176
192
|
return parseSpacesQueryResult(queryResult);
|
|
177
193
|
};
|