jinaga-server 2.5.0 → 2.6.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/dist/authorization/authorization-keystore.d.ts +5 -4
- package/dist/authorization/authorization-keystore.js +16 -13
- package/dist/authorization/authorization-keystore.js.map +1 -1
- package/dist/http/router.d.ts +5 -3
- package/dist/http/router.js +125 -52
- package/dist/http/router.js.map +1 -1
- package/dist/http/stream.d.ts +10 -0
- package/dist/http/stream.js +35 -0
- package/dist/http/stream.js.map +1 -0
- package/dist/index.d.ts +1 -2
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/jinaga-server.js +7 -8
- package/dist/jinaga-server.js.map +1 -1
- package/dist/postgres/postgres-store.d.ts +4 -4
- package/dist/postgres/postgres-store.js +2 -2
- package/dist/postgres/postgres-store.js.map +1 -1
- package/dist/postgres/query-description.d.ts +75 -0
- package/dist/postgres/query-description.js +283 -0
- package/dist/postgres/query-description.js.map +1 -0
- package/dist/postgres/specification-result-sql.d.ts +2 -2
- package/dist/postgres/specification-result-sql.js +39 -324
- package/dist/postgres/specification-result-sql.js.map +1 -1
- package/dist/postgres/specification-sql.d.ts +2 -2
- package/dist/postgres/specification-sql.js +60 -163
- package/dist/postgres/specification-sql.js.map +1 -1
- package/http/sans-auth/.env.local +1 -0
- package/http/sans-auth/Create post sans auth.http +27 -0
- package/http/sans-auth/Create site sans auth.http +11 -0
- package/http/sans-auth/Feed sites.http +1 -0
- package/http/sans-auth/Feeds sites.http +12 -0
- package/http/sans-auth/Get posts sans auth.http +35 -0
- package/http/sans-auth/Get sites sans auth.http +12 -0
- package/http/sans-auth/stream.sh +2 -0
- package/integration-test/jinaga-test/Dockerfile +1 -1
- package/integration-test/jinaga-test/package-lock.json +917 -748
- package/integration-test/jinaga-test/package.json +3 -3
- package/package.json +2 -2
- package/replicator/package-lock.json +16 -16
- package/replicator/package.json +1 -1
- package/src/authorization/authorization-keystore.ts +23 -14
- package/src/http/router.ts +154 -64
- package/src/http/stream.ts +32 -0
- package/src/index.ts +1 -2
- package/src/jinaga-server.ts +8 -8
- package/src/postgres/postgres-store.ts +5 -8
- package/src/postgres/query-description.ts +435 -0
- package/src/postgres/specification-result-sql.ts +56 -489
- package/src/postgres/specification-sql.ts +71 -232
- package/test/authorization/authorizationSpec.ts +12 -2
- package/test/postgres/postgresSpecificationSpec.ts +15 -15
- package/dist/http/feed-cache.d.ts +0 -12
- package/dist/http/feed-cache.js +0 -3
- package/dist/http/feed-cache.js.map +0 -1
- package/dist/memory/memory-feed-cache.d.ts +0 -6
- package/dist/memory/memory-feed-cache.js +0 -17
- package/dist/memory/memory-feed-cache.js.map +0 -1
- package/src/http/feed-cache.ts +0 -14
- package/src/memory/memory-feed-cache.ts +0 -14
|
@@ -1,15 +1,11 @@
|
|
|
1
1
|
import {
|
|
2
2
|
buildFeeds,
|
|
3
|
-
EdgeDescription as FeedEdgeDescription,
|
|
4
3
|
FactReference,
|
|
5
|
-
Feed,
|
|
6
|
-
InputDescription as FeedInputDescription,
|
|
7
|
-
NotExistsConditionDescription as FeedNotExistsConditionDescription,
|
|
8
|
-
OutputDescription as FeedOutputDescription,
|
|
9
4
|
Specification,
|
|
5
|
+
validateGiven
|
|
10
6
|
} from "jinaga";
|
|
11
7
|
|
|
12
|
-
import {
|
|
8
|
+
import { EdgeDescription, ExistentialConditionDescription, QueryDescription, QueryDescriptionBuider } from "./query-description";
|
|
13
9
|
|
|
14
10
|
interface SpecificationLabel {
|
|
15
11
|
type: string;
|
|
@@ -23,67 +19,40 @@ interface SpecificationSqlQuery {
|
|
|
23
19
|
bookmark: string;
|
|
24
20
|
};
|
|
25
21
|
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
.
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
const firstEdge = this.edges[0];
|
|
61
|
-
const predecessorFact = this.inputs.find(i => i.factIndex === firstEdge.predecessorFactIndex);
|
|
62
|
-
const successorFact = this.inputs.find(i => i.factIndex === firstEdge.successorFactIndex);
|
|
63
|
-
const firstFactIndex = predecessorFact ? predecessorFact.factIndex : successorFact!.factIndex;
|
|
64
|
-
const writtenFactIndexes = new Set<number>().add(firstFactIndex);
|
|
65
|
-
const joins: string[] = generateJoins(schema, this.edges, writtenFactIndexes);
|
|
66
|
-
const inputWhereClauses = this.inputs
|
|
67
|
-
.filter(input => input.factTypeParameter !== 0)
|
|
68
|
-
.map(input => `f${input.factIndex}.fact_type_id = $${input.factTypeParameter} AND f${input.factIndex}.hash = $${input.factHashParameter}`)
|
|
69
|
-
.join(" AND ");
|
|
70
|
-
const notExistsWhereClauses = this.notExistsConditions
|
|
71
|
-
.map(notExistsWhereClause => ` AND NOT EXISTS (${generateNotExistsWhereClause(schema, notExistsWhereClause, writtenFactIndexes)})`)
|
|
72
|
-
.join("");
|
|
73
|
-
const bookmarkParameter = this.parameters.length + 1;
|
|
74
|
-
const limitParameter = bookmarkParameter + 1;
|
|
75
|
-
const sql = `SELECT ${hashes}, sort(array[${factIds}], 'desc') as bookmark FROM ${schema}.fact f${firstFactIndex}${joins.join("")} WHERE ${inputWhereClauses}${notExistsWhereClauses} AND sort(array[${factIds}], 'desc') > $${bookmarkParameter} ORDER BY bookmark ASC LIMIT $${limitParameter}`;
|
|
76
|
-
const bookmarkValue: number[] = parseBookmark(bookmark);
|
|
77
|
-
return {
|
|
78
|
-
sql,
|
|
79
|
-
parameters: [...this.parameters, bookmarkValue, limit],
|
|
80
|
-
labels: this.outputs.map(output => ({
|
|
81
|
-
type: output.type,
|
|
82
|
-
index: output.factIndex
|
|
83
|
-
})),
|
|
84
|
-
bookmark: "[]"
|
|
85
|
-
};
|
|
86
|
-
}
|
|
22
|
+
function generateSqlQuery(queryDescription: QueryDescription, schema: string, bookmark: string, limit: number): SpecificationSqlQuery {
|
|
23
|
+
const hashes = queryDescription.outputs
|
|
24
|
+
.map(output => `f${output.factIndex}.hash as hash${output.factIndex}`)
|
|
25
|
+
.join(", ");
|
|
26
|
+
const factIds = queryDescription.outputs
|
|
27
|
+
.map(output => `f${output.factIndex}.fact_id`)
|
|
28
|
+
.join(", ");
|
|
29
|
+
const firstEdge = queryDescription.edges[0];
|
|
30
|
+
const predecessorFact = queryDescription.inputs.find(i => i.factIndex === firstEdge.predecessorFactIndex);
|
|
31
|
+
const successorFact = queryDescription.inputs.find(i => i.factIndex === firstEdge.successorFactIndex);
|
|
32
|
+
const firstFactIndex = predecessorFact ? predecessorFact.factIndex : successorFact!.factIndex;
|
|
33
|
+
const writtenFactIndexes = new Set<number>().add(firstFactIndex);
|
|
34
|
+
const joins: string[] = generateJoins(schema, queryDescription.edges, writtenFactIndexes);
|
|
35
|
+
const inputWhereClauses = queryDescription.inputs
|
|
36
|
+
.filter(input => input.factTypeParameter !== 0)
|
|
37
|
+
.map(input => `f${input.factIndex}.fact_type_id = $${input.factTypeParameter} AND f${input.factIndex}.hash = $${input.factHashParameter}`)
|
|
38
|
+
.join(" AND ");
|
|
39
|
+
const notExistsWhereClauses = (queryDescription.existentialConditions
|
|
40
|
+
.filter(c => c.exists === false))
|
|
41
|
+
.map(notExistsWhereClause => ` AND NOT EXISTS (${generateNotExistsWhereClause(schema, notExistsWhereClause, writtenFactIndexes)})`)
|
|
42
|
+
.join("");
|
|
43
|
+
const bookmarkParameter = queryDescription.parameters.length + 1;
|
|
44
|
+
const limitParameter = bookmarkParameter + 1;
|
|
45
|
+
const sql = `SELECT ${hashes}, sort(array[${factIds}], 'desc') as bookmark FROM ${schema}.fact f${firstFactIndex}${joins.join("")} WHERE ${inputWhereClauses}${notExistsWhereClauses} AND sort(array[${factIds}], 'desc') > $${bookmarkParameter} ORDER BY bookmark ASC LIMIT $${limitParameter}`;
|
|
46
|
+
const bookmarkValue: number[] = parseBookmark(bookmark);
|
|
47
|
+
return {
|
|
48
|
+
sql,
|
|
49
|
+
parameters: [...queryDescription.parameters, bookmarkValue, limit],
|
|
50
|
+
labels: queryDescription.outputs.map(output => ({
|
|
51
|
+
type: output.type,
|
|
52
|
+
index: output.factIndex
|
|
53
|
+
})),
|
|
54
|
+
bookmark: "[]"
|
|
55
|
+
};
|
|
87
56
|
}
|
|
88
57
|
|
|
89
58
|
function generateJoins(schema: string, edges: EdgeDescription[], writtenFactIndexes: Set<number>) {
|
|
@@ -130,7 +99,7 @@ function generateJoins(schema: string, edges: EdgeDescription[], writtenFactInde
|
|
|
130
99
|
return joins;
|
|
131
100
|
}
|
|
132
101
|
|
|
133
|
-
function generateNotExistsWhereClause(schema: string, notExistsWhereClause:
|
|
102
|
+
function generateNotExistsWhereClause(schema: string, notExistsWhereClause: ExistentialConditionDescription, outerFactIndexes: Set<number>): string {
|
|
134
103
|
const firstEdge = notExistsWhereClause.edges[0];
|
|
135
104
|
const writtenFactIndexes = new Set<number>(outerFactIndexes);
|
|
136
105
|
const firstJoin: string[] = [];
|
|
@@ -192,182 +161,52 @@ function parseBookmark(bookmark: string): number[] {
|
|
|
192
161
|
}
|
|
193
162
|
}
|
|
194
163
|
|
|
195
|
-
class DescriptionBuilder {
|
|
196
|
-
constructor(
|
|
197
|
-
private factTypes: FactTypeMap,
|
|
198
|
-
private roleMap: RoleMap
|
|
199
|
-
) { }
|
|
200
|
-
|
|
201
|
-
isSatisfiable(feed: Feed, edges: FeedEdgeDescription[]): boolean {
|
|
202
|
-
for (const edge of edges) {
|
|
203
|
-
const successor = feed.facts.find(f => f.factIndex === edge.successorFactIndex);
|
|
204
|
-
if (!successor) {
|
|
205
|
-
return false;
|
|
206
|
-
}
|
|
207
|
-
|
|
208
|
-
const predecessor = feed.facts.find(f => f.factIndex === edge.predecessorFactIndex);
|
|
209
|
-
if (!predecessor) {
|
|
210
|
-
return false;
|
|
211
|
-
}
|
|
212
|
-
|
|
213
|
-
const successorFactTypeId = getFactTypeId(this.factTypes, successor.factType);
|
|
214
|
-
if (!successorFactTypeId) {
|
|
215
|
-
return false;
|
|
216
|
-
}
|
|
217
|
-
|
|
218
|
-
if (!getRoleId(this.roleMap, successorFactTypeId, edge.roleName)) {
|
|
219
|
-
return false;
|
|
220
|
-
}
|
|
221
|
-
|
|
222
|
-
const predecessorFactTypeId = getFactTypeId(this.factTypes, predecessor.factType);
|
|
223
|
-
if (!predecessorFactTypeId) {
|
|
224
|
-
return false;
|
|
225
|
-
}
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
return true;
|
|
229
|
-
}
|
|
230
|
-
|
|
231
|
-
buildDescription(feed: Feed, start: FactReference[]): QueryDescription {
|
|
232
|
-
const parameters: (string | number)[] = [];
|
|
233
|
-
function addParameter(value: string | number) {
|
|
234
|
-
parameters.push(value);
|
|
235
|
-
return parameters.length;
|
|
236
|
-
}
|
|
237
|
-
|
|
238
|
-
// Allocate parameters for the inputs.
|
|
239
|
-
const inputs: InputDescription[] = feed.inputs.map(input =>
|
|
240
|
-
this.buildInputDescription(feed, input, start, addParameter)
|
|
241
|
-
);
|
|
242
|
-
|
|
243
|
-
// Allocate parameters for the edge roles.
|
|
244
|
-
const edges: EdgeDescription[] = feed.edges.map(edge =>
|
|
245
|
-
this.buildEdgeDescription(feed, edge, addParameter)
|
|
246
|
-
);
|
|
247
|
-
|
|
248
|
-
// Allocate parameters for the conditional roles.
|
|
249
|
-
const satisfiableNotExistsConditions = feed.notExistsConditions.filter(condition =>
|
|
250
|
-
this.isSatisfiable(feed, condition.edges)
|
|
251
|
-
);
|
|
252
|
-
const notExistsConditions: NotExistsConditionDescription[] = satisfiableNotExistsConditions.map(condition =>
|
|
253
|
-
this.buildNotExistsConditionDescription(feed, condition, addParameter)
|
|
254
|
-
);
|
|
255
|
-
|
|
256
|
-
const outputs: OutputDescription[] = feed.outputs.map(output =>
|
|
257
|
-
this.buildOutputDescription(feed, output)
|
|
258
|
-
);
|
|
259
|
-
|
|
260
|
-
return new QueryDescription(
|
|
261
|
-
inputs,
|
|
262
|
-
parameters,
|
|
263
|
-
outputs,
|
|
264
|
-
edges,
|
|
265
|
-
notExistsConditions
|
|
266
|
-
);
|
|
267
|
-
}
|
|
268
|
-
|
|
269
|
-
private buildInputDescription(feed: Feed, input: FeedInputDescription, start: FactReference[], addParameter: (value: string | number) => number): InputDescription {
|
|
270
|
-
const fact = feed.facts.find(f => f.factIndex === input.factIndex);
|
|
271
|
-
if (!fact) {
|
|
272
|
-
throw new Error(`Fact not found: ${input.factIndex}`);
|
|
273
|
-
}
|
|
274
|
-
|
|
275
|
-
const factTypeId = getFactTypeId(this.factTypes, fact.factType);
|
|
276
|
-
if (!factTypeId) {
|
|
277
|
-
throw new Error(`Fact type not found: ${fact.factType}`);
|
|
278
|
-
}
|
|
279
|
-
|
|
280
|
-
const factTypeParameter = addParameter(factTypeId);
|
|
281
|
-
const factHashParameter = addParameter(start[input.inputIndex].hash);
|
|
282
|
-
return {
|
|
283
|
-
factIndex: input.factIndex,
|
|
284
|
-
factTypeParameter,
|
|
285
|
-
factHashParameter
|
|
286
|
-
};
|
|
287
|
-
}
|
|
288
|
-
|
|
289
|
-
private buildEdgeDescription(feed: Feed, edge: FeedEdgeDescription, addParameter: (value: string | number) => number) {
|
|
290
|
-
const fact = feed.facts.find(f => f.factIndex === edge.successorFactIndex);
|
|
291
|
-
if (!fact) {
|
|
292
|
-
throw new Error(`Fact not found: ${edge.successorFactIndex}`);
|
|
293
|
-
}
|
|
294
|
-
|
|
295
|
-
const factTypeId = getFactTypeId(this.factTypes, fact.factType);
|
|
296
|
-
if (!factTypeId) {
|
|
297
|
-
throw new Error(`Fact type not found: ${fact.factType}`);
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
const roleId = getRoleId(this.roleMap, factTypeId, edge.roleName);
|
|
301
|
-
if (!roleId) {
|
|
302
|
-
throw new Error(`Role not found: ${fact.factType}.${edge.roleName}`);
|
|
303
|
-
}
|
|
304
|
-
|
|
305
|
-
const roleParameter = addParameter(roleId);
|
|
306
|
-
return <EdgeDescription>{
|
|
307
|
-
edgeIndex: edge.edgeIndex,
|
|
308
|
-
predecessorFactIndex: edge.predecessorFactIndex,
|
|
309
|
-
successorFactIndex: edge.successorFactIndex,
|
|
310
|
-
roleParameter
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
|
|
314
|
-
private buildOutputDescription(feed: Feed, output: FeedOutputDescription) {
|
|
315
|
-
const fact = feed.facts.find(f => f.factIndex === output.factIndex);
|
|
316
|
-
if (!fact) {
|
|
317
|
-
throw new Error(`Fact not found: ${output.factIndex}`);
|
|
318
|
-
}
|
|
319
|
-
|
|
320
|
-
return <OutputDescription>{
|
|
321
|
-
factIndex: output.factIndex,
|
|
322
|
-
type: fact.factType
|
|
323
|
-
};
|
|
324
|
-
}
|
|
325
|
-
|
|
326
|
-
private buildNotExistsConditionDescription(feed: Feed, condition: FeedNotExistsConditionDescription, addParameter: (value: string | number) => number): NotExistsConditionDescription {
|
|
327
|
-
const edges = condition.edges.map(edge =>
|
|
328
|
-
this.buildEdgeDescription(feed, edge, addParameter)
|
|
329
|
-
);
|
|
330
|
-
|
|
331
|
-
return {
|
|
332
|
-
edges
|
|
333
|
-
}
|
|
334
|
-
}
|
|
335
|
-
}
|
|
336
|
-
|
|
337
164
|
export function sqlFromSpecification(start: FactReference[], schema: string, bookmarks: string[], limit: number, specification: Specification, factTypes: Map<string, number>, roleMap: Map<number, Map<string, number>>): SpecificationSqlQuery[] {
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
}
|
|
165
|
+
validateGiven(start, specification);
|
|
166
|
+
|
|
167
|
+
const labeledStart = start.map((s, index) => ({
|
|
168
|
+
name: specification.given[index].name,
|
|
169
|
+
reference: s
|
|
170
|
+
})).reduce((map, s) => {
|
|
171
|
+
map.set(s.name, s.reference);
|
|
172
|
+
return map;
|
|
173
|
+
}, new Map<string, FactReference>());
|
|
348
174
|
|
|
349
175
|
const feeds = buildFeeds(specification);
|
|
350
|
-
const
|
|
176
|
+
const queryDescriptionBuilder = new QueryDescriptionBuider(factTypes, roleMap);
|
|
351
177
|
const feedAndBookmark = feeds.map((feed, index) => ({
|
|
352
178
|
feed,
|
|
353
179
|
bookmark: bookmarks[index]
|
|
354
180
|
}));
|
|
355
|
-
const
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
181
|
+
const queryDescriptionsAndBookmarks = feedAndBookmark.map(fb => {
|
|
182
|
+
const feedStart = fb.feed.given.map(s => labeledStart.get(s.name)!);
|
|
183
|
+
return {
|
|
184
|
+
queryDescription: buildQueryDescription(queryDescriptionBuilder, fb.feed, feedStart),
|
|
185
|
+
bookmark: fb.bookmark
|
|
186
|
+
};
|
|
361
187
|
});
|
|
188
|
+
const satisfiableQueryDescriptionsAndBookmarks = queryDescriptionsAndBookmarks.filter(qb =>
|
|
189
|
+
qb.queryDescription.isSatisfiable());
|
|
190
|
+
const sqlQueries = satisfiableQueryDescriptionsAndBookmarks.map(qdb =>
|
|
191
|
+
generateSqlQuery(qdb.queryDescription, schema, qdb.bookmark, limit));
|
|
362
192
|
return sqlQueries;
|
|
363
193
|
}
|
|
364
194
|
|
|
365
|
-
export function sqlFromFeed(feed:
|
|
366
|
-
const
|
|
367
|
-
|
|
195
|
+
export function sqlFromFeed(feed: Specification, start: FactReference[], schema: string, bookmark: string, limit: number, factTypes: Map<string, number>, roleMap: Map<number, Map<string, number>>): SpecificationSqlQuery | null {
|
|
196
|
+
const queryDescriptionBuilder = new QueryDescriptionBuider(factTypes, roleMap);
|
|
197
|
+
const queryDescription = buildQueryDescription(queryDescriptionBuilder, feed, start);
|
|
198
|
+
if (!queryDescription.isSatisfiable()) {
|
|
368
199
|
return null;
|
|
369
200
|
}
|
|
370
|
-
const
|
|
371
|
-
const sql = description.generateSqlQuery(schema, bookmark, limit);
|
|
201
|
+
const sql = generateSqlQuery(queryDescription, schema, bookmark, limit);
|
|
372
202
|
return sql;
|
|
373
203
|
}
|
|
204
|
+
|
|
205
|
+
function buildQueryDescription(queryDescriptionBuilder: QueryDescriptionBuider, specification: Specification, start: FactReference[]): QueryDescription {
|
|
206
|
+
const { queryDescription } = queryDescriptionBuilder.addEdges(
|
|
207
|
+
QueryDescription.unsatisfiable,
|
|
208
|
+
specification.given,
|
|
209
|
+
start, {}, [],
|
|
210
|
+
specification.matches);
|
|
211
|
+
return queryDescription;
|
|
212
|
+
}
|
|
@@ -1,11 +1,16 @@
|
|
|
1
1
|
import {
|
|
2
|
+
AuthenticationNoOp,
|
|
2
3
|
AuthorizationRules,
|
|
3
4
|
dehydrateFact,
|
|
4
5
|
ensure,
|
|
6
|
+
FactManager,
|
|
5
7
|
FactRecord,
|
|
6
8
|
hydrate,
|
|
7
9
|
Jinaga as j,
|
|
8
|
-
MemoryStore
|
|
10
|
+
MemoryStore,
|
|
11
|
+
NetworkNoOp,
|
|
12
|
+
ObservableSource,
|
|
13
|
+
PassThroughFork
|
|
9
14
|
} from "jinaga";
|
|
10
15
|
|
|
11
16
|
import { AuthorizationKeystore } from "../../src/authorization/authorization-keystore";
|
|
@@ -160,6 +165,11 @@ function givenStorage() {
|
|
|
160
165
|
function givenAuthorizationWithStorage(storage: MemoryStore) {
|
|
161
166
|
const keystore = new MemoryKeystore();
|
|
162
167
|
keystore.getOrCreateUserFact(givenMockUserIdentity());
|
|
168
|
+
const authentication = new AuthenticationNoOp();
|
|
169
|
+
const fork = new PassThroughFork(storage);
|
|
170
|
+
const observableSource = new ObservableSource(storage);
|
|
171
|
+
const network = new NetworkNoOp();
|
|
172
|
+
const factManager = new FactManager(authentication, fork, observableSource, storage, network);
|
|
163
173
|
const authorizationRules = new AuthorizationRules(undefined)
|
|
164
174
|
.any('Hashtag')
|
|
165
175
|
.no('Jinaga.User')
|
|
@@ -167,7 +177,7 @@ function givenAuthorizationWithStorage(storage: MemoryStore) {
|
|
|
167
177
|
.type('Like', j.for(likeUser))
|
|
168
178
|
.type('Delete', j.for(deleteSender))
|
|
169
179
|
;
|
|
170
|
-
return new AuthorizationKeystore(storage, keystore, authorizationRules, null);
|
|
180
|
+
return new AuthorizationKeystore(factManager, storage, keystore, authorizationRules, null);
|
|
171
181
|
}
|
|
172
182
|
|
|
173
183
|
function givenOtherUser() {
|
|
@@ -291,14 +291,14 @@ describe("Postgres query generator", () => {
|
|
|
291
291
|
'f3.hash as hash3, ' +
|
|
292
292
|
'sort(array[f2.fact_id, f3.fact_id], \'desc\') as bookmark ' +
|
|
293
293
|
'FROM public.fact f1 ' +
|
|
294
|
-
'JOIN public.edge e1 ON e1.predecessor_fact_id = f1.fact_id AND e1.role_id = $
|
|
294
|
+
'JOIN public.edge e1 ON e1.predecessor_fact_id = f1.fact_id AND e1.role_id = $3 ' +
|
|
295
295
|
'JOIN public.fact f2 ON f2.fact_id = e1.successor_fact_id ' +
|
|
296
|
-
'JOIN public.edge e2 ON e2.predecessor_fact_id = f2.fact_id AND e2.role_id = $
|
|
296
|
+
'JOIN public.edge e2 ON e2.predecessor_fact_id = f2.fact_id AND e2.role_id = $4 ' +
|
|
297
297
|
'JOIN public.fact f3 ON f3.fact_id = e2.successor_fact_id ' +
|
|
298
298
|
'JOIN public.edge e3 ON e3.successor_fact_id = f3.fact_id AND e3.role_id = $7 ' +
|
|
299
299
|
'JOIN public.fact f4 ON f4.fact_id = e3.predecessor_fact_id ' +
|
|
300
300
|
'WHERE f1.fact_type_id = $1 AND f1.hash = $2 ' +
|
|
301
|
-
'AND f4.fact_type_id = $
|
|
301
|
+
'AND f4.fact_type_id = $5 AND f4.hash = $6 ' +
|
|
302
302
|
'AND sort(array[f2.fact_id, f3.fact_id], \'desc\') > $8 ' +
|
|
303
303
|
'ORDER BY bookmark ASC ' +
|
|
304
304
|
'LIMIT $9'
|
|
@@ -306,10 +306,10 @@ describe("Postgres query generator", () => {
|
|
|
306
306
|
expect(sqlQueries[0].parameters).toEqual([
|
|
307
307
|
getFactTypeId(factTypes, "Root"),
|
|
308
308
|
rootHash,
|
|
309
|
-
getFactTypeId(factTypes, "Jinaga.User"),
|
|
310
|
-
userHash,
|
|
311
309
|
roleParameter(roleMap, factTypes, "MyApplication.Project", "root"),
|
|
312
310
|
roleParameter(roleMap, factTypes, "MyApplication.Assignment", "project"),
|
|
311
|
+
getFactTypeId(factTypes, "Jinaga.User"),
|
|
312
|
+
userHash,
|
|
313
313
|
roleParameter(roleMap, factTypes, "MyApplication.Assignment", "user"),
|
|
314
314
|
[],
|
|
315
315
|
100
|
|
@@ -344,15 +344,15 @@ describe("Postgres query generator", () => {
|
|
|
344
344
|
'SELECT f2.hash as hash2, ' +
|
|
345
345
|
'f3.hash as hash3, ' +
|
|
346
346
|
'sort(array[f2.fact_id, f3.fact_id], \'desc\') as bookmark ' +
|
|
347
|
-
'FROM public.fact f1 ' +
|
|
348
|
-
'JOIN public.edge e1 ON e1.predecessor_fact_id = f1.fact_id AND e1.role_id = $
|
|
349
|
-
'JOIN public.fact f2 ON f2.fact_id = e1.successor_fact_id ' +
|
|
350
|
-
'JOIN public.edge e2 ON e2.predecessor_fact_id = f2.fact_id AND e2.role_id = $
|
|
351
|
-
'JOIN public.fact f3 ON f3.fact_id = e2.successor_fact_id ' +
|
|
352
|
-
'JOIN public.edge e3 ON e3.successor_fact_id = f3.fact_id AND e3.role_id = $7 ' +
|
|
353
|
-
'JOIN public.fact f4 ON f4.fact_id = e3.predecessor_fact_id ' +
|
|
347
|
+
'FROM public.fact f1 ' + // root
|
|
348
|
+
'JOIN public.edge e1 ON e1.predecessor_fact_id = f1.fact_id AND e1.role_id = $3 ' + // project->root
|
|
349
|
+
'JOIN public.fact f2 ON f2.fact_id = e1.successor_fact_id ' + // project
|
|
350
|
+
'JOIN public.edge e2 ON e2.predecessor_fact_id = f2.fact_id AND e2.role_id = $4 ' + // assignment->project
|
|
351
|
+
'JOIN public.fact f3 ON f3.fact_id = e2.successor_fact_id ' + // assignment
|
|
352
|
+
'JOIN public.edge e3 ON e3.successor_fact_id = f3.fact_id AND e3.role_id = $7 ' + // assignment->user
|
|
353
|
+
'JOIN public.fact f4 ON f4.fact_id = e3.predecessor_fact_id ' + // user
|
|
354
354
|
'WHERE f1.fact_type_id = $1 AND f1.hash = $2 ' +
|
|
355
|
-
'AND f4.fact_type_id = $
|
|
355
|
+
'AND f4.fact_type_id = $5 AND f4.hash = $6 ' +
|
|
356
356
|
'AND sort(array[f2.fact_id, f3.fact_id], \'desc\') > $8 ' +
|
|
357
357
|
'ORDER BY bookmark ASC ' +
|
|
358
358
|
'LIMIT $9'
|
|
@@ -360,10 +360,10 @@ describe("Postgres query generator", () => {
|
|
|
360
360
|
expect(sqlQueries[0].parameters).toEqual([
|
|
361
361
|
getFactTypeId(factTypes, "Root"),
|
|
362
362
|
rootHash,
|
|
363
|
-
getFactTypeId(factTypes, "Jinaga.User"),
|
|
364
|
-
userHash,
|
|
365
363
|
roleParameter(roleMap, factTypes, "MyApplication.Project", "root"),
|
|
366
364
|
roleParameter(roleMap, factTypes, "MyApplication.Assignment", "project"),
|
|
365
|
+
getFactTypeId(factTypes, "Jinaga.User"),
|
|
366
|
+
userHash,
|
|
367
367
|
roleParameter(roleMap, factTypes, "MyApplication.Assignment", "user"),
|
|
368
368
|
[],
|
|
369
369
|
100
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { FactReference, Feed } from "jinaga";
|
|
2
|
-
export interface FeedDefinition {
|
|
3
|
-
start: {
|
|
4
|
-
factReference: FactReference;
|
|
5
|
-
index: number;
|
|
6
|
-
}[];
|
|
7
|
-
feed: Feed;
|
|
8
|
-
}
|
|
9
|
-
export interface FeedCache {
|
|
10
|
-
storeFeed(feedHash: string, feedDefinition: FeedDefinition): Promise<void>;
|
|
11
|
-
getFeed(feedHash: string): Promise<FeedDefinition | undefined>;
|
|
12
|
-
}
|
package/dist/http/feed-cache.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"feed-cache.js","sourceRoot":"","sources":["../../src/http/feed-cache.ts"],"names":[],"mappings":""}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
import { FeedCache, FeedDefinition } from "../http/feed-cache";
|
|
2
|
-
export declare class MemoryFeedCache implements FeedCache {
|
|
3
|
-
private feedDefinitions;
|
|
4
|
-
storeFeed(feedHash: string, feedDefinition: FeedDefinition): Promise<void>;
|
|
5
|
-
getFeed(feedHash: string): Promise<FeedDefinition | undefined>;
|
|
6
|
-
}
|
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.MemoryFeedCache = void 0;
|
|
4
|
-
class MemoryFeedCache {
|
|
5
|
-
constructor() {
|
|
6
|
-
this.feedDefinitions = {};
|
|
7
|
-
}
|
|
8
|
-
storeFeed(feedHash, feedDefinition) {
|
|
9
|
-
this.feedDefinitions[feedHash] = feedDefinition;
|
|
10
|
-
return Promise.resolve();
|
|
11
|
-
}
|
|
12
|
-
getFeed(feedHash) {
|
|
13
|
-
return Promise.resolve(this.feedDefinitions[feedHash]);
|
|
14
|
-
}
|
|
15
|
-
}
|
|
16
|
-
exports.MemoryFeedCache = MemoryFeedCache;
|
|
17
|
-
//# sourceMappingURL=memory-feed-cache.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"memory-feed-cache.js","sourceRoot":"","sources":["../../src/memory/memory-feed-cache.ts"],"names":[],"mappings":";;;AAEA,MAAa,eAAe;IAA5B;QACY,oBAAe,GAA2C,EAAE,CAAC;IAUzE,CAAC;IARG,SAAS,CAAC,QAAgB,EAAE,cAA8B;QACtD,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,GAAG,cAAc,CAAC;QAChD,OAAO,OAAO,CAAC,OAAO,EAAE,CAAC;IAC7B,CAAC;IAED,OAAO,CAAC,QAAgB;QACpB,OAAO,OAAO,CAAC,OAAO,CAAC,IAAI,CAAC,eAAe,CAAC,QAAQ,CAAC,CAAC,CAAC;IAC3D,CAAC;CACJ;AAXD,0CAWC"}
|
package/src/http/feed-cache.ts
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { FactReference, Feed } from "jinaga";
|
|
2
|
-
|
|
3
|
-
export interface FeedDefinition {
|
|
4
|
-
start: {
|
|
5
|
-
factReference: FactReference,
|
|
6
|
-
index: number
|
|
7
|
-
}[],
|
|
8
|
-
feed: Feed
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
export interface FeedCache {
|
|
12
|
-
storeFeed(feedHash: string, feedDefinition: FeedDefinition): Promise<void>;
|
|
13
|
-
getFeed(feedHash: string): Promise<FeedDefinition | undefined>;
|
|
14
|
-
}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import { FeedCache, FeedDefinition } from "../http/feed-cache";
|
|
2
|
-
|
|
3
|
-
export class MemoryFeedCache implements FeedCache {
|
|
4
|
-
private feedDefinitions: { [feedHash: string]: FeedDefinition } = {};
|
|
5
|
-
|
|
6
|
-
storeFeed(feedHash: string, feedDefinition: FeedDefinition): Promise<void> {
|
|
7
|
-
this.feedDefinitions[feedHash] = feedDefinition;
|
|
8
|
-
return Promise.resolve();
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
getFeed(feedHash: string): Promise<FeedDefinition | undefined> {
|
|
12
|
-
return Promise.resolve(this.feedDefinitions[feedHash]);
|
|
13
|
-
}
|
|
14
|
-
}
|