@geoprotocol/geo-sdk 0.16.0 → 0.18.0
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/README.md +173 -8
- package/dist/src/core/ids/system.d.ts +22 -0
- package/dist/src/core/ids/system.d.ts.map +1 -1
- package/dist/src/core/ids/system.js +26 -0
- package/dist/src/core/ids/system.js.map +1 -1
- package/dist/src/full-flow-test.test.js +146 -2
- package/dist/src/full-flow-test.test.js.map +1 -1
- package/dist/src/graph/comment-utils.d.ts +5 -0
- package/dist/src/graph/comment-utils.d.ts.map +1 -0
- package/dist/src/graph/comment-utils.js +23 -0
- package/dist/src/graph/comment-utils.js.map +1 -0
- package/dist/src/graph/create-comment.d.ts +28 -0
- package/dist/src/graph/create-comment.d.ts.map +1 -0
- package/dist/src/graph/create-comment.js +142 -0
- package/dist/src/graph/create-comment.js.map +1 -0
- package/dist/src/graph/create-comment.test.d.ts +2 -0
- package/dist/src/graph/create-comment.test.d.ts.map +1 -0
- package/dist/src/graph/create-comment.test.js +262 -0
- package/dist/src/graph/create-comment.test.js.map +1 -0
- package/dist/src/graph/create-proposal-review.d.ts +32 -0
- package/dist/src/graph/create-proposal-review.d.ts.map +1 -0
- package/dist/src/graph/create-proposal-review.js +62 -0
- package/dist/src/graph/create-proposal-review.js.map +1 -0
- package/dist/src/graph/create-proposal-review.test.d.ts +2 -0
- package/dist/src/graph/create-proposal-review.test.d.ts.map +1 -0
- package/dist/src/graph/create-proposal-review.test.js +162 -0
- package/dist/src/graph/create-proposal-review.test.js.map +1 -0
- package/dist/src/graph/index.d.ts +4 -0
- package/dist/src/graph/index.d.ts.map +1 -1
- package/dist/src/graph/index.js +4 -0
- package/dist/src/graph/index.js.map +1 -1
- package/dist/src/graph/update-comment.d.ts +20 -0
- package/dist/src/graph/update-comment.d.ts.map +1 -0
- package/dist/src/graph/update-comment.js +45 -0
- package/dist/src/graph/update-comment.js.map +1 -0
- package/dist/src/graph/update-comment.test.d.ts +2 -0
- package/dist/src/graph/update-comment.test.d.ts.map +1 -0
- package/dist/src/graph/update-comment.test.js +110 -0
- package/dist/src/graph/update-comment.test.js.map +1 -0
- package/dist/src/graph/update-proposal-review.d.ts +31 -0
- package/dist/src/graph/update-proposal-review.d.ts.map +1 -0
- package/dist/src/graph/update-proposal-review.js +49 -0
- package/dist/src/graph/update-proposal-review.js.map +1 -0
- package/dist/src/graph/update-proposal-review.test.d.ts +2 -0
- package/dist/src/graph/update-proposal-review.test.d.ts.map +1 -0
- package/dist/src/graph/update-proposal-review.test.js +95 -0
- package/dist/src/graph/update-proposal-review.test.js.map +1 -0
- package/dist/src/ipfs.d.ts +1 -1
- package/dist/src/ipfs.d.ts.map +1 -1
- package/dist/src/types.d.ts +46 -0
- package/dist/src/types.d.ts.map +1 -1
- package/dist/src/types.js.map +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-utils.d.ts","sourceRoot":"","sources":["../../../src/graph/comment-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAmBzD"}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Strips markdown syntax and returns the first 20 characters for use as the comment name.
|
|
3
|
+
*/
|
|
4
|
+
export function deriveCommentName(content) {
|
|
5
|
+
const stripped = content
|
|
6
|
+
.replace(/^#{1,6}\s+/gm, '') // headings
|
|
7
|
+
.replace(/\*\*(.+?)\*\*/g, '$1') // bold
|
|
8
|
+
.replace(/\*(.+?)\*/g, '$1') // italic
|
|
9
|
+
.replace(/__(.+?)__/g, '$1') // bold (underscore)
|
|
10
|
+
.replace(/_(.+?)_/g, '$1') // italic (underscore)
|
|
11
|
+
.replace(/~~(.+?)~~/g, '$1') // strikethrough
|
|
12
|
+
.replace(/`(.+?)`/g, '$1') // inline code
|
|
13
|
+
.replace(/\[(.+?)\]\(.+?\)/g, '$1') // links
|
|
14
|
+
.replace(/!\[.*?\]\(.+?\)/g, '') // images
|
|
15
|
+
.replace(/^>\s+/gm, '') // blockquotes
|
|
16
|
+
.replace(/^[-*+]\s+/gm, '') // unordered lists
|
|
17
|
+
.replace(/^\d+\.\s+/gm, '') // ordered lists
|
|
18
|
+
.replace(/---/g, '') // horizontal rules
|
|
19
|
+
.replace(/\n+/g, ' ') // newlines to spaces
|
|
20
|
+
.trim();
|
|
21
|
+
return stripped.slice(0, 20);
|
|
22
|
+
}
|
|
23
|
+
//# sourceMappingURL=comment-utils.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"comment-utils.js","sourceRoot":"","sources":["../../../src/graph/comment-utils.ts"],"names":[],"mappings":"AAAA;;GAEG;AACH,MAAM,UAAU,iBAAiB,CAAC,OAAe;IAC/C,MAAM,QAAQ,GAAG,OAAO;SACrB,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC,WAAW;SACvC,OAAO,CAAC,gBAAgB,EAAE,IAAI,CAAC,CAAC,OAAO;SACvC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,SAAS;SACrC,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,oBAAoB;SAChD,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,sBAAsB;SAChD,OAAO,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,gBAAgB;SAC5C,OAAO,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC,cAAc;SACxC,OAAO,CAAC,mBAAmB,EAAE,IAAI,CAAC,CAAC,QAAQ;SAC3C,OAAO,CAAC,kBAAkB,EAAE,EAAE,CAAC,CAAC,SAAS;SACzC,OAAO,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,cAAc;SACrC,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,kBAAkB;SAC7C,OAAO,CAAC,aAAa,EAAE,EAAE,CAAC,CAAC,gBAAgB;SAC3C,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,mBAAmB;SACvC,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,qBAAqB;SAC1C,IAAI,EAAE,CAAC;IAEV,OAAO,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;AAC/B,CAAC"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import type { CreateCommentParams, CreateResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a comment entity. Content can be plain text or markdown.
|
|
4
|
+
*
|
|
5
|
+
* When replying to a root entity (no existing reply-to relations), creates 1 reply-to relation.
|
|
6
|
+
* When replying to a comment that has already been published on the Knowledge Graph, carries
|
|
7
|
+
* forward all of the parent's reply-to relations and adds the parent itself, accumulating the
|
|
8
|
+
* full ancestor chain at any depth. The parent comment must be published before creating a
|
|
9
|
+
* reply so that its reply-to relations can be fetched. Reply-to relations are ordered by
|
|
10
|
+
* position: the direct parent comment has the lowest position and the root entity has the
|
|
11
|
+
* highest.
|
|
12
|
+
*
|
|
13
|
+
* @example
|
|
14
|
+
* ```ts
|
|
15
|
+
* import { Graph } from '@geoprotocol/geo-sdk';
|
|
16
|
+
*
|
|
17
|
+
* const { id, ops } = await Graph.createComment({
|
|
18
|
+
* content: 'I agree with this.',
|
|
19
|
+
* replyTo: { entityId: someId, spaceId: spaceId },
|
|
20
|
+
* resolved: false, // optional, defaults to false
|
|
21
|
+
* });
|
|
22
|
+
* ```
|
|
23
|
+
*
|
|
24
|
+
* @param params – {@link CreateCommentParams}
|
|
25
|
+
* @returns – {@link CreateResult}
|
|
26
|
+
*/
|
|
27
|
+
export declare const createComment: ({ id: providedId, content, replyTo, resolved, network, }: CreateCommentParams) => Promise<CreateResult>;
|
|
28
|
+
//# sourceMappingURL=create-comment.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-comment.d.ts","sourceRoot":"","sources":["../../../src/graph/create-comment.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,mBAAmB,EAAE,YAAY,EAAW,MAAM,aAAa,CAAC;AAwE9E;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AACH,eAAO,MAAM,aAAa,GAAU,0DAMjC,mBAAmB,KAAG,OAAO,CAAC,YAAY,CAsE5C,CAAC"}
|
|
@@ -0,0 +1,142 @@
|
|
|
1
|
+
import { Micro } from 'effect';
|
|
2
|
+
import { COMMENT_TYPE } from '../core/ids/content.js';
|
|
3
|
+
import { MARKDOWN_CONTENT, REPLY_TO_PROPERTY, RESOLVED_PROPERTY } from '../core/ids/system.js';
|
|
4
|
+
import { generateBetween } from '../core/position.js';
|
|
5
|
+
import { Id } from '../id.js';
|
|
6
|
+
import { assertValid, generate } from '../id-utils.js';
|
|
7
|
+
import { deriveCommentName } from './comment-utils.js';
|
|
8
|
+
import { getApiOrigin } from './constants.js';
|
|
9
|
+
import { createEntity } from './create-entity.js';
|
|
10
|
+
class CreateCommentError extends Error {
|
|
11
|
+
_tag = 'CreateCommentError';
|
|
12
|
+
}
|
|
13
|
+
async function fetchReplyToRelations(entityId, network) {
|
|
14
|
+
const query = `query entity {
|
|
15
|
+
entity(id: "${entityId}") {
|
|
16
|
+
relationsList(filter: { typeId: { in: ["${REPLY_TO_PROPERTY}"] } }) {
|
|
17
|
+
toEntity { id }
|
|
18
|
+
toSpace { id }
|
|
19
|
+
position
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}`;
|
|
23
|
+
const fetchData = Micro.gen(function* () {
|
|
24
|
+
const result = yield* Micro.tryPromise({
|
|
25
|
+
try: () => fetch(`${getApiOrigin(network)}/graphql`, {
|
|
26
|
+
method: 'POST',
|
|
27
|
+
headers: { 'Content-Type': 'application/json' },
|
|
28
|
+
body: JSON.stringify({ query }),
|
|
29
|
+
}),
|
|
30
|
+
catch: error => new CreateCommentError(`Could not fetch entity data for ${entityId}: ${error}`),
|
|
31
|
+
});
|
|
32
|
+
const json = yield* Micro.tryPromise({
|
|
33
|
+
try: () => result.json(),
|
|
34
|
+
catch: error => new CreateCommentError(`Could not parse GraphQL response for entity ${entityId}: ${error}`),
|
|
35
|
+
});
|
|
36
|
+
return json;
|
|
37
|
+
});
|
|
38
|
+
const response = await Micro.runPromise(fetchData);
|
|
39
|
+
if (!response.data?.entity) {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
return response.data.entity.relationsList
|
|
43
|
+
.filter((r) => r.toSpace !== null)
|
|
44
|
+
.map(r => ({
|
|
45
|
+
entityId: r.toEntity.id,
|
|
46
|
+
spaceId: r.toSpace.id,
|
|
47
|
+
position: r.position,
|
|
48
|
+
}));
|
|
49
|
+
}
|
|
50
|
+
/**
|
|
51
|
+
* Creates a comment entity. Content can be plain text or markdown.
|
|
52
|
+
*
|
|
53
|
+
* When replying to a root entity (no existing reply-to relations), creates 1 reply-to relation.
|
|
54
|
+
* When replying to a comment that has already been published on the Knowledge Graph, carries
|
|
55
|
+
* forward all of the parent's reply-to relations and adds the parent itself, accumulating the
|
|
56
|
+
* full ancestor chain at any depth. The parent comment must be published before creating a
|
|
57
|
+
* reply so that its reply-to relations can be fetched. Reply-to relations are ordered by
|
|
58
|
+
* position: the direct parent comment has the lowest position and the root entity has the
|
|
59
|
+
* highest.
|
|
60
|
+
*
|
|
61
|
+
* @example
|
|
62
|
+
* ```ts
|
|
63
|
+
* import { Graph } from '@geoprotocol/geo-sdk';
|
|
64
|
+
*
|
|
65
|
+
* const { id, ops } = await Graph.createComment({
|
|
66
|
+
* content: 'I agree with this.',
|
|
67
|
+
* replyTo: { entityId: someId, spaceId: spaceId },
|
|
68
|
+
* resolved: false, // optional, defaults to false
|
|
69
|
+
* });
|
|
70
|
+
* ```
|
|
71
|
+
*
|
|
72
|
+
* @param params – {@link CreateCommentParams}
|
|
73
|
+
* @returns – {@link CreateResult}
|
|
74
|
+
*/
|
|
75
|
+
export const createComment = async ({ id: providedId, content, replyTo, resolved = false, network = 'TESTNET', }) => {
|
|
76
|
+
if (providedId)
|
|
77
|
+
assertValid(providedId, '`id` in `createComment`');
|
|
78
|
+
assertValid(replyTo.entityId, '`replyTo.entityId` in `createComment`');
|
|
79
|
+
assertValid(replyTo.spaceId, '`replyTo.spaceId` in `createComment`');
|
|
80
|
+
const id = providedId ?? generate();
|
|
81
|
+
const name = deriveCommentName(content);
|
|
82
|
+
// Fetch existing reply-to relations from the target entity.
|
|
83
|
+
// If the target has no reply-to relations, it is a root entity — use it directly.
|
|
84
|
+
// If the target has reply-to relations, it is a comment — carry forward all
|
|
85
|
+
// of the parent's reply-tos and add the parent itself. This accumulates the
|
|
86
|
+
// full ancestor chain at any depth.
|
|
87
|
+
// Order: direct parent first (lowest position), root entity last (highest position).
|
|
88
|
+
const existingReplyTos = await fetchReplyToRelations(replyTo.entityId, network);
|
|
89
|
+
const orderedTargets = [];
|
|
90
|
+
if (existingReplyTos.length > 0) {
|
|
91
|
+
// Direct parent first
|
|
92
|
+
orderedTargets.push({ toEntity: replyTo.entityId, toSpace: replyTo.spaceId });
|
|
93
|
+
// Then the parent's reply-tos sorted by position ascending
|
|
94
|
+
// (parent's direct parent first, root entity last)
|
|
95
|
+
const sorted = [...existingReplyTos].sort((a, b) => {
|
|
96
|
+
if (a.position === null && b.position === null)
|
|
97
|
+
return 0;
|
|
98
|
+
if (a.position === null)
|
|
99
|
+
return 1;
|
|
100
|
+
if (b.position === null)
|
|
101
|
+
return -1;
|
|
102
|
+
return a.position.localeCompare(b.position);
|
|
103
|
+
});
|
|
104
|
+
for (const rt of sorted) {
|
|
105
|
+
orderedTargets.push({ toEntity: rt.entityId, toSpace: rt.spaceId });
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
else {
|
|
109
|
+
orderedTargets.push({ toEntity: replyTo.entityId, toSpace: replyTo.spaceId });
|
|
110
|
+
}
|
|
111
|
+
// Assign ascending positions: first target gets lowest, last gets highest
|
|
112
|
+
let lastPosition = null;
|
|
113
|
+
const replyToRelationEntries = [];
|
|
114
|
+
for (const target of orderedTargets) {
|
|
115
|
+
const position = generateBetween(lastPosition, null);
|
|
116
|
+
replyToRelationEntries.push({ ...target, position });
|
|
117
|
+
lastPosition = position;
|
|
118
|
+
}
|
|
119
|
+
const replyToRelations = {
|
|
120
|
+
[REPLY_TO_PROPERTY]: replyToRelationEntries,
|
|
121
|
+
};
|
|
122
|
+
const { ops } = createEntity({
|
|
123
|
+
id,
|
|
124
|
+
name,
|
|
125
|
+
types: [COMMENT_TYPE],
|
|
126
|
+
values: [
|
|
127
|
+
{
|
|
128
|
+
property: MARKDOWN_CONTENT,
|
|
129
|
+
type: 'text',
|
|
130
|
+
value: content,
|
|
131
|
+
},
|
|
132
|
+
{
|
|
133
|
+
property: RESOLVED_PROPERTY,
|
|
134
|
+
type: 'boolean',
|
|
135
|
+
value: resolved,
|
|
136
|
+
},
|
|
137
|
+
],
|
|
138
|
+
relations: replyToRelations,
|
|
139
|
+
});
|
|
140
|
+
return { id: Id(id), ops };
|
|
141
|
+
};
|
|
142
|
+
//# sourceMappingURL=create-comment.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-comment.js","sourceRoot":"","sources":["../../../src/graph/create-comment.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-comment.test.d.ts","sourceRoot":"","sources":["../../../src/graph/create-comment.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,262 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, it, vi } from 'vitest';
|
|
2
|
+
import { COMMENT_TYPE } from '../core/ids/content.js';
|
|
3
|
+
import { MARKDOWN_CONTENT, NAME_PROPERTY, REPLY_TO_PROPERTY, RESOLVED_PROPERTY, TYPES_PROPERTY, } from '../core/ids/system.js';
|
|
4
|
+
import { Id } from '../id.js';
|
|
5
|
+
import { toGrcId } from '../id-utils.js';
|
|
6
|
+
import { TESTNET_API_ORIGIN } from './constants.js';
|
|
7
|
+
import { createComment } from './create-comment.js';
|
|
8
|
+
const entityId = Id('3af3e22d21694a078681516710b7ecf1');
|
|
9
|
+
const spaceId = Id('d4bc2f205e2d415e971eb0b9fbf6b6fc');
|
|
10
|
+
const graphqlUrl = `${TESTNET_API_ORIGIN}/graphql`;
|
|
11
|
+
function mockGraphQLResponse(relationsList = []) {
|
|
12
|
+
vi.spyOn(global, 'fetch').mockImplementation(url => {
|
|
13
|
+
if (url.toString() === graphqlUrl) {
|
|
14
|
+
return Promise.resolve({
|
|
15
|
+
status: 200,
|
|
16
|
+
json: () => Promise.resolve({
|
|
17
|
+
data: {
|
|
18
|
+
entity: { relationsList },
|
|
19
|
+
},
|
|
20
|
+
}),
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
return vi.fn();
|
|
24
|
+
});
|
|
25
|
+
}
|
|
26
|
+
function mockRelation(toEntityId, toSpaceId, position = null) {
|
|
27
|
+
return {
|
|
28
|
+
toEntity: { id: toEntityId },
|
|
29
|
+
toSpace: { id: toSpaceId },
|
|
30
|
+
position,
|
|
31
|
+
};
|
|
32
|
+
}
|
|
33
|
+
describe('createComment', () => {
|
|
34
|
+
beforeEach(() => {
|
|
35
|
+
vi.restoreAllMocks();
|
|
36
|
+
});
|
|
37
|
+
it('creates a basic comment on an entity', async () => {
|
|
38
|
+
mockGraphQLResponse();
|
|
39
|
+
const { id, ops } = await createComment({
|
|
40
|
+
content: 'Hello world',
|
|
41
|
+
replyTo: { entityId, spaceId },
|
|
42
|
+
});
|
|
43
|
+
expect(id).toBeDefined();
|
|
44
|
+
expect(typeof id).toBe('string');
|
|
45
|
+
expect(ops.length).toBeGreaterThanOrEqual(3);
|
|
46
|
+
// createEntity op
|
|
47
|
+
const entityOp = ops[0];
|
|
48
|
+
expect(entityOp.type).toBe('createEntity');
|
|
49
|
+
expect(entityOp.id).toEqual(toGrcId(id));
|
|
50
|
+
// Verify name value
|
|
51
|
+
const nameValue = entityOp.values.find(v => {
|
|
52
|
+
const propBytes = v.property;
|
|
53
|
+
return propBytes.every((b, i) => b === toGrcId(NAME_PROPERTY)[i]);
|
|
54
|
+
});
|
|
55
|
+
expect(nameValue).toBeDefined();
|
|
56
|
+
expect(nameValue?.value.type).toBe('text');
|
|
57
|
+
if (nameValue?.value.type === 'text') {
|
|
58
|
+
expect(nameValue.value.value).toBe('Hello world');
|
|
59
|
+
}
|
|
60
|
+
// Verify markdown content value
|
|
61
|
+
const markdownValue = entityOp.values.find(v => {
|
|
62
|
+
const propBytes = v.property;
|
|
63
|
+
return propBytes.every((b, i) => b === toGrcId(MARKDOWN_CONTENT)[i]);
|
|
64
|
+
});
|
|
65
|
+
expect(markdownValue).toBeDefined();
|
|
66
|
+
expect(markdownValue?.value.type).toBe('text');
|
|
67
|
+
if (markdownValue?.value.type === 'text') {
|
|
68
|
+
expect(markdownValue.value.value).toBe('Hello world');
|
|
69
|
+
}
|
|
70
|
+
// Type relation to COMMENT_TYPE
|
|
71
|
+
const typeRel = ops.find(op => op.type === 'createRelation' &&
|
|
72
|
+
op.relationType.every((b, i) => b === toGrcId(TYPES_PROPERTY)[i]));
|
|
73
|
+
expect(typeRel).toBeDefined();
|
|
74
|
+
expect(typeRel.from).toEqual(toGrcId(id));
|
|
75
|
+
expect(typeRel.to).toEqual(toGrcId(COMMENT_TYPE));
|
|
76
|
+
// Reply-to relation (only 1 — the root entity)
|
|
77
|
+
const replyRels = ops.filter(op => op.type === 'createRelation' &&
|
|
78
|
+
op.relationType.every((b, i) => b === toGrcId(REPLY_TO_PROPERTY)[i]));
|
|
79
|
+
expect(replyRels).toHaveLength(1);
|
|
80
|
+
expect(replyRels[0]?.to).toEqual(toGrcId(entityId));
|
|
81
|
+
expect(replyRels[0]?.toSpace).toEqual(toGrcId(spaceId));
|
|
82
|
+
});
|
|
83
|
+
it('orders reply-tos: direct parent first, root entity last', async () => {
|
|
84
|
+
const rootEntityId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
|
85
|
+
const rootSpaceId = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
|
|
86
|
+
// Target is a comment with 1 reply-to (the root entity)
|
|
87
|
+
mockGraphQLResponse([mockRelation(rootEntityId, rootSpaceId, 'a0')]);
|
|
88
|
+
const { ops } = await createComment({
|
|
89
|
+
content: 'Reply',
|
|
90
|
+
replyTo: { entityId, spaceId },
|
|
91
|
+
});
|
|
92
|
+
const replyRels = ops.filter(op => op.type === 'createRelation' &&
|
|
93
|
+
op.relationType.every((b, i) => b === toGrcId(REPLY_TO_PROPERTY)[i]));
|
|
94
|
+
expect(replyRels).toHaveLength(2);
|
|
95
|
+
const parentReply = replyRels.find(r => r.to.every((b, i) => b === toGrcId(entityId)[i]));
|
|
96
|
+
const rootReply = replyRels.find(r => r.to.every((b, i) => b === toGrcId(rootEntityId)[i]));
|
|
97
|
+
expect(parentReply).toBeDefined();
|
|
98
|
+
expect(rootReply).toBeDefined();
|
|
99
|
+
expect(parentReply?.toSpace).toEqual(toGrcId(spaceId));
|
|
100
|
+
expect(rootReply?.toSpace).toEqual(toGrcId(rootSpaceId));
|
|
101
|
+
expect(parentReply?.position).toBeDefined();
|
|
102
|
+
expect(rootReply?.position).toBeDefined();
|
|
103
|
+
// Direct parent should have lower position than root entity
|
|
104
|
+
expect(parentReply.position.localeCompare(rootReply.position)).toBeLessThan(0);
|
|
105
|
+
// Emission order must also be parent → root
|
|
106
|
+
expect(replyRels[0]?.to).toEqual(toGrcId(entityId));
|
|
107
|
+
expect(replyRels[1]?.to).toEqual(toGrcId(rootEntityId));
|
|
108
|
+
});
|
|
109
|
+
it('orders reply-tos correctly at depth 3', async () => {
|
|
110
|
+
const rootEntityId = 'aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa';
|
|
111
|
+
const rootSpaceId = 'bbbbbbbbbbbbbbbbbbbbbbbbbbbbbbbb';
|
|
112
|
+
const commentAId = 'cccccccccccccccccccccccccccccccc';
|
|
113
|
+
const commentASpaceId = 'dddddddddddddddddddddddddddddddd';
|
|
114
|
+
// Target is Comment B with 2 reply-tos ordered: [CommentA (a0), RootEntity (a1)]
|
|
115
|
+
mockGraphQLResponse([
|
|
116
|
+
mockRelation(commentAId, commentASpaceId, 'a0'),
|
|
117
|
+
mockRelation(rootEntityId, rootSpaceId, 'a1'),
|
|
118
|
+
]);
|
|
119
|
+
const { ops } = await createComment({
|
|
120
|
+
content: 'Deep reply',
|
|
121
|
+
replyTo: { entityId, spaceId },
|
|
122
|
+
});
|
|
123
|
+
const replyRels = ops.filter(op => op.type === 'createRelation' &&
|
|
124
|
+
op.relationType.every((b, i) => b === toGrcId(REPLY_TO_PROPERTY)[i]));
|
|
125
|
+
expect(replyRels).toHaveLength(3);
|
|
126
|
+
const parentReply = replyRels.find(r => r.to.every((b, i) => b === toGrcId(entityId)[i]));
|
|
127
|
+
const commentAReply = replyRels.find(r => r.to.every((b, i) => b === toGrcId(commentAId)[i]));
|
|
128
|
+
const rootReply = replyRels.find(r => r.to.every((b, i) => b === toGrcId(rootEntityId)[i]));
|
|
129
|
+
expect(parentReply).toBeDefined();
|
|
130
|
+
expect(commentAReply).toBeDefined();
|
|
131
|
+
expect(rootReply).toBeDefined();
|
|
132
|
+
expect(parentReply?.toSpace).toEqual(toGrcId(spaceId));
|
|
133
|
+
expect(commentAReply?.toSpace).toEqual(toGrcId(commentASpaceId));
|
|
134
|
+
expect(rootReply?.toSpace).toEqual(toGrcId(rootSpaceId));
|
|
135
|
+
expect(parentReply?.position).toBeDefined();
|
|
136
|
+
expect(commentAReply?.position).toBeDefined();
|
|
137
|
+
expect(rootReply?.position).toBeDefined();
|
|
138
|
+
// Order: direct parent < commentA < root entity
|
|
139
|
+
expect(parentReply.position.localeCompare(commentAReply.position)).toBeLessThan(0);
|
|
140
|
+
expect(commentAReply.position.localeCompare(rootReply.position)).toBeLessThan(0);
|
|
141
|
+
// Emission order must also be parent → commentA → root
|
|
142
|
+
expect(replyRels[0]?.to).toEqual(toGrcId(entityId));
|
|
143
|
+
expect(replyRels[1]?.to).toEqual(toGrcId(commentAId));
|
|
144
|
+
expect(replyRels[2]?.to).toEqual(toGrcId(rootEntityId));
|
|
145
|
+
});
|
|
146
|
+
it('sets resolved to false by default', async () => {
|
|
147
|
+
mockGraphQLResponse();
|
|
148
|
+
const { ops } = await createComment({
|
|
149
|
+
content: 'Test',
|
|
150
|
+
replyTo: { entityId, spaceId },
|
|
151
|
+
});
|
|
152
|
+
const entityOp = ops[0];
|
|
153
|
+
const resolvedValue = entityOp.values.find(v => {
|
|
154
|
+
const propBytes = v.property;
|
|
155
|
+
return propBytes.every((b, i) => b === toGrcId(RESOLVED_PROPERTY)[i]);
|
|
156
|
+
});
|
|
157
|
+
expect(resolvedValue).toBeDefined();
|
|
158
|
+
expect(resolvedValue?.value.type).toBe('boolean');
|
|
159
|
+
if (resolvedValue?.value.type === 'boolean') {
|
|
160
|
+
expect(resolvedValue.value.value).toBe(false);
|
|
161
|
+
}
|
|
162
|
+
});
|
|
163
|
+
it('sets resolved to true when specified', async () => {
|
|
164
|
+
mockGraphQLResponse();
|
|
165
|
+
const { ops } = await createComment({
|
|
166
|
+
content: 'Test',
|
|
167
|
+
replyTo: { entityId, spaceId },
|
|
168
|
+
resolved: true,
|
|
169
|
+
});
|
|
170
|
+
const entityOp = ops[0];
|
|
171
|
+
const resolvedValue = entityOp.values.find(v => {
|
|
172
|
+
const propBytes = v.property;
|
|
173
|
+
return propBytes.every((b, i) => b === toGrcId(RESOLVED_PROPERTY)[i]);
|
|
174
|
+
});
|
|
175
|
+
expect(resolvedValue).toBeDefined();
|
|
176
|
+
expect(resolvedValue?.value.type).toBe('boolean');
|
|
177
|
+
if (resolvedValue?.value.type === 'boolean') {
|
|
178
|
+
expect(resolvedValue.value.value).toBe(true);
|
|
179
|
+
}
|
|
180
|
+
});
|
|
181
|
+
it('strips markdown from name and truncates to 20 chars', async () => {
|
|
182
|
+
mockGraphQLResponse();
|
|
183
|
+
const { ops } = await createComment({
|
|
184
|
+
content: '## Lorem ipsum dolor sit amet, consectetur adipiscing',
|
|
185
|
+
replyTo: { entityId, spaceId },
|
|
186
|
+
});
|
|
187
|
+
const entityOp = ops[0];
|
|
188
|
+
const nameValue = entityOp.values.find(v => {
|
|
189
|
+
const propBytes = v.property;
|
|
190
|
+
return propBytes.every((b, i) => b === toGrcId(NAME_PROPERTY)[i]);
|
|
191
|
+
});
|
|
192
|
+
expect(nameValue).toBeDefined();
|
|
193
|
+
expect(nameValue?.value.type).toBe('text');
|
|
194
|
+
if (nameValue?.value.type === 'text') {
|
|
195
|
+
expect(nameValue.value.value).toBe('Lorem ipsum dolor si');
|
|
196
|
+
}
|
|
197
|
+
});
|
|
198
|
+
it('strips heading markdown from name', async () => {
|
|
199
|
+
mockGraphQLResponse();
|
|
200
|
+
const { ops } = await createComment({
|
|
201
|
+
content: '## Hello World',
|
|
202
|
+
replyTo: { entityId, spaceId },
|
|
203
|
+
});
|
|
204
|
+
const entityOp = ops[0];
|
|
205
|
+
const nameValue = entityOp.values.find(v => {
|
|
206
|
+
const propBytes = v.property;
|
|
207
|
+
return propBytes.every((b, i) => b === toGrcId(NAME_PROPERTY)[i]);
|
|
208
|
+
});
|
|
209
|
+
expect(nameValue).toBeDefined();
|
|
210
|
+
if (nameValue?.value.type === 'text') {
|
|
211
|
+
expect(nameValue.value.value).toBe('Hello World');
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
it('handles entity not found in API', async () => {
|
|
215
|
+
vi.spyOn(global, 'fetch').mockImplementation(url => {
|
|
216
|
+
if (url.toString() === graphqlUrl) {
|
|
217
|
+
return Promise.resolve({
|
|
218
|
+
status: 200,
|
|
219
|
+
json: () => Promise.resolve({ data: { entity: null } }),
|
|
220
|
+
});
|
|
221
|
+
}
|
|
222
|
+
return vi.fn();
|
|
223
|
+
});
|
|
224
|
+
const { ops } = await createComment({
|
|
225
|
+
content: 'Comment on missing entity',
|
|
226
|
+
replyTo: { entityId, spaceId },
|
|
227
|
+
});
|
|
228
|
+
const replyRels = ops.filter(op => op.type === 'createRelation' &&
|
|
229
|
+
op.relationType.every((b, i) => b === toGrcId(REPLY_TO_PROPERTY)[i]));
|
|
230
|
+
expect(replyRels).toHaveLength(1);
|
|
231
|
+
});
|
|
232
|
+
it('uses provided id when given', async () => {
|
|
233
|
+
mockGraphQLResponse();
|
|
234
|
+
const customId = Id('aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa');
|
|
235
|
+
const { id } = await createComment({
|
|
236
|
+
id: customId,
|
|
237
|
+
content: 'Test',
|
|
238
|
+
replyTo: { entityId, spaceId },
|
|
239
|
+
});
|
|
240
|
+
expect(id).toBe(customId);
|
|
241
|
+
});
|
|
242
|
+
it('throws for invalid replyTo entityId', async () => {
|
|
243
|
+
await expect(createComment({
|
|
244
|
+
content: 'Test',
|
|
245
|
+
replyTo: { entityId: 'invalid', spaceId },
|
|
246
|
+
})).rejects.toThrow('Invalid id: "invalid" for `replyTo.entityId` in `createComment`');
|
|
247
|
+
});
|
|
248
|
+
it('throws for invalid replyTo spaceId', async () => {
|
|
249
|
+
await expect(createComment({
|
|
250
|
+
content: 'Test',
|
|
251
|
+
replyTo: { entityId, spaceId: 'invalid' },
|
|
252
|
+
})).rejects.toThrow('Invalid id: "invalid" for `replyTo.spaceId` in `createComment`');
|
|
253
|
+
});
|
|
254
|
+
it('throws for invalid provided id', async () => {
|
|
255
|
+
await expect(createComment({
|
|
256
|
+
id: 'invalid',
|
|
257
|
+
content: 'Test',
|
|
258
|
+
replyTo: { entityId, spaceId },
|
|
259
|
+
})).rejects.toThrow('Invalid id: "invalid" for `id` in `createComment`');
|
|
260
|
+
});
|
|
261
|
+
});
|
|
262
|
+
//# sourceMappingURL=create-comment.test.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-comment.test.js","sourceRoot":"","sources":["../../../src/graph/create-comment.test.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,UAAU,EAAE,QAAQ,EAAE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,MAAM,QAAQ,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AACtD,OAAO,EACL,gBAAgB,EAChB,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,GACf,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,OAAO,EAAE,MAAM,gBAAgB,CAAC;AACzC,OAAO,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACpD,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAEpD,MAAM,QAAQ,GAAG,EAAE,CAAC,kCAAkC,CAAC,CAAC;AACxD,MAAM,OAAO,GAAG,EAAE,CAAC,kCAAkC,CAAC,CAAC;AACvD,MAAM,UAAU,GAAG,GAAG,kBAAkB,UAAU,CAAC;AAEnD,SAAS,mBAAmB,CAAC,gBAAgD,EAAE;IAC7E,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE;QACjD,IAAI,GAAG,CAAC,QAAQ,EAAE,KAAK,UAAU,EAAE,CAAC;YAClC,OAAO,OAAO,CAAC,OAAO,CAAC;gBACrB,MAAM,EAAE,GAAG;gBACX,IAAI,EAAE,GAAG,EAAE,CACT,OAAO,CAAC,OAAO,CAAC;oBACd,IAAI,EAAE;wBACJ,MAAM,EAAE,EAAE,aAAa,EAAE;qBAC1B;iBACF,CAAC;aACO,CAAC,CAAC;QACjB,CAAC;QACD,OAAO,EAAE,CAAC,EAAE,EAAW,CAAC;IAC1B,CAAC,CAAC,CAAC;AACL,CAAC;AAED,SAAS,YAAY,CAAC,UAAkB,EAAE,SAAiB,EAAE,WAA0B,IAAI;IACzF,OAAO;QACL,QAAQ,EAAE,EAAE,EAAE,EAAE,UAAU,EAAE;QAC5B,OAAO,EAAE,EAAE,EAAE,EAAE,SAAS,EAAE;QAC1B,QAAQ;KACT,CAAC;AACJ,CAAC;AAED,QAAQ,CAAC,eAAe,EAAE,GAAG,EAAE;IAC7B,UAAU,CAAC,GAAG,EAAE;QACd,EAAE,CAAC,eAAe,EAAE,CAAC;IACvB,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,mBAAmB,EAAE,CAAC;QAEtB,MAAM,EAAE,EAAE,EAAE,GAAG,EAAE,GAAG,MAAM,aAAa,CAAC;YACtC,OAAO,EAAE,aAAa;YACtB,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAC/B,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,CAAC,WAAW,EAAE,CAAC;QACzB,MAAM,CAAC,OAAO,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;QACjC,MAAM,CAAC,GAAG,CAAC,MAAM,CAAC,CAAC,sBAAsB,CAAC,CAAC,CAAC,CAAC;QAE7C,kBAAkB;QAClB,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAiB,CAAC;QACxC,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC;QAC3C,MAAM,CAAC,QAAQ,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAEzC,oBAAoB;QACpB,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YACzC,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC;YAC7B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,SAAS,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACrC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACpD,CAAC;QAED,gCAAgC;QAChC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YAC7C,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC;YAC7B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACvE,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,aAAa,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACzC,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACxD,CAAC;QAED,gCAAgC;QAChC,MAAM,OAAO,GAAG,GAAG,CAAC,IAAI,CACtB,EAAE,CAAC,EAAE,CACH,EAAE,CAAC,IAAI,KAAK,gBAAgB;YAC3B,EAAqB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,cAAc,CAAC,CAAC,CAAC,CAAC,CAAC,CACtE,CAAC;QACpB,MAAM,CAAC,OAAO,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9B,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,CAAC;QAC1C,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;QAElD,+CAA+C;QAC/C,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAC1B,EAAE,CAAC,EAAE,CACH,EAAE,CAAC,IAAI,KAAK,gBAAgB;YAC3B,EAAqB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CACvE,CAAC;QACtB,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAClC,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,yDAAyD,EAAE,KAAK,IAAI,EAAE;QACvE,MAAM,YAAY,GAAG,kCAAkC,CAAC;QACxD,MAAM,WAAW,GAAG,kCAAkC,CAAC;QAEvD,wDAAwD;QACxD,mBAAmB,CAAC,CAAC,YAAY,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC;QAErE,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,aAAa,CAAC;YAClC,OAAO,EAAE,OAAO;YAChB,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAC/B,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAC1B,EAAE,CAAC,EAAE,CACH,EAAE,CAAC,IAAI,KAAK,gBAAgB;YAC3B,EAAqB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CACvE,CAAC;QACtB,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAElC,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAE1C,4DAA4D;QAC5D,MAAM,CAAC,WAAY,CAAC,QAAS,CAAC,aAAa,CAAC,SAAU,CAAC,QAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAEnF,4CAA4C;QAC5C,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,uCAAuC,EAAE,KAAK,IAAI,EAAE;QACrD,MAAM,YAAY,GAAG,kCAAkC,CAAC;QACxD,MAAM,WAAW,GAAG,kCAAkC,CAAC;QACvD,MAAM,UAAU,GAAG,kCAAkC,CAAC;QACtD,MAAM,eAAe,GAAG,kCAAkC,CAAC;QAE3D,iFAAiF;QACjF,mBAAmB,CAAC;YAClB,YAAY,CAAC,UAAU,EAAE,eAAe,EAAE,IAAI,CAAC;YAC/C,YAAY,CAAC,YAAY,EAAE,WAAW,EAAE,IAAI,CAAC;SAC9C,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,aAAa,CAAC;YAClC,OAAO,EAAE,YAAY;YACrB,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAC/B,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAC1B,EAAE,CAAC,EAAE,CACH,EAAE,CAAC,IAAI,KAAK,gBAAgB;YAC3B,EAAqB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CACvE,CAAC;QACtB,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAElC,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC1F,MAAM,aAAa,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC9F,MAAM,SAAS,GAAG,SAAS,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QAC5F,MAAM,CAAC,WAAW,CAAC,CAAC,WAAW,EAAE,CAAC;QAClC,MAAM,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,CAAC,WAAW,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC;QACvD,MAAM,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC,CAAC;QACjE,MAAM,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC;QACzD,MAAM,CAAC,WAAW,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC5C,MAAM,CAAC,aAAa,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAC9C,MAAM,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC;QAE1C,gDAAgD;QAChD,MAAM,CAAC,WAAY,CAAC,QAAS,CAAC,aAAa,CAAC,aAAc,CAAC,QAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QACvF,MAAM,CAAC,aAAc,CAAC,QAAS,CAAC,aAAa,CAAC,SAAU,CAAC,QAAS,CAAC,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;QAErF,uDAAuD;QACvD,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC;QACpD,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,UAAU,CAAC,CAAC,CAAC;QACtD,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,OAAO,CAAC,YAAY,CAAC,CAAC,CAAC;IAC1D,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,mBAAmB,EAAE,CAAC;QAEtB,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,aAAa,CAAC;YAClC,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAC/B,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAiB,CAAC;QACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YAC7C,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC;YAC7B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,aAAa,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5C,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAChD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,sCAAsC,EAAE,KAAK,IAAI,EAAE;QACpD,mBAAmB,EAAE,CAAC;QAEtB,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,aAAa,CAAC;YAClC,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;YAC9B,QAAQ,EAAE,IAAI;SACf,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAiB,CAAC;QACxC,MAAM,aAAa,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YAC7C,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC;YAC7B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACxE,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,aAAa,CAAC,CAAC,WAAW,EAAE,CAAC;QACpC,MAAM,CAAC,aAAa,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC;QAClD,IAAI,aAAa,EAAE,KAAK,CAAC,IAAI,KAAK,SAAS,EAAE,CAAC;YAC5C,MAAM,CAAC,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qDAAqD,EAAE,KAAK,IAAI,EAAE;QACnE,mBAAmB,EAAE,CAAC;QAEtB,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,aAAa,CAAC;YAClC,OAAO,EAAE,uDAAuD;YAChE,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAC/B,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAiB,CAAC;QACxC,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YACzC,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC;YAC7B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,MAAM,CAAC,SAAS,EAAE,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC;QAC3C,IAAI,SAAS,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACrC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,sBAAsB,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,mCAAmC,EAAE,KAAK,IAAI,EAAE;QACjD,mBAAmB,EAAE,CAAC;QAEtB,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,aAAa,CAAC;YAClC,OAAO,EAAE,gBAAgB;YACzB,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAC/B,CAAC,CAAC;QAEH,MAAM,QAAQ,GAAG,GAAG,CAAC,CAAC,CAAiB,CAAC;QACxC,MAAM,SAAS,GAAG,QAAQ,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE;YACzC,MAAM,SAAS,GAAG,CAAC,CAAC,QAAQ,CAAC;YAC7B,OAAO,SAAS,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;QACpE,CAAC,CAAC,CAAC;QACH,MAAM,CAAC,SAAS,CAAC,CAAC,WAAW,EAAE,CAAC;QAChC,IAAI,SAAS,EAAE,KAAK,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACrC,MAAM,CAAC,SAAS,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC;QACpD,CAAC;IACH,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,iCAAiC,EAAE,KAAK,IAAI,EAAE;QAC/C,EAAE,CAAC,KAAK,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,kBAAkB,CAAC,GAAG,CAAC,EAAE;YACjD,IAAI,GAAG,CAAC,QAAQ,EAAE,KAAK,UAAU,EAAE,CAAC;gBAClC,OAAO,OAAO,CAAC,OAAO,CAAC;oBACrB,MAAM,EAAE,GAAG;oBACX,IAAI,EAAE,GAAG,EAAE,CAAC,OAAO,CAAC,OAAO,CAAC,EAAE,IAAI,EAAE,EAAE,MAAM,EAAE,IAAI,EAAE,EAAE,CAAC;iBAC5C,CAAC,CAAC;YACjB,CAAC;YACD,OAAO,EAAE,CAAC,EAAE,EAAW,CAAC;QAC1B,CAAC,CAAC,CAAC;QAEH,MAAM,EAAE,GAAG,EAAE,GAAG,MAAM,aAAa,CAAC;YAClC,OAAO,EAAE,2BAA2B;YACpC,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAC/B,CAAC,CAAC;QAEH,MAAM,SAAS,GAAG,GAAG,CAAC,MAAM,CAC1B,EAAE,CAAC,EAAE,CACH,EAAE,CAAC,IAAI,KAAK,gBAAgB;YAC3B,EAAqB,CAAC,YAAY,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,KAAK,OAAO,CAAC,iBAAiB,CAAC,CAAC,CAAC,CAAC,CAAC,CACvE,CAAC;QACtB,MAAM,CAAC,SAAS,CAAC,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC;IACpC,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,6BAA6B,EAAE,KAAK,IAAI,EAAE;QAC3C,mBAAmB,EAAE,CAAC;QACtB,MAAM,QAAQ,GAAG,EAAE,CAAC,kCAAkC,CAAC,CAAC;QAExD,MAAM,EAAE,EAAE,EAAE,GAAG,MAAM,aAAa,CAAC;YACjC,EAAE,EAAE,QAAQ;YACZ,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAC/B,CAAC,CAAC;QAEH,MAAM,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC;IAC5B,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,qCAAqC,EAAE,KAAK,IAAI,EAAE;QACnD,MAAM,MAAM,CACV,aAAa,CAAC;YACZ,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,EAAE,QAAQ,EAAE,SAAS,EAAE,OAAO,EAAE;SAC1C,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,iEAAiE,CAAC,CAAC;IACvF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,oCAAoC,EAAE,KAAK,IAAI,EAAE;QAClD,MAAM,MAAM,CACV,aAAa,CAAC;YACZ,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE,SAAS,EAAE;SAC1C,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,gEAAgE,CAAC,CAAC;IACtF,CAAC,CAAC,CAAC;IAEH,EAAE,CAAC,gCAAgC,EAAE,KAAK,IAAI,EAAE;QAC9C,MAAM,MAAM,CACV,aAAa,CAAC;YACZ,EAAE,EAAE,SAAS;YACb,OAAO,EAAE,MAAM;YACf,OAAO,EAAE,EAAE,QAAQ,EAAE,OAAO,EAAE;SAC/B,CAAC,CACH,CAAC,OAAO,CAAC,OAAO,CAAC,mDAAmD,CAAC,CAAC;IACzE,CAAC,CAAC,CAAC;AACL,CAAC,CAAC,CAAC"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
import type { CreateProposalReviewParams, CreateResult } from '../types.js';
|
|
2
|
+
/**
|
|
3
|
+
* Creates a proposal review entity with a pass/fail status and optional star ratings.
|
|
4
|
+
* For low-difficulty bounties, only `pass` is required. For medium/hard bounties,
|
|
5
|
+
* `completeness`, `accuracy`, `skill`, and `effort` ratings must also be provided.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```ts
|
|
9
|
+
* import { Graph } from '@geoprotocol/geo-sdk';
|
|
10
|
+
*
|
|
11
|
+
* // Low-difficulty bounty review (pass only)
|
|
12
|
+
* const { id, ops } = Graph.createProposalReview({
|
|
13
|
+
* proposal: { id: proposalId, name: 'Proposal name' },
|
|
14
|
+
* pass: true,
|
|
15
|
+
* });
|
|
16
|
+
*
|
|
17
|
+
* // Medium/hard bounty review (with ratings)
|
|
18
|
+
* const { id, ops } = Graph.createProposalReview({
|
|
19
|
+
* proposal: { id: proposalId, name: 'Proposal name' },
|
|
20
|
+
* pass: true,
|
|
21
|
+
* completeness: 0.8,
|
|
22
|
+
* accuracy: 1,
|
|
23
|
+
* skill: 0.6,
|
|
24
|
+
* effort: 0.8,
|
|
25
|
+
* });
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @param params – {@link CreateProposalReviewParams}
|
|
29
|
+
* @returns – {@link CreateResult}
|
|
30
|
+
*/
|
|
31
|
+
export declare const createProposalReview: (params: CreateProposalReviewParams) => CreateResult;
|
|
32
|
+
//# sourceMappingURL=create-proposal-review.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-proposal-review.d.ts","sourceRoot":"","sources":["../../../src/graph/create-proposal-review.ts"],"names":[],"mappings":"AAWA,OAAO,KAAK,EAAE,0BAA0B,EAAE,YAAY,EAAmB,MAAM,aAAa,CAAC;AAG7F;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,eAAO,MAAM,oBAAoB,GAAI,QAAQ,0BAA0B,KAAG,YAoCzE,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import { ACCURACY_RATING_PROPERTY, BOUNTY_REVIEW_TYPE, COMPLETENESS_RATING_PROPERTY, EFFORT_RATING_PROPERTY, PASS_PROPERTY, PROPOSALS_PROPERTY, SKILL_RATING_PROPERTY, } from '../core/ids/system.js';
|
|
2
|
+
import { Id } from '../id.js';
|
|
3
|
+
import { assertValid, generate } from '../id-utils.js';
|
|
4
|
+
import { createEntity } from './create-entity.js';
|
|
5
|
+
/**
|
|
6
|
+
* Creates a proposal review entity with a pass/fail status and optional star ratings.
|
|
7
|
+
* For low-difficulty bounties, only `pass` is required. For medium/hard bounties,
|
|
8
|
+
* `completeness`, `accuracy`, `skill`, and `effort` ratings must also be provided.
|
|
9
|
+
*
|
|
10
|
+
* @example
|
|
11
|
+
* ```ts
|
|
12
|
+
* import { Graph } from '@geoprotocol/geo-sdk';
|
|
13
|
+
*
|
|
14
|
+
* // Low-difficulty bounty review (pass only)
|
|
15
|
+
* const { id, ops } = Graph.createProposalReview({
|
|
16
|
+
* proposal: { id: proposalId, name: 'Proposal name' },
|
|
17
|
+
* pass: true,
|
|
18
|
+
* });
|
|
19
|
+
*
|
|
20
|
+
* // Medium/hard bounty review (with ratings)
|
|
21
|
+
* const { id, ops } = Graph.createProposalReview({
|
|
22
|
+
* proposal: { id: proposalId, name: 'Proposal name' },
|
|
23
|
+
* pass: true,
|
|
24
|
+
* completeness: 0.8,
|
|
25
|
+
* accuracy: 1,
|
|
26
|
+
* skill: 0.6,
|
|
27
|
+
* effort: 0.8,
|
|
28
|
+
* });
|
|
29
|
+
* ```
|
|
30
|
+
*
|
|
31
|
+
* @param params – {@link CreateProposalReviewParams}
|
|
32
|
+
* @returns – {@link CreateResult}
|
|
33
|
+
*/
|
|
34
|
+
export const createProposalReview = (params) => {
|
|
35
|
+
if (params.id)
|
|
36
|
+
assertValid(params.id, '`id` in `createProposalReview`');
|
|
37
|
+
assertValid(params.proposal.id, '`proposal.id` in `createProposalReview`');
|
|
38
|
+
const id = params.id ?? generate();
|
|
39
|
+
const values = [
|
|
40
|
+
{
|
|
41
|
+
property: PASS_PROPERTY,
|
|
42
|
+
type: 'boolean',
|
|
43
|
+
value: params.pass,
|
|
44
|
+
},
|
|
45
|
+
];
|
|
46
|
+
if ('completeness' in params) {
|
|
47
|
+
values.push({ property: COMPLETENESS_RATING_PROPERTY, type: 'float', value: params.completeness }, { property: ACCURACY_RATING_PROPERTY, type: 'float', value: params.accuracy }, { property: SKILL_RATING_PROPERTY, type: 'float', value: params.skill }, { property: EFFORT_RATING_PROPERTY, type: 'float', value: params.effort });
|
|
48
|
+
}
|
|
49
|
+
const { ops } = createEntity({
|
|
50
|
+
id,
|
|
51
|
+
name: params.proposal.name,
|
|
52
|
+
types: [BOUNTY_REVIEW_TYPE],
|
|
53
|
+
values,
|
|
54
|
+
relations: {
|
|
55
|
+
[PROPOSALS_PROPERTY]: {
|
|
56
|
+
toEntity: params.proposal.id,
|
|
57
|
+
},
|
|
58
|
+
},
|
|
59
|
+
});
|
|
60
|
+
return { id: Id(id), ops };
|
|
61
|
+
};
|
|
62
|
+
//# sourceMappingURL=create-proposal-review.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-proposal-review.js","sourceRoot":"","sources":["../../../src/graph/create-proposal-review.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,wBAAwB,EACxB,kBAAkB,EAClB,4BAA4B,EAC5B,sBAAsB,EACtB,aAAa,EACb,kBAAkB,EAClB,qBAAqB,GACtB,MAAM,uBAAuB,CAAC;AAC/B,OAAO,EAAE,EAAE,EAAE,MAAM,UAAU,CAAC;AAC9B,OAAO,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,gBAAgB,CAAC;AAEvD,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AACH,MAAM,CAAC,MAAM,oBAAoB,GAAG,CAAC,MAAkC,EAAgB,EAAE;IACvF,IAAI,MAAM,CAAC,EAAE;QAAE,WAAW,CAAC,MAAM,CAAC,EAAE,EAAE,gCAAgC,CAAC,CAAC;IACxE,WAAW,CAAC,MAAM,CAAC,QAAQ,CAAC,EAAE,EAAE,yCAAyC,CAAC,CAAC;IAE3E,MAAM,EAAE,GAAG,MAAM,CAAC,EAAE,IAAI,QAAQ,EAAE,CAAC;IAEnC,MAAM,MAAM,GAAoB;QAC9B;YACE,QAAQ,EAAE,aAAa;YACvB,IAAI,EAAE,SAAS;YACf,KAAK,EAAE,MAAM,CAAC,IAAI;SACnB;KACF,CAAC;IAEF,IAAI,cAAc,IAAI,MAAM,EAAE,CAAC;QAC7B,MAAM,CAAC,IAAI,CACT,EAAE,QAAQ,EAAE,4BAA4B,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,YAAY,EAAE,EACrF,EAAE,QAAQ,EAAE,wBAAwB,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,QAAQ,EAAE,EAC7E,EAAE,QAAQ,EAAE,qBAAqB,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,KAAK,EAAE,EACvE,EAAE,QAAQ,EAAE,sBAAsB,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,CAAC,MAAM,EAAE,CAC1E,CAAC;IACJ,CAAC;IAED,MAAM,EAAE,GAAG,EAAE,GAAG,YAAY,CAAC;QAC3B,EAAE;QACF,IAAI,EAAE,MAAM,CAAC,QAAQ,CAAC,IAAI;QAC1B,KAAK,EAAE,CAAC,kBAAkB,CAAC;QAC3B,MAAM;QACN,SAAS,EAAE;YACT,CAAC,kBAAkB,CAAC,EAAE;gBACpB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,EAAE;aAC7B;SACF;KACF,CAAC,CAAC;IAEH,OAAO,EAAE,EAAE,EAAE,EAAE,CAAC,EAAE,CAAC,EAAE,GAAG,EAAE,CAAC;AAC7B,CAAC,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"create-proposal-review.test.d.ts","sourceRoot":"","sources":["../../../src/graph/create-proposal-review.test.ts"],"names":[],"mappings":""}
|