@nlabs/reaktor 0.1.0 → 0.1.1
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/lib/data/conversations.js +3 -7
- package/lib/data/email.js +4 -5
- package/lib/data/files.js +3 -4
- package/lib/data/images.js +6 -7
- package/lib/data/posts.d.ts +5 -3
- package/lib/data/posts.js +179 -97
- package/lib/data/users.js +1 -3
- package/lib/types/apps.d.ts +0 -1
- package/lib/types/auth.d.ts +1 -0
- package/lib/types/files.d.ts +0 -2
- package/lib/types/groups.d.ts +0 -1
- package/lib/types/images.d.ts +0 -1
- package/lib/types/locations.d.ts +0 -1
- package/lib/types/payments.d.ts +0 -5
- package/lib/types/posts.d.ts +11 -4
- package/lib/types/tags.d.ts +0 -1
- package/lib/utils/auth.d.ts +6 -1
- package/lib/utils/auth.js +41 -4
- package/lib/utils/graphql.d.ts +1 -0
- package/lib/utils/graphql.js +7 -0
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +2 -1
- package/package.json +12 -12
- package/src/data/conversations.ts +2 -4
- package/src/data/email.ts +3 -4
- package/src/data/files.ts +2 -2
- package/src/data/images.ts +5 -5
- package/src/data/posts.ts +178 -125
- package/src/data/users.ts +0 -2
- package/src/types/apps.ts +0 -1
- package/src/types/auth.ts +1 -0
- package/src/types/files.ts +0 -2
- package/src/types/groups.ts +0 -1
- package/src/types/images.ts +0 -1
- package/src/types/locations.ts +0 -1
- package/src/types/payments.ts +0 -5
- package/src/types/posts.ts +12 -4
- package/src/types/tags.ts +0 -1
- package/src/utils/auth.ts +35 -2
- package/src/utils/graphql.ts +7 -0
- package/src/utils/index.ts +1 -0
package/src/data/posts.ts
CHANGED
|
@@ -2,36 +2,68 @@
|
|
|
2
2
|
* Copyright (c) 2019-Present, Nitrogen Labs, Inc.
|
|
3
3
|
* Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
|
|
4
4
|
*/
|
|
5
|
-
import {createHash, parseChar, parseId, parseString, parseVarChar} from '@nlabs/utils';
|
|
5
|
+
import {createHash, parseChar, parseId, parseNum, parseString, parseVarChar} from '@nlabs/utils';
|
|
6
6
|
import {aql, Database} from 'arangojs';
|
|
7
7
|
import {AqlQuery} from 'arangojs/lib/cjs/aql-query';
|
|
8
8
|
import {ArrayCursor} from 'arangojs/lib/cjs/cursor';
|
|
9
9
|
import flatten from 'lodash/flatten';
|
|
10
10
|
import uniqBy from 'lodash/uniqBy';
|
|
11
11
|
|
|
12
|
-
import {ApiContext, ArangoDBLimit, FileType, GroupType, PostType, TagType} from '../types';
|
|
12
|
+
import {ApiContext, ArangoDBLimit, FileType, GroupType, PostOptions, PostType, TagType} from '../types';
|
|
13
13
|
import {getLimit, useDb} from '../utils';
|
|
14
14
|
import {updateFiles} from './files';
|
|
15
15
|
import {extractTags} from './tags';
|
|
16
16
|
|
|
17
17
|
// const eventCategory: string = 'posts';
|
|
18
|
+
const MAX_CONTENT_LENGTH: number = 100000;
|
|
19
|
+
|
|
20
|
+
export const getPostOptional = (fields: string[]) =>
|
|
21
|
+
fields.reduce((selects: any, field: string) => {
|
|
22
|
+
switch(field) {
|
|
23
|
+
case 'reactions': {
|
|
24
|
+
selects.queries.push(`LET reactions = (
|
|
25
|
+
FOR post, r IN INBOUND p._id reactions
|
|
26
|
+
COLLECT reactionName = r.value INTO reactionItems
|
|
27
|
+
RETURN {name: reactionName, count: LENGTH(reactionItems[*].r.value)}
|
|
28
|
+
)`);
|
|
29
|
+
selects.objects.push('reactions:reactions');
|
|
30
|
+
return selects;
|
|
31
|
+
}
|
|
32
|
+
case 'tags': {
|
|
33
|
+
selects.queries.push(`LET tags = (
|
|
34
|
+
FOR t, pl IN INBOUND p._id isTagged
|
|
35
|
+
RETURN t
|
|
36
|
+
)`);
|
|
37
|
+
selects.objects.push('tags:tags');
|
|
38
|
+
return selects;
|
|
39
|
+
}
|
|
40
|
+
case 'user': {
|
|
41
|
+
selects.queries.push(`LET user = FIRST(
|
|
42
|
+
FOR u IN users
|
|
43
|
+
FILTER p.userId == u._key
|
|
44
|
+
LIMIT 1
|
|
45
|
+
RETURN u
|
|
46
|
+
)`);
|
|
47
|
+
selects.objects.push('user:user');
|
|
48
|
+
return selects;
|
|
49
|
+
}
|
|
50
|
+
default: {
|
|
51
|
+
return selects;
|
|
52
|
+
}
|
|
53
|
+
}
|
|
54
|
+
}, {objects: [], queries: []});
|
|
18
55
|
|
|
19
56
|
export const getPostList = (context: ApiContext, from: number, to: number): Promise<PostType[]> => {
|
|
20
57
|
// const action: string = 'getListByApp';
|
|
21
|
-
const {database} = context;
|
|
58
|
+
const {database, fields} = context;
|
|
22
59
|
const limit: ArangoDBLimit = getLimit(from, to);
|
|
60
|
+
const {objects: selectObjects, queries: selectQueries} = getPostOptional(fields);
|
|
23
61
|
const aqlQry: string = `FOR p IN posts
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
)
|
|
30
|
-
FOR u IN users
|
|
31
|
-
FILTER p.userId == u._key
|
|
32
|
-
${limit.aql}
|
|
33
|
-
SORT p.added
|
|
34
|
-
RETURN DISTINCT MERGE(p, {user:u, reactions:reactions})`;
|
|
62
|
+
FILTER p.privacy == "public" && p.parent == null
|
|
63
|
+
${selectQueries.join('\n')}
|
|
64
|
+
${limit.aql}
|
|
65
|
+
SORT p.added
|
|
66
|
+
RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
|
|
35
67
|
|
|
36
68
|
return useDb(database).query(aqlQry)
|
|
37
69
|
.then((cursor: ArrayCursor) => cursor.all())
|
|
@@ -42,7 +74,8 @@ export const getPostList = (context: ApiContext, from: number, to: number): Prom
|
|
|
42
74
|
|
|
43
75
|
export const getPostListByGroup = (context: ApiContext, groupId: string, from: number, to: number): Promise<PostType[]> => {
|
|
44
76
|
// const action: string = 'getListByGroup';
|
|
45
|
-
const {database, userId: sessionId} = context;
|
|
77
|
+
const {database, fields, userId: sessionId} = context;
|
|
78
|
+
const {objects: selectObjects, queries: selectQueries} = getPostOptional(fields);
|
|
46
79
|
|
|
47
80
|
// Group id
|
|
48
81
|
const formatGroupId: string = parseId(groupId);
|
|
@@ -57,17 +90,11 @@ export const getPostListByGroup = (context: ApiContext, groupId: string, from: n
|
|
|
57
90
|
if(groups.length) {
|
|
58
91
|
const limit: ArangoDBLimit = getLimit(from, to);
|
|
59
92
|
const postAqlQry: string = `FOR p IN posts
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
)
|
|
66
|
-
FOR u IN users
|
|
67
|
-
FILTER p.userId == u._key
|
|
68
|
-
${limit.aql}
|
|
69
|
-
SORT p.added
|
|
70
|
-
RETURN DISTINCT MERGE(p, {user:u, reactions:reactions})`;
|
|
93
|
+
FILTER p.groupId == "${formatGroupId}" && p.parent == null
|
|
94
|
+
${selectQueries.join('\n')}
|
|
95
|
+
${limit.aql}
|
|
96
|
+
SORT p.added
|
|
97
|
+
RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
|
|
71
98
|
|
|
72
99
|
return db.query(postAqlQry)
|
|
73
100
|
.then((cursor: ArrayCursor) => cursor.all())
|
|
@@ -85,20 +112,15 @@ export const getPostListByGroup = (context: ApiContext, groupId: string, from: n
|
|
|
85
112
|
|
|
86
113
|
export const getPostListByLatest = (context: ApiContext, from: number, to: number): Promise<PostType[]> => {
|
|
87
114
|
// const action: string = 'getListByLatest';
|
|
88
|
-
const {database} = context;
|
|
115
|
+
const {database, fields} = context;
|
|
89
116
|
const limit: ArangoDBLimit = getLimit(from, to);
|
|
117
|
+
const {objects: selectObjects, queries: selectQueries} = getPostOptional(fields);
|
|
90
118
|
const aqlQry: string = `FOR p IN posts
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
)
|
|
97
|
-
FOR u IN users
|
|
98
|
-
FILTER p.userId == u._key
|
|
99
|
-
${limit.aql}
|
|
100
|
-
SORT p.added
|
|
101
|
-
RETURN DISTINCT MERGE(p, {user:u, reactions:reactions})`;
|
|
119
|
+
FILTER p.privacy == "public" && p.parent == null
|
|
120
|
+
${selectQueries.join('\n')}
|
|
121
|
+
${limit.aql}
|
|
122
|
+
SORT p.added
|
|
123
|
+
RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
|
|
102
124
|
|
|
103
125
|
return useDb(database).query(aqlQry)
|
|
104
126
|
.then((cursor: ArrayCursor) => cursor.all())
|
|
@@ -107,31 +129,48 @@ export const getPostListByLatest = (context: ApiContext, from: number, to: numbe
|
|
|
107
129
|
});
|
|
108
130
|
};
|
|
109
131
|
|
|
110
|
-
export const getPostListByTags = (
|
|
132
|
+
export const getPostListByTags = (
|
|
133
|
+
context: ApiContext,
|
|
134
|
+
tagNames: string[],
|
|
135
|
+
options: PostOptions
|
|
136
|
+
): Promise<PostType[]> => {
|
|
111
137
|
// const action: string = 'getListByTags';
|
|
112
|
-
const {database} = context;
|
|
138
|
+
const {database, fields} = context;
|
|
139
|
+
const {latitude, longitude, from = 0, to = 30} = options;
|
|
140
|
+
const {objects: selectObjects, queries: selectQueries} = getPostOptional(fields);
|
|
141
|
+
const sortBy: string[] = [];
|
|
142
|
+
|
|
143
|
+
if(latitude !== undefined && longitude !== undefined) {
|
|
144
|
+
const formatLatitude: number = parseNum(latitude);
|
|
145
|
+
const formatLongitude: number = parseNum(longitude);
|
|
146
|
+
selectQueries.push(`LET distance = DISTANCE(
|
|
147
|
+
${formatLatitude},
|
|
148
|
+
${formatLongitude},
|
|
149
|
+
NOT_NULL(p.latitude, 0),
|
|
150
|
+
NOT_NULL(p.longitude, 0))
|
|
151
|
+
`);
|
|
152
|
+
selectObjects.push('distance:distance');
|
|
153
|
+
sortBy.push('distance');
|
|
154
|
+
}
|
|
155
|
+
|
|
156
|
+
sortBy.push('p.added');
|
|
113
157
|
|
|
114
158
|
return Promise.all(
|
|
115
159
|
tagNames.map((tagName: string) => {
|
|
116
|
-
const formatTagId: string = createHash(`tag-${tagName}`, null);
|
|
117
160
|
const limit: ArangoDBLimit = getLimit(from, to);
|
|
118
|
-
const aqlQry: string = `FOR
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
RETURN DISTINCT MERGE(p, {user:u, reactions:reactions})`;
|
|
129
|
-
|
|
161
|
+
const aqlQry: string = `FOR targetTag IN tags
|
|
162
|
+
FILTER targetTag.name == "${tagName}"
|
|
163
|
+
FOR p, e IN OUTBOUND targetTag._id isTagged
|
|
164
|
+
${selectQueries.join('\n')}
|
|
165
|
+
FILTER p.privacy == "public" && e.type == 'posts'
|
|
166
|
+
${limit.aql}
|
|
167
|
+
SORT ${sortBy.join(', ')}
|
|
168
|
+
RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
|
|
169
|
+
|
|
170
|
+
console.log(aqlQry);
|
|
130
171
|
return useDb(database).query(aqlQry)
|
|
131
172
|
.then((cursor: ArrayCursor) => cursor.all())
|
|
132
|
-
.catch((
|
|
133
|
-
throw error;
|
|
134
|
-
});
|
|
173
|
+
.catch(() => []);
|
|
135
174
|
}))
|
|
136
175
|
.then((results) => uniqBy(flatten(results), '_key'))
|
|
137
176
|
.catch((error: Error) => {
|
|
@@ -139,23 +178,54 @@ export const getPostListByTags = (context: ApiContext, tagNames: string[], from?
|
|
|
139
178
|
});
|
|
140
179
|
};
|
|
141
180
|
|
|
142
|
-
export const getPostListByUser = (context: ApiContext, userId: string,
|
|
181
|
+
export const getPostListByUser = (context: ApiContext, userId: string, options): Promise<PostType[]> => {
|
|
143
182
|
// const action: string = 'getListByUser';
|
|
144
|
-
const {database} = context;
|
|
183
|
+
const {database, fields} = context;
|
|
184
|
+
const {from = 0, to = 30} = options;
|
|
145
185
|
const formatUserId: string = parseId(userId);
|
|
146
186
|
const limit: ArangoDBLimit = getLimit(from, to);
|
|
187
|
+
const {objects: selectObjects, queries: selectQueries} = getPostOptional(fields);
|
|
188
|
+
const aqlQry: string = `FOR p IN posts
|
|
189
|
+
FILTER p.userId == "${formatUserId}" && p.privacy == "public" && p.parent == null
|
|
190
|
+
${selectQueries.join('\n')}
|
|
191
|
+
${limit.aql}
|
|
192
|
+
SORT p.added
|
|
193
|
+
RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
|
|
194
|
+
|
|
195
|
+
return useDb(database).query(aqlQry)
|
|
196
|
+
.then((cursor: ArrayCursor) => cursor.all())
|
|
197
|
+
.catch((error: Error) => {
|
|
198
|
+
throw error;
|
|
199
|
+
});
|
|
200
|
+
};
|
|
201
|
+
|
|
202
|
+
export const getPostListByArea = (
|
|
203
|
+
context: ApiContext,
|
|
204
|
+
latitude: number,
|
|
205
|
+
longitude: number,
|
|
206
|
+
from: number,
|
|
207
|
+
to: number
|
|
208
|
+
): Promise<PostType[]> => {
|
|
209
|
+
// const action: string = 'getListByUser';
|
|
210
|
+
const {database, fields} = context;
|
|
211
|
+
const formatLatitude: number = parseNum(latitude);
|
|
212
|
+
const formatLongitude: number = parseNum(longitude);
|
|
213
|
+
const limit: ArangoDBLimit = getLimit(from, to);
|
|
214
|
+
const {objects: selectObjects, queries: selectQueries} = getPostOptional(fields);
|
|
215
|
+
selectQueries.push(`LET distance = DISTANCE(
|
|
216
|
+
${formatLatitude},
|
|
217
|
+
${formatLongitude},
|
|
218
|
+
NOT_NULL(p.latitude, 0),
|
|
219
|
+
NOT_NULL(p.longitude, 0))
|
|
220
|
+
`);
|
|
221
|
+
selectObjects.push('distance:distance');
|
|
222
|
+
|
|
147
223
|
const aqlQry: string = `FOR p IN posts
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
)
|
|
154
|
-
FOR u IN users
|
|
155
|
-
FILTER p.userId == u._key
|
|
156
|
-
${limit.aql}
|
|
157
|
-
SORT p.added
|
|
158
|
-
RETURN DISTINCT MERGE(p, {user:u, reactions:reactions})`;
|
|
224
|
+
${selectQueries.join('\n')}
|
|
225
|
+
FILTER p.privacy == "public" && p.parentId == null
|
|
226
|
+
${limit.aql}
|
|
227
|
+
SORT distance, p.added
|
|
228
|
+
RETURN DISTINCT MERGE(p, {${selectObjects.join(', ')}})`;
|
|
159
229
|
|
|
160
230
|
return useDb(database).query(aqlQry)
|
|
161
231
|
.then((cursor: ArrayCursor) => cursor.all())
|
|
@@ -166,9 +236,10 @@ export const getPostListByUser = (context: ApiContext, userId: string, from: num
|
|
|
166
236
|
|
|
167
237
|
export const getPost = (context: ApiContext, itemId: string): Promise<PostType> => {
|
|
168
238
|
// const action: string = 'getItem';
|
|
169
|
-
const {database, userId: sessionId} = context;
|
|
239
|
+
const {database, fields, userId: sessionId} = context;
|
|
170
240
|
const formatItemId: string = parseId(itemId);
|
|
171
241
|
const db = useDb(database);
|
|
242
|
+
const {objects: selectObjects, queries: selectQueries} = getPostOptional(fields);
|
|
172
243
|
const aqlQry: AqlQuery = aql`FOR p IN posts
|
|
173
244
|
FILTER p._key == ${formatItemId}
|
|
174
245
|
LIMIT 1
|
|
@@ -184,34 +255,24 @@ export const getPost = (context: ApiContext, itemId: string): Promise<PostType>
|
|
|
184
255
|
}: PostType = post;
|
|
185
256
|
|
|
186
257
|
// Query based on privacy level
|
|
187
|
-
let privacyAqlQry:
|
|
258
|
+
let privacyAqlQry: string;
|
|
188
259
|
|
|
189
260
|
if(groupId && privacy === 'group') {
|
|
190
|
-
privacyAqlQry =
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
LET reactions = (
|
|
194
|
-
FOR post, r IN INBOUND p._id reactions
|
|
195
|
-
COLLECT reactionName = r.value INTO reactionItems
|
|
196
|
-
RETURN {name: reactionName, count: LENGTH(reactionItems[*].r.value)}
|
|
197
|
-
)
|
|
261
|
+
privacyAqlQry = `FOR p IN posts
|
|
262
|
+
FILTER p._key == "${_key}"
|
|
263
|
+
${selectQueries.join('\n')}
|
|
198
264
|
FOR group IN groups
|
|
199
265
|
FILTER group._key == p.groupId
|
|
200
266
|
FOR u, e IN OUTBOUND group._id isGrouped
|
|
201
267
|
FILTER u._key == ${sessionId}
|
|
202
268
|
LIMIT 1
|
|
203
|
-
RETURN MERGE(p, {
|
|
269
|
+
RETURN MERGE(p, {${selectObjects.join(', ')}})`;
|
|
204
270
|
} else if(privacy === 'public') {
|
|
205
|
-
privacyAqlQry =
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
LET reactions = (
|
|
209
|
-
FOR post, r IN INBOUND p._id reactions
|
|
210
|
-
COLLECT reactionName = r.value INTO reactionItems
|
|
211
|
-
RETURN {name: reactionName, count: LENGTH(reactionItems[*].r.value)}
|
|
212
|
-
)
|
|
271
|
+
privacyAqlQry = `FOR p IN posts
|
|
272
|
+
FILTER p._key == "${_key}"
|
|
273
|
+
${selectQueries.join('\n')}
|
|
213
274
|
LIMIT 1
|
|
214
|
-
RETURN MERGE(p, {
|
|
275
|
+
RETURN MERGE(p, {${selectObjects.join(', ')}})`;
|
|
215
276
|
}
|
|
216
277
|
|
|
217
278
|
if(privacyAqlQry) {
|
|
@@ -305,12 +366,14 @@ export const addPost = (context: ApiContext, item: PostType): Promise<PostType>
|
|
|
305
366
|
const {database, userId: sessionId} = context;
|
|
306
367
|
|
|
307
368
|
const {
|
|
369
|
+
content = '',
|
|
308
370
|
groupId = '',
|
|
371
|
+
location,
|
|
372
|
+
latitude,
|
|
373
|
+
longitude,
|
|
309
374
|
name = '',
|
|
310
|
-
parentId =
|
|
311
|
-
privacy = 'public'
|
|
312
|
-
text = '',
|
|
313
|
-
title = ''
|
|
375
|
+
parentId = null,
|
|
376
|
+
privacy = 'public'
|
|
314
377
|
}: PostType = item;
|
|
315
378
|
|
|
316
379
|
const now: number = Date.now();
|
|
@@ -318,15 +381,18 @@ export const addPost = (context: ApiContext, item: PostType): Promise<PostType>
|
|
|
318
381
|
const insert: PostType = {
|
|
319
382
|
_key: createHash(`post-${sessionId}`),
|
|
320
383
|
added: now,
|
|
321
|
-
|
|
384
|
+
content: parseString(content, MAX_CONTENT_LENGTH),
|
|
385
|
+
groupId: groupId ? parseId(groupId) : undefined,
|
|
386
|
+
latitude: latitude !== undefined ? parseNum(latitude) : undefined,
|
|
387
|
+
location: location ? parseString(location, 160) : undefined,
|
|
388
|
+
longitude: longitude !== undefined ? parseNum(longitude) : undefined,
|
|
322
389
|
modified: now,
|
|
323
390
|
name: parseString(name, 160),
|
|
324
|
-
parentId: parseId(parentId),
|
|
325
|
-
privacy: parseVarChar(privacy, 16),
|
|
326
|
-
text: parseString(text, 20000),
|
|
327
|
-
title: parseString(title, 160),
|
|
391
|
+
parentId: parentId ? parseId(parentId) : undefined,
|
|
392
|
+
privacy: privacy ? parseVarChar(privacy, 16) : undefined,
|
|
328
393
|
userId: sessionId
|
|
329
394
|
};
|
|
395
|
+
|
|
330
396
|
const db: Database = useDb(database);
|
|
331
397
|
const aqlQry: AqlQuery = aql`INSERT ${insert} IN posts RETURN NEW`;
|
|
332
398
|
|
|
@@ -336,7 +402,7 @@ export const addPost = (context: ApiContext, item: PostType): Promise<PostType>
|
|
|
336
402
|
const {_key: postKey} = post;
|
|
337
403
|
|
|
338
404
|
// Update linked tags within posts
|
|
339
|
-
return extractTags(db, 'posts', postKey, insert.
|
|
405
|
+
return extractTags(db, 'posts', postKey, insert.content)
|
|
340
406
|
.then((tagList: TagType[]) => {
|
|
341
407
|
post.tags = tagList;
|
|
342
408
|
return post;
|
|
@@ -352,36 +418,23 @@ export const updatePost = (context: ApiContext, item: PostType): Promise<PostTyp
|
|
|
352
418
|
const {database, userId: sessionId} = context;
|
|
353
419
|
const now: number = Date.now();
|
|
354
420
|
const {
|
|
421
|
+
content,
|
|
355
422
|
groupId,
|
|
356
|
-
id,
|
|
357
423
|
name,
|
|
358
424
|
parentId,
|
|
359
|
-
|
|
360
|
-
|
|
425
|
+
postId,
|
|
426
|
+
privacy
|
|
361
427
|
}: PostType = item;
|
|
362
428
|
|
|
363
|
-
const
|
|
364
|
-
|
|
429
|
+
const update: PostType = {
|
|
430
|
+
content: content ? parseString(content, MAX_CONTENT_LENGTH) : undefined,
|
|
431
|
+
modified: now,
|
|
432
|
+
name: name ? parseString(name, 160) : undefined,
|
|
433
|
+
parentId: parentId ? parseString(parentId, 160) : undefined,
|
|
434
|
+
privacy: privacy ? parseVarChar(privacy, 16) : undefined,
|
|
365
435
|
};
|
|
366
436
|
|
|
367
|
-
|
|
368
|
-
updatedPost.name = parseString(name, 160);
|
|
369
|
-
}
|
|
370
|
-
|
|
371
|
-
if(text) {
|
|
372
|
-
updatedPost.text = parseString(text, 640);
|
|
373
|
-
}
|
|
374
|
-
|
|
375
|
-
if(privacy) {
|
|
376
|
-
updatedPost.privacy = parseVarChar(privacy, 16);
|
|
377
|
-
}
|
|
378
|
-
|
|
379
|
-
if(parent) {
|
|
380
|
-
updatedPost.parentId = parseId(parentId);
|
|
381
|
-
}
|
|
382
|
-
const update: any = updatedPost;
|
|
383
|
-
|
|
384
|
-
let formatId: string = parseId(id);
|
|
437
|
+
let formatId: string = parseId(postId);
|
|
385
438
|
formatId = formatId === '' ? createHash(`post-${sessionId}`) : formatId;
|
|
386
439
|
const formatGroupId: string = parseId(groupId);
|
|
387
440
|
const insert: any = {
|
|
@@ -393,7 +446,7 @@ export const updatePost = (context: ApiContext, item: PostType): Promise<PostTyp
|
|
|
393
446
|
userId: sessionId
|
|
394
447
|
};
|
|
395
448
|
const db: Database = useDb(database);
|
|
396
|
-
const aqlQry: AqlQuery = aql`UPSERT {_key: ${
|
|
449
|
+
const aqlQry: AqlQuery = aql`UPSERT {_key: ${formatId}, userId: ${sessionId}}
|
|
397
450
|
INSERT ${insert}
|
|
398
451
|
UPDATE ${update}
|
|
399
452
|
IN posts RETURN NEW`;
|
|
@@ -404,7 +457,7 @@ export const updatePost = (context: ApiContext, item: PostType): Promise<PostTyp
|
|
|
404
457
|
const {_key: updatedPostKey} = updatedPost;
|
|
405
458
|
|
|
406
459
|
// Update linked tags
|
|
407
|
-
return extractTags(db, 'posts', updatedPostKey, update.
|
|
460
|
+
return extractTags(db, 'posts', updatedPostKey, update.content || '')
|
|
408
461
|
.then((tagList = []) => {
|
|
409
462
|
updatedPost.tags = tagList;
|
|
410
463
|
|
|
@@ -412,7 +465,7 @@ export const updatePost = (context: ApiContext, item: PostType): Promise<PostTyp
|
|
|
412
465
|
const files: FileType[] = updatedPost.files || [];
|
|
413
466
|
|
|
414
467
|
if(files.length) {
|
|
415
|
-
return updateFiles(db,
|
|
468
|
+
return updateFiles(db, formatId, files)
|
|
416
469
|
.then((fileList = []) => {
|
|
417
470
|
updatedPost.files = fileList;
|
|
418
471
|
return updatedPost;
|
package/src/data/users.ts
CHANGED
|
@@ -207,13 +207,11 @@ export const getUsersByRelations = (
|
|
|
207
207
|
const formatUserId: string = parseId(userId);
|
|
208
208
|
const formatType: string = parseChar(type, 32);
|
|
209
209
|
const limit = getLimit(from, to);
|
|
210
|
-
console.log('context', context);
|
|
211
210
|
const aqlQry: string = `FOR u, r IN INBOUND "${`users/${formatUserId}`}" hasRelation
|
|
212
211
|
FILTER r.type == "${formatType}"
|
|
213
212
|
${limit.aql}
|
|
214
213
|
RETURN u`;
|
|
215
214
|
|
|
216
|
-
console.log('getUsersByRelations::aqlQry', aqlQry);
|
|
217
215
|
return useDb(database).query(aqlQry)
|
|
218
216
|
.then((cursor: ArrayCursor) => cursor.all())
|
|
219
217
|
.catch((error: Error) => logError({
|
package/src/types/apps.ts
CHANGED
package/src/types/auth.ts
CHANGED
package/src/types/files.ts
CHANGED
|
@@ -5,7 +5,6 @@
|
|
|
5
5
|
export interface FileType {
|
|
6
6
|
readonly _key?: string;
|
|
7
7
|
readonly added?: number;
|
|
8
|
-
readonly appId?: string;
|
|
9
8
|
readonly base64?: string;
|
|
10
9
|
readonly buffer?: Buffer;
|
|
11
10
|
readonly description?: string;
|
|
@@ -26,7 +25,6 @@ export interface FileDecodedType {
|
|
|
26
25
|
}
|
|
27
26
|
|
|
28
27
|
export interface FileEdgeType {
|
|
29
|
-
readonly appId?: string;
|
|
30
28
|
readonly imgId?: string;
|
|
31
29
|
readonly itemId?: string;
|
|
32
30
|
readonly itemType?: string;
|
package/src/types/groups.ts
CHANGED
package/src/types/images.ts
CHANGED
|
@@ -23,7 +23,6 @@ export interface ImageIdentifyType {
|
|
|
23
23
|
export type ImageUrlTypes = 'app' | 'events' | 'groups' | 'users';
|
|
24
24
|
|
|
25
25
|
export interface ImageUrlData {
|
|
26
|
-
readonly appId?: string;
|
|
27
26
|
readonly directory?: string;
|
|
28
27
|
readonly imgId?: string;
|
|
29
28
|
readonly imgType?: string;
|
package/src/types/locations.ts
CHANGED
package/src/types/payments.ts
CHANGED
|
@@ -9,7 +9,6 @@ export interface PaymentCardType {
|
|
|
9
9
|
readonly acceptedTerms?: boolean;
|
|
10
10
|
readonly accountNumber?: string;
|
|
11
11
|
readonly added?: number;
|
|
12
|
-
readonly appId?: string;
|
|
13
12
|
readonly brand?: string;
|
|
14
13
|
city?: string;
|
|
15
14
|
country?: string;
|
|
@@ -35,7 +34,6 @@ export interface PaymentBankAccount {
|
|
|
35
34
|
export interface PaymentCharge {
|
|
36
35
|
readonly added?: number;
|
|
37
36
|
readonly amount?: number;
|
|
38
|
-
readonly appId?: string;
|
|
39
37
|
readonly capture?: boolean;
|
|
40
38
|
readonly cardId?: string;
|
|
41
39
|
readonly chargeFailCode?: string;
|
|
@@ -51,7 +49,6 @@ export interface PaymentCharge {
|
|
|
51
49
|
export interface PaymentTransfer {
|
|
52
50
|
readonly added?: number;
|
|
53
51
|
readonly amount?: number;
|
|
54
|
-
readonly appId?: string;
|
|
55
52
|
readonly currency?: string;
|
|
56
53
|
readonly description?: string;
|
|
57
54
|
readonly modified?: number;
|
|
@@ -64,7 +61,6 @@ export interface PaymentPlan {
|
|
|
64
61
|
readonly _key?: string;
|
|
65
62
|
readonly added?: number;
|
|
66
63
|
readonly amount?: number;
|
|
67
|
-
readonly appId?: string;
|
|
68
64
|
readonly currency?: string;
|
|
69
65
|
readonly description?: string;
|
|
70
66
|
readonly id?: string;
|
|
@@ -77,7 +73,6 @@ export interface PaymentPlan {
|
|
|
77
73
|
export interface PaymentSubscription {
|
|
78
74
|
readonly _key?: string;
|
|
79
75
|
readonly added?: number;
|
|
80
|
-
readonly appId?: string;
|
|
81
76
|
readonly cancelDate?: number;
|
|
82
77
|
readonly expires?: number;
|
|
83
78
|
readonly id?: string;
|
package/src/types/posts.ts
CHANGED
|
@@ -9,17 +9,25 @@ export interface PostType {
|
|
|
9
9
|
readonly _id?: string;
|
|
10
10
|
readonly _key?: string;
|
|
11
11
|
readonly added?: number;
|
|
12
|
-
|
|
12
|
+
content?: string;
|
|
13
13
|
files?: FileType[];
|
|
14
14
|
readonly groupId?: string;
|
|
15
|
-
readonly
|
|
15
|
+
readonly postId?: string;
|
|
16
|
+
readonly latitude?: number;
|
|
17
|
+
readonly location?: string;
|
|
18
|
+
readonly longitude?: number;
|
|
16
19
|
readonly modified?: number;
|
|
17
20
|
name?: string;
|
|
18
21
|
parentId?: string;
|
|
19
22
|
privacy?: string;
|
|
20
23
|
tags?: TagType[];
|
|
21
|
-
text?: string;
|
|
22
|
-
title?: string;
|
|
23
24
|
type?: string;
|
|
24
25
|
readonly userId?: string;
|
|
25
26
|
}
|
|
27
|
+
|
|
28
|
+
export interface PostOptions {
|
|
29
|
+
readonly latitude?: number;
|
|
30
|
+
readonly longitude?: number;
|
|
31
|
+
readonly from?: number;
|
|
32
|
+
readonly to?: number;
|
|
33
|
+
}
|
package/src/types/tags.ts
CHANGED
package/src/utils/auth.ts
CHANGED
|
@@ -2,10 +2,43 @@
|
|
|
2
2
|
* Copyright (c) 2019-Present, Nitrogen Labs, Inc.
|
|
3
3
|
* Copyrights licensed under the MIT License. See the accompanying LICENSE file for terms.
|
|
4
4
|
*/
|
|
5
|
+
import isPlainObject from 'lodash/isPlainObject';
|
|
6
|
+
import isString from 'lodash/isString';
|
|
7
|
+
|
|
5
8
|
import {ApiContext} from '../types/auth';
|
|
6
9
|
|
|
7
|
-
export const
|
|
8
|
-
|
|
10
|
+
export const parseJsonData = (data): any => {
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(data);
|
|
13
|
+
} catch(error) {
|
|
14
|
+
return data;
|
|
15
|
+
}
|
|
16
|
+
};
|
|
17
|
+
|
|
18
|
+
export const getLambdaData = (data: any) => {
|
|
19
|
+
if(isPlainObject(data)) {
|
|
20
|
+
const queryData = data.body || data['body-json'];
|
|
21
|
+
const {requestContext, isOffline} = data;
|
|
22
|
+
|
|
23
|
+
return {
|
|
24
|
+
body: queryData ? parseJsonData(queryData) : data,
|
|
25
|
+
context: requestContext ? {...requestContext, isOffline} : {isOffline}
|
|
26
|
+
};
|
|
27
|
+
} else if(isString(data)) {
|
|
28
|
+
return {
|
|
29
|
+
body: parseJsonData(data),
|
|
30
|
+
context: {}
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
return {
|
|
35
|
+
body: {},
|
|
36
|
+
context: {}
|
|
37
|
+
};
|
|
38
|
+
};
|
|
39
|
+
|
|
40
|
+
export const parseContext = (appId: string, data: any): ApiContext => {
|
|
41
|
+
const {authorizer = {}, identity, isOffline} = data;
|
|
9
42
|
const {claims} = authorizer;
|
|
10
43
|
|
|
11
44
|
if(claims) {
|