Skip to content

Commit dad8103

Browse files
committed
allow to provide an existing id when creating an entity, image, type or property
1 parent 5c35de1 commit dad8103

File tree

11 files changed

+83
-11
lines changed

11 files changed

+83
-11
lines changed

.changeset/shaggy-windows-camp.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@graphprotocol/grc-20": minor
3+
---
4+
5+
allow to provide an existing id when creating an entity, image, type or property

src/core/image.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,28 @@ type MakeImageParams = {
2121
width: number;
2222
height: number;
2323
};
24+
id?: Id;
2425
};
2526

2627
/**
2728
* Creates an entity representing an Image.
2829
*
2930
* @example
3031
* ```ts
31-
* const { id, ops } = Image.make({ cid: 'https://example.com/image.png', dimensions: { width: 100, height: 100 } });
32+
* const { id, ops } = Image.make({
33+
* cid: 'https://example.com/image.png',
34+
* dimensions: { width: 100, height: 100 },
35+
* id: imageId, // optional and will be generated if not provided
36+
* });
3237
* console.log(id); // 'gw9uTVTnJdhtczyuzBkL3X'
3338
* console.log(ops); // [...]
3439
* ```
3540
*
3641
* @returns id – base58 encoded v4 uuid representing the image entity: {@link MakeImageReturnType}
3742
* @returns ops – The ops for the Image entity: {@link MakeImageReturnType}
3843
*/
39-
export function make({ cid, dimensions }: MakeImageParams): MakeImageReturnType {
40-
const entityId = generate();
44+
export function make({ cid, dimensions, id }: MakeImageParams): MakeImageReturnType {
45+
const entityId = id ?? generate();
4146
const ops: Array<Op> = [
4247
Relation.make({
4348
fromId: entityId,

src/graph/create-entity.test.ts

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -310,4 +310,23 @@ describe('createEntity', () => {
310310
expect(typeof entity.id).toBe('string');
311311
expect(entity.ops).toHaveLength(9);
312312
});
313+
314+
it('creates an entity with a provided id', async () => {
315+
const entity = createEntity({
316+
id: Id('WeUPYRkhnQLmHPH4S1ioc4'),
317+
name: 'Yummy Coffee',
318+
});
319+
320+
expect(entity).toBeDefined();
321+
expect(entity.id).toBe('WeUPYRkhnQLmHPH4S1ioc4');
322+
expect(entity.ops).toHaveLength(1);
323+
expect(entity.ops[0]).toMatchObject({
324+
type: 'SET_TRIPLE',
325+
triple: {
326+
attribute: NAME_PROPERTY,
327+
entity: entity.id,
328+
value: { type: 'TEXT', value: 'Yummy Coffee' },
329+
},
330+
});
331+
});
313332
});

src/graph/create-entity.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@ type CreateEntityParams = DefaultProperties & {
2121
* description: 'description of the entity',
2222
* cover: imageEntityId,
2323
* types: [typeEntityId1, typeEntityId2],
24+
* id: entityId, // optional and will be generated if not provided
2425
* properties: {
2526
* // value property like text, number, url, time, point, checkbox
2627
* [propertyId]: {
@@ -49,8 +50,8 @@ type CreateEntityParams = DefaultProperties & {
4950
* @returns – {@link CreateResult}
5051
* @throws Will throw an error if any provided ID is invalid
5152
*/
52-
export const createEntity = ({ name, description, cover, properties, types }: CreateEntityParams): CreateResult => {
53-
const id = generate();
53+
export const createEntity = ({ id: providedId, name, description, cover, properties, types }: CreateEntityParams): CreateResult => {
54+
const id = providedId ?? generate();
5455
const ops: Array<Op> = [];
5556

5657
ops.push(...createDefaultProperties({ entityId: id, name, description, cover }));

src/graph/create-image.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { beforeEach, describe, expect, it, vi } from 'vitest';
2+
import { Id } from '../id.js';
23
import { SystemIds } from '../system-ids.js';
34
import { createImage } from './create-image.js';
45

@@ -129,6 +130,16 @@ describe('createImage', () => {
129130
}
130131
});
131132

133+
it('creates an image with a provided id', async () => {
134+
const image = await createImage({
135+
url: 'http://localhost:3000/image',
136+
id: Id('WeUPYRkhnQLmHPH4S1ioc4'),
137+
});
138+
139+
expect(image).toBeDefined();
140+
expect(image.id).toBe('WeUPYRkhnQLmHPH4S1ioc4');
141+
});
142+
132143
it('throws an error if the image cannot be uploaded to IPFS', async () => {
133144
vi.spyOn(global, 'fetch').mockImplementation(url => {
134145
if (url.toString() === 'http://localhost:3000/image') {

src/graph/create-image.ts

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import type { Id } from '../id.js';
12
import { Image } from '../image.js';
23
import { uploadImage } from '../ipfs.js';
34
import type { CreateResult, Op } from '../types.js';
@@ -7,11 +8,13 @@ type CreateImageParams =
78
blob: Blob;
89
name?: string;
910
description?: string;
11+
id?: Id;
1012
}
1113
| {
1214
url: string;
1315
name?: string;
1416
description?: string;
17+
id?: Id;
1518
};
1619

1720
/**
@@ -25,22 +28,24 @@ type CreateImageParams =
2528
* url: 'https://example.com/image.png',
2629
* name: 'name of the image', // optional
2730
* description: 'description of the image', // optional
31+
* id: imageId, // optional and will be generated if not provided
2832
* });
2933
*
3034
* const { id, ops } = createImage({
3135
* blob: new Blob(…),
3236
* name: 'name of the image', // optional
3337
* description: 'description of the image', // optional
38+
* id: imageId, // optional and will be generated if not provided
3439
* });
3540
* ```
3641
* @param params – {@link CreateImageParams}
3742
* @returns – {@link CreateResult}
3843
* @throws Will throw an IpfsUploadError if the image cannot be uploaded to IPFS
3944
*/
40-
export const createImage = async ({ name, description, ...params }: CreateImageParams): Promise<CreateResult> => {
45+
export const createImage = async ({ name, description, id: providedId, ...params }: CreateImageParams): Promise<CreateResult> => {
4146
const ops: Array<Op> = [];
4247
const { cid, dimensions } = await uploadImage(params);
43-
const { id, ops: imageOps } = Image.make({ cid, dimensions });
48+
const { id, ops: imageOps } = Image.make({ cid, dimensions, id: providedId });
4449
ops.push(...imageOps);
4550
ops.push(...createDefaultProperties({ entityId: id, name, description }));
4651

src/graph/create-property.test.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
import { describe, expect, it } from 'vitest';
22
import { JOB_TYPE, ROLES_PROPERTY } from '../core/ids/content.js';
3+
import { Id } from '../id.js';
34
import { createProperty } from './create-property.js';
45

56
describe('createProperty', () => {
@@ -73,4 +74,15 @@ describe('createProperty', () => {
7374
expect(property.ops[4]?.type).toBe('CREATE_RELATION');
7475
expect(property.ops[5]?.type).toBe('CREATE_RELATION');
7576
});
77+
78+
it('creates a property with a provided id', async () => {
79+
const property = createProperty({
80+
id: Id('WeUPYRkhnQLmHPH4S1ioc4'),
81+
name: 'Price',
82+
type: 'NUMBER',
83+
});
84+
85+
expect(property).toBeDefined();
86+
expect(property.id).toBe('WeUPYRkhnQLmHPH4S1ioc4');
87+
});
7688
});

src/graph/create-property.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -32,15 +32,16 @@ type CreatePropertyParams = DefaultProperties &
3232
* type: 'TEXT'
3333
* description: 'description of the property',
3434
* cover: imageEntityId,
35+
* id: propertyId, // optional and will be generated if not provided
3536
* });
3637
* ```
3738
* @param params – {@link CreatePropertyParams}
3839
* @returns – {@link CreateResult}
3940
* @throws Will throw an error if any provided ID is invalid
4041
*/
4142
export const createProperty = (params: CreatePropertyParams): CreateResult => {
42-
const { name, description, cover } = params;
43-
const entityId = generate();
43+
const { id, name, description, cover } = params;
44+
const entityId = id ?? generate();
4445
const ops: Op[] = [];
4546

4647
ops.push(...createDefaultProperties({ entityId, name, description, cover }));

src/graph/create-type.test.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { describe, expect, it } from 'vitest';
22
import { AUTHORS_PROPERTY, WEBSITE_PROPERTY } from '../core/ids/content.js';
33
import { NAME_PROPERTY, PROPERTY, SCHEMA_TYPE, TYPES_PROPERTY } from '../core/ids/system.js';
4+
import { Id } from '../id.js';
45
import { createType } from './create-type.js';
56

67
describe('createType', () => {
@@ -100,4 +101,14 @@ describe('createType', () => {
100101
type: 'CREATE_RELATION',
101102
});
102103
});
104+
105+
it('creates a type with a provided id', async () => {
106+
const type = createType({
107+
id: Id('WeUPYRkhnQLmHPH4S1ioc4'),
108+
name: 'Article',
109+
});
110+
111+
expect(type).toBeDefined();
112+
expect(type.id).toBe('WeUPYRkhnQLmHPH4S1ioc4');
113+
});
103114
});

src/graph/create-type.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,16 @@ type CreateTypeParams = DefaultProperties & {
1818
* name: 'name of the type',
1919
* description: 'description of the type',
2020
* cover: imageEntityId,
21+
* id: typeId, // optional and will be generated if not provided
2122
* properties: [propertyEntityId1, propertyEntityId2],
2223
* });
2324
* ```
2425
* @param params – {@link CreateTypeParams}
2526
* @returns – {@link CreateResult}
2627
* @throws Will throw an error if any provided ID is invalid
2728
*/
28-
export const createType = ({ name, description, cover, properties }: CreateTypeParams): CreateResult => {
29-
const id = generate();
29+
export const createType = ({ id: providedId, name, description, cover, properties }: CreateTypeParams): CreateResult => {
30+
const id = providedId ?? generate();
3031
const ops: Op[] = [];
3132

3233
ops.push(...createDefaultProperties({ entityId: id, name, description, cover }));

0 commit comments

Comments
 (0)