@graphprotocol/hypergraph 0.2.0 → 0.4.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.
Files changed (77) hide show
  1. package/dist/cli/Cli.d.ts +2 -0
  2. package/dist/cli/Cli.d.ts.map +1 -0
  3. package/dist/cli/Cli.js +8 -0
  4. package/dist/cli/Cli.js.map +1 -0
  5. package/dist/cli/Logger.d.ts +3 -0
  6. package/dist/cli/Logger.d.ts.map +1 -0
  7. package/dist/cli/Logger.js +20 -0
  8. package/dist/cli/Logger.js.map +1 -0
  9. package/dist/cli/bin.d.ts +3 -0
  10. package/dist/cli/bin.d.ts.map +1 -0
  11. package/dist/cli/bin.js +20 -0
  12. package/dist/cli/bin.js.map +1 -0
  13. package/dist/cli/bun.d.ts +3 -0
  14. package/dist/cli/bun.d.ts.map +1 -0
  15. package/dist/cli/bun.js +3 -0
  16. package/dist/cli/bun.js.map +1 -0
  17. package/dist/cli/services/Typesync.d.ts +21 -0
  18. package/dist/cli/services/Typesync.d.ts.map +1 -0
  19. package/dist/cli/services/Typesync.js +137 -0
  20. package/dist/cli/services/Typesync.js.map +1 -0
  21. package/dist/cli/services/Utils.d.ts +10 -0
  22. package/dist/cli/services/Utils.d.ts.map +1 -0
  23. package/dist/cli/services/Utils.js +154 -0
  24. package/dist/cli/services/Utils.js.map +1 -0
  25. package/dist/cli/subcommands/typesync.d.ts +7 -0
  26. package/dist/cli/subcommands/typesync.d.ts.map +1 -0
  27. package/dist/cli/subcommands/typesync.js +38 -0
  28. package/dist/cli/subcommands/typesync.js.map +1 -0
  29. package/dist/entity/findMany.js.map +1 -1
  30. package/dist/entity/types.d.ts +4 -4
  31. package/dist/entity/types.d.ts.map +1 -1
  32. package/dist/index.d.ts +2 -0
  33. package/dist/index.d.ts.map +1 -1
  34. package/dist/index.js +2 -0
  35. package/dist/index.js.map +1 -1
  36. package/dist/mapping/Mapping.d.ts +51 -39
  37. package/dist/mapping/Mapping.d.ts.map +1 -1
  38. package/dist/mapping/Mapping.js +49 -27
  39. package/dist/mapping/Mapping.js.map +1 -1
  40. package/dist/type/type.d.ts +3 -2
  41. package/dist/type/type.d.ts.map +1 -1
  42. package/dist/type/type.js +5 -2
  43. package/dist/type/type.js.map +1 -1
  44. package/dist/type-utils/type-utils.d.ts +7 -0
  45. package/dist/type-utils/type-utils.d.ts.map +1 -0
  46. package/dist/type-utils/type-utils.js +41 -0
  47. package/dist/type-utils/type-utils.js.map +1 -0
  48. package/package.json +7 -3
  49. package/src/cli/Cli.ts +15 -0
  50. package/src/cli/Logger.ts +20 -0
  51. package/src/cli/bin.ts +33 -0
  52. package/src/cli/bun.ts +3 -0
  53. package/src/cli/services/Typesync.ts +189 -0
  54. package/src/cli/services/Utils.ts +187 -0
  55. package/src/cli/subcommands/typesync.ts +93 -0
  56. package/src/entity/findMany.ts +4 -4
  57. package/src/entity/types.ts +4 -4
  58. package/src/index.ts +2 -0
  59. package/src/mapping/Mapping.ts +65 -43
  60. package/src/type/type.ts +6 -2
  61. package/src/type-utils/type-utils.ts +46 -0
  62. package/dist/Entity.d.ts +0 -69
  63. package/dist/Entity.d.ts.map +0 -1
  64. package/dist/Entity.js +0 -174
  65. package/dist/Entity.js.map +0 -1
  66. package/dist/identity/create-identity-keys.d.ts +0 -3
  67. package/dist/identity/create-identity-keys.d.ts.map +0 -1
  68. package/dist/identity/create-identity-keys.js +0 -20
  69. package/dist/identity/create-identity-keys.js.map +0 -1
  70. package/dist/identity/login.d.ts +0 -38
  71. package/dist/identity/login.d.ts.map +0 -1
  72. package/dist/identity/login.js +0 -241
  73. package/dist/identity/login.js.map +0 -1
  74. package/dist/utils/hasArrayField.d.ts +0 -2
  75. package/dist/utils/hasArrayField.d.ts.map +0 -1
  76. package/dist/utils/hasArrayField.js +0 -5
  77. package/dist/utils/hasArrayField.js.map +0 -1
@@ -0,0 +1,187 @@
1
+ import { Data, Effect, Array as EffectArray } from 'effect';
2
+ import ts from 'typescript';
3
+
4
+ import * as Mapping from '../../mapping/Mapping.js';
5
+ import * as Utils from '../../mapping/Utils.js';
6
+
7
+ /**
8
+ * Takes a parsed schema.ts file and maps it to a the Mapping.Schema type.
9
+ *
10
+ * @internal
11
+ *
12
+ * @param sourceCode the read schema.ts file
13
+ * @param mapping the parsed mappint.ts file
14
+ * @returns the parsed Schema instance
15
+ */
16
+ export const parseSchema = (
17
+ sourceCode: string,
18
+ mapping: Mapping.Mapping,
19
+ ): Effect.Effect<Mapping.Schema, SchemaParserFailure> =>
20
+ Effect.try({
21
+ try() {
22
+ const sourceFile = ts.createSourceFile('schema.ts', sourceCode, ts.ScriptTarget.Latest, true);
23
+
24
+ const entities: Array<Mapping.SchemaType> = [];
25
+
26
+ const visit = (node: ts.Node) => {
27
+ if (ts.isClassDeclaration(node) && node.name) {
28
+ const className = node.name.text;
29
+ const properties: Array<Mapping.SchemaTypePropertyPrimitive | Mapping.SchemaTypePropertyRelation> = [];
30
+
31
+ // Find the Entity.Class call
32
+ if (node.heritageClauses) {
33
+ for (const clause of node.heritageClauses) {
34
+ for (const type of clause.types) {
35
+ if (ts.isCallExpression(type.expression)) {
36
+ const callExpr = type.expression;
37
+
38
+ // Look for the object literal with properties
39
+ if (callExpr.arguments.length > 0) {
40
+ const arg = callExpr.arguments[0];
41
+ if (ts.isObjectLiteralExpression(arg)) {
42
+ for (const prop of arg.properties) {
43
+ if (ts.isPropertyAssignment(prop) && ts.isIdentifier(prop.name)) {
44
+ const propName = prop.name.text;
45
+ let dataType: Mapping.SchemaDataType = 'String';
46
+ let relationType: string | undefined;
47
+
48
+ const mappingEntry = mapping[className];
49
+ const camelCasePropName = Utils.toCamelCase(propName);
50
+
51
+ // Extract the type
52
+ if (ts.isPropertyAccessExpression(prop.initializer)) {
53
+ // Simple types like Type.Text
54
+ dataType = Mapping.getDataType(prop.initializer.name.text);
55
+
56
+ // Look up the property's knowledgeGraphId from the mapping
57
+ const propKnowledgeGraphId = mappingEntry?.properties?.[camelCasePropName] || null;
58
+
59
+ // push to type properties as primitive property
60
+ properties.push({
61
+ name: propName,
62
+ dataType: dataType as Mapping.SchemaDataTypePrimitive,
63
+ knowledgeGraphId: propKnowledgeGraphId,
64
+ } satisfies Mapping.SchemaTypePropertyPrimitive);
65
+ } else if (ts.isCallExpression(prop.initializer)) {
66
+ // Relation types like Type.Relation(User)
67
+ const callNode = prop.initializer;
68
+ if (ts.isPropertyAccessExpression(callNode.expression)) {
69
+ const typeName = callNode.expression.name.text;
70
+
71
+ if (typeName === 'Relation' && callNode.arguments.length > 0) {
72
+ const relationArg = callNode.arguments[0];
73
+ if (ts.isIdentifier(relationArg)) {
74
+ relationType = relationArg.text;
75
+ dataType = `Relation(${relationType})`;
76
+
77
+ // Look up the relation property's knowledgeGraphId from the mapping
78
+ const relKnowledgeGraphId = mappingEntry?.relations?.[camelCasePropName] || null;
79
+
80
+ // push to type properties as relation property
81
+ properties.push({
82
+ name: propName,
83
+ dataType,
84
+ relationType,
85
+ knowledgeGraphId: relKnowledgeGraphId,
86
+ } satisfies Mapping.SchemaTypePropertyRelation);
87
+ }
88
+ }
89
+ }
90
+ }
91
+ }
92
+ }
93
+ }
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+
100
+ // Look up the type's knowledgeGraphId from the mapping
101
+ const mappingEntry = mapping[Utils.toPascalCase(className)];
102
+ const typeKnowledgeGraphId = mappingEntry?.typeIds?.[0] ? mappingEntry.typeIds[0] : null;
103
+
104
+ entities.push({ name: className, knowledgeGraphId: typeKnowledgeGraphId, properties });
105
+ }
106
+
107
+ ts.forEachChild(node, visit);
108
+ };
109
+
110
+ visit(sourceFile);
111
+
112
+ return {
113
+ types: entities,
114
+ } as const;
115
+ },
116
+ catch(error) {
117
+ return new SchemaParserFailure({
118
+ message: `Failed to parse schema: ${error}`,
119
+ cause: error,
120
+ });
121
+ },
122
+ });
123
+
124
+ export class SchemaParserFailure extends Data.TaggedError('/Hypergraph/cli/errors/SchemaParserFailure')<{
125
+ readonly message: string;
126
+ readonly cause: unknown;
127
+ }> {}
128
+
129
+ /**
130
+ * @internal
131
+ *
132
+ * Runtime check to see if a value looks like a Mapping
133
+ */
134
+ function isMappingLike(value: unknown): value is Mapping.Mapping {
135
+ if (!value || typeof value !== 'object') return false;
136
+ return Object.values(value).every(
137
+ (entry) =>
138
+ entry &&
139
+ typeof entry === 'object' &&
140
+ 'typeIds' in entry &&
141
+ // biome-ignore lint/suspicious/noExplicitAny: parsing so type unknown
142
+ EffectArray.isArray((entry as any).typeIds),
143
+ );
144
+ }
145
+
146
+ /**
147
+ * @internal
148
+ *
149
+ * Look at the exported object from the mapping.ts file loaded via jiti and try to pull out the hypergraph mapping.
150
+ * Default should be:
151
+ * ```typescript
152
+ * export const mapping: Mapping
153
+ * ```
154
+ * But this is not guaranteed. This function looks through the file to try to find it using some logical defaults/checks.
155
+ *
156
+ * @param moduleExport the object imported from jiti from the mapping.ts file
157
+ */
158
+ // biome-ignore lint/suspicious/noExplicitAny: type should be import object from jiti
159
+ export function parseHypergraphMapping(moduleExport: any): Mapping.Mapping {
160
+ // Handle null/undefined inputs
161
+ if (!moduleExport || typeof moduleExport !== 'object') {
162
+ return {} as Mapping.Mapping;
163
+ }
164
+
165
+ // Find all exports that look like Mapping objects
166
+ const mappingCandidates = Object.entries(moduleExport).filter(([, value]) => isMappingLike(value));
167
+
168
+ if (mappingCandidates.length === 0) {
169
+ return {} as Mapping.Mapping;
170
+ }
171
+
172
+ if (mappingCandidates.length === 1) {
173
+ return mappingCandidates[0][1] as Mapping.Mapping;
174
+ }
175
+
176
+ // Multiple candidates - prefer common names
177
+ const preferredNames = ['mapping', 'default', 'config'];
178
+ for (const preferredName of preferredNames) {
179
+ const found = mappingCandidates.find(([name]) => name === preferredName);
180
+ if (found) {
181
+ return found[1] as Mapping.Mapping;
182
+ }
183
+ }
184
+
185
+ // If no preferred names found, use the first one
186
+ return mappingCandidates[0][1] as Mapping.Mapping;
187
+ }
@@ -0,0 +1,93 @@
1
+ import { createServer } from 'node:http';
2
+ import { Command, Options } from '@effect/cli';
3
+ import {
4
+ HttpApi,
5
+ HttpApiBuilder,
6
+ HttpApiEndpoint,
7
+ HttpApiError,
8
+ HttpApiGroup,
9
+ HttpApiSchema,
10
+ HttpMiddleware,
11
+ HttpServer,
12
+ HttpServerResponse,
13
+ } from '@effect/platform';
14
+ import { NodeHttpServer } from '@effect/platform-node';
15
+ import { AnsiDoc } from '@effect/printer-ansi';
16
+ import { Effect, Layer, Schema } from 'effect';
17
+ import * as Typesync from '../services/Typesync.js';
18
+
19
+ const hypergraphTypeSyncApi = HttpApi.make('HypergraphTypeSyncApi')
20
+ .add(
21
+ HttpApiGroup.make('SchemaStreamGroup')
22
+ .add(
23
+ // exposes an api endpoint at /api/vX/schema/events that is a stream of the current Schema parsed from the directory the hypergraph-cli tool is running in
24
+ HttpApiEndpoint.get('HypergraphSchemaEventStream')`/schema/events`
25
+ .addError(HttpApiError.InternalServerError)
26
+ .addSuccess(
27
+ Schema.String.pipe(
28
+ HttpApiSchema.withEncoding({
29
+ kind: 'Json',
30
+ contentType: 'text/event-stream',
31
+ }),
32
+ ),
33
+ ),
34
+ )
35
+ .prefix('/v1'),
36
+ )
37
+ .prefix('/api');
38
+
39
+ const hypergraphTypeSyncApiLive = HttpApiBuilder.group(hypergraphTypeSyncApi, 'SchemaStreamGroup', (handlers) =>
40
+ handlers.handle('HypergraphSchemaEventStream', () =>
41
+ Effect.gen(function* () {
42
+ const schemaStream = yield* Typesync.TypesyncSchemaStreamBuilder;
43
+
44
+ const stream = yield* schemaStream
45
+ .hypergraphSchemaStream()
46
+ .pipe(Effect.catchAll(() => new HttpApiError.InternalServerError()));
47
+
48
+ return yield* HttpServerResponse.stream(stream, { contentType: 'text/event-stream' }).pipe(
49
+ HttpServerResponse.setHeaders({
50
+ 'Content-Type': 'text/event-stream',
51
+ 'Cache-Control': 'no-cache',
52
+ Connection: 'keep-alive',
53
+ }),
54
+ );
55
+ }),
56
+ ),
57
+ );
58
+
59
+ const HypergraphTypeSyncApiLive = HttpApiBuilder.api(hypergraphTypeSyncApi).pipe(
60
+ Layer.provide(hypergraphTypeSyncApiLive),
61
+ Layer.provide(Typesync.layer),
62
+ );
63
+
64
+ const HypergraphTypeSyncApiLayer = HttpApiBuilder.serve(HttpMiddleware.logger).pipe(
65
+ Layer.provide(HttpApiBuilder.middlewareCors()),
66
+ Layer.provide(HypergraphTypeSyncApiLive),
67
+ );
68
+
69
+ export const typesync = Command.make('typesync', {
70
+ args: {
71
+ port: Options.integer('port').pipe(
72
+ Options.withAlias('p'),
73
+ Options.withDefault(3000),
74
+ Options.withDescription('The port to run the Hypergraph TypeSync studio server on. Default 3000'),
75
+ ),
76
+ },
77
+ }).pipe(
78
+ Command.withDescription(
79
+ 'Opens the TypeSync studio to help users build and publish their Hypergraph application schema',
80
+ ),
81
+ Command.withHandler(({ args }) =>
82
+ Effect.gen(function* () {
83
+ yield* HypergraphTypeSyncApiLayer.pipe(
84
+ HttpServer.withLogAddress,
85
+ Layer.provide(NodeHttpServer.layer(createServer, { port: args.port })),
86
+ Layer.tap(() =>
87
+ Effect.logInfo(AnsiDoc.text(`🎉 TypeSync studio started and running at http://localhost:${args.port}`)),
88
+ ),
89
+ Layer.launch,
90
+ );
91
+ }),
92
+ ),
93
+ );
@@ -15,7 +15,7 @@ import type {
15
15
  EntityFieldFilter,
16
16
  EntityFilter,
17
17
  EntityNumberFilter,
18
- EntityTextFilter,
18
+ EntityStringFilter,
19
19
  } from './types.js';
20
20
 
21
21
  const documentChangeListener: {
@@ -298,19 +298,19 @@ export function findMany<const S extends AnyNoContext>(
298
298
 
299
299
  if (typeof fieldValue === 'string') {
300
300
  if ('startsWith' in fieldFilter) {
301
- const textFilter = fieldFilter as EntityTextFilter;
301
+ const textFilter = fieldFilter as EntityStringFilter;
302
302
  if (textFilter.startsWith !== undefined && !fieldValue.startsWith(textFilter.startsWith)) {
303
303
  return false;
304
304
  }
305
305
  }
306
306
  if ('endsWith' in fieldFilter) {
307
- const textFilter = fieldFilter as EntityTextFilter;
307
+ const textFilter = fieldFilter as EntityStringFilter;
308
308
  if (textFilter.endsWith !== undefined && !fieldValue.endsWith(textFilter.endsWith)) {
309
309
  return false;
310
310
  }
311
311
  }
312
312
  if ('contains' in fieldFilter) {
313
- const textFilter = fieldFilter as EntityTextFilter;
313
+ const textFilter = fieldFilter as EntityStringFilter;
314
314
  if (textFilter.contains !== undefined && !fieldValue.includes(textFilter.contains)) {
315
315
  return false;
316
316
  }
@@ -47,7 +47,7 @@ export type DocumentContent = {
47
47
  relations?: Record<string, DocumentRelation>;
48
48
  };
49
49
 
50
- export type EntityCheckboxFilter = {
50
+ export type EntityBooleanFilter = {
51
51
  is: boolean;
52
52
  };
53
53
 
@@ -59,14 +59,14 @@ export type EntityNumberFilter = {
59
59
  or?: EntityNumberFilter[];
60
60
  };
61
61
 
62
- export type EntityTextFilter = {
62
+ export type EntityStringFilter = {
63
63
  is?: string;
64
64
  startsWith?: string;
65
65
  endsWith?: string;
66
66
  contains?: string;
67
67
  equals?: string;
68
- not?: EntityTextFilter;
69
- or?: EntityTextFilter[];
68
+ not?: EntityStringFilter;
69
+ or?: EntityStringFilter[];
70
70
  };
71
71
 
72
72
  export type CrossFieldFilter<T> = {
package/src/index.ts CHANGED
@@ -1,3 +1,4 @@
1
+ export { Id } from '@graphprotocol/grc-20';
1
2
  export * as Connect from './connect/index.js';
2
3
  export * as Entity from './entity/index.js';
3
4
  export * as Identity from './identity/index.js';
@@ -10,5 +11,6 @@ export * as SpaceInfo from './space-info/index.js';
10
11
  export * from './store.js';
11
12
  export * as StoreConnect from './store-connect.js';
12
13
  export * as Type from './type/type.js';
14
+ export * as TypeUtils from './type-utils/type-utils.js';
13
15
  export * from './types.js';
14
16
  export * as Utils from './utils/index.js';
@@ -10,30 +10,30 @@ import { namesAreUnique, toCamelCase, toPascalCase } from './Utils.js';
10
10
  */
11
11
  export type MappingEntry = {
12
12
  /**
13
- * Array of the `Id.Id` of the type in the Knowledge Graph.
13
+ * Array of the `Id` of the type in the Knowledge Graph.
14
14
  * Is an array because a type can belong to multiple spaces/extend multiple types.
15
15
  *
16
16
  * @since 0.2.0
17
17
  */
18
- typeIds: Array<Grc20Id.Id>;
18
+ typeIds: Array<Grc20Id>;
19
19
  /**
20
- * Record of property names to the `Id.Id` of the type in the Knowledge Graph
20
+ * Record of property names to the `Id` of the type in the Knowledge Graph
21
21
  *
22
22
  * @since 0.2.0
23
23
  */
24
24
  properties?:
25
25
  | {
26
- [key: string]: Grc20Id.Id;
26
+ [key: string]: Grc20Id;
27
27
  }
28
28
  | undefined;
29
29
  /**
30
- * Record of relation properties to the `Id.Id` of the type in the Knowledge Graph
30
+ * Record of relation properties to the `Id` of the type in the Knowledge Graph
31
31
  *
32
32
  * @since 0.2.0
33
33
  */
34
34
  relations?:
35
35
  | {
36
- [key: string]: Grc20Id.Id;
36
+ [key: string]: Grc20Id;
37
37
  }
38
38
  | undefined;
39
39
  };
@@ -46,20 +46,20 @@ export type MappingEntry = {
46
46
  *
47
47
  * const mapping: Mapping = {
48
48
  * Account: {
49
- * typeIds: [Id.Id('a5fd07b1-120f-46c6-b46f-387ef98396a6')],
49
+ * typeIds: [Id('a5fd07b1-120f-46c6-b46f-387ef98396a6')],
50
50
  * properties: {
51
- * username: Id.Id('994edcff-6996-4a77-9797-a13e5e3efad8'),
52
- * createdAt: Id.Id('64bfba51-a69b-4746-be4b-213214a879fe')
51
+ * username: Id('994edcff-6996-4a77-9797-a13e5e3efad8'),
52
+ * createdAt: Id('64bfba51-a69b-4746-be4b-213214a879fe')
53
53
  * }
54
54
  * },
55
55
  * Event: {
56
- * typeIds: [Id.Id('0349187b-526f-435f-b2bb-9e9caf23127a')],
56
+ * typeIds: [Id('0349187b-526f-435f-b2bb-9e9caf23127a')],
57
57
  * properties: {
58
- * name: Id.Id('3808e060-fb4a-4d08-8069-35b8c8a1902b'),
59
- * description: Id.Id('1f0d9007-8da2-4b28-ab9f-3bc0709f4837'),
58
+ * name: Id('3808e060-fb4a-4d08-8069-35b8c8a1902b'),
59
+ * description: Id('1f0d9007-8da2-4b28-ab9f-3bc0709f4837'),
60
60
  * },
61
61
  * relations: {
62
- * speaker: Id.Id('a5fd07b1-120f-46c6-b46f-387ef98396a6')
62
+ * speaker: Id('a5fd07b1-120f-46c6-b46f-387ef98396a6')
63
63
  * }
64
64
  * }
65
65
  * }
@@ -94,11 +94,17 @@ export type SchemaDataTypeRelation = typeof SchemaDataTypeRelation.Type;
94
94
  /**
95
95
  * @since 0.2.0
96
96
  */
97
- export const SchemaDataTypePrimitive = EffectSchema.Literal('Text', 'Number', 'Checkbox', 'Date', 'Point');
97
+ export const SchemaDataTypePrimitive = EffectSchema.Literal('String', 'Number', 'Boolean', 'Date', 'Point');
98
98
  /**
99
99
  * @since 0.2.0
100
100
  */
101
101
  export type SchemaDataTypePrimitive = typeof SchemaDataTypePrimitive.Type;
102
+ /**
103
+ * @since 0.4.0
104
+ */
105
+ export function isDataTypePrimitive(val: string): val is SchemaDataTypePrimitive {
106
+ return ['String', 'Number', 'Boolean', 'Date', 'Point'].includes(val);
107
+ }
102
108
  /**
103
109
  * @since 0.2.0
104
110
  */
@@ -107,6 +113,22 @@ export const SchemaDataType = EffectSchema.Union(SchemaDataTypePrimitive, Schema
107
113
  * @since 0.2.0
108
114
  */
109
115
  export type SchemaDataType = typeof SchemaDataType.Type;
116
+ /**
117
+ * @since 0.4.0
118
+ */
119
+ export function isDataType(val: string): val is SchemaDataType {
120
+ return isDataTypePrimitive(val) || isDataTypeRelation(val);
121
+ }
122
+ /**
123
+ * @since 0.4.0
124
+ */
125
+ export function getDataType(val: string): SchemaDataType {
126
+ const dataType = isDataTypePrimitive(val) || isDataTypeRelation(val);
127
+ if (dataType) {
128
+ return val;
129
+ }
130
+ throw new Error(`Passed dataType ${val} is not supported`);
131
+ }
110
132
  /**
111
133
  * @since 0.2.0
112
134
  */
@@ -195,7 +217,7 @@ export const Schema = EffectSchema.Struct({
195
217
  {
196
218
  name: 'Account',
197
219
  knowledgeGraphId: null,
198
- properties: [{ name: 'username', knowledgeGraphId: null, dataType: 'Text' }],
220
+ properties: [{ name: 'username', knowledgeGraphId: null, dataType: 'String' }],
199
221
  },
200
222
  ],
201
223
  },
@@ -204,7 +226,7 @@ export const Schema = EffectSchema.Struct({
204
226
  {
205
227
  name: 'Account',
206
228
  knowledgeGraphId: 'a5fd07b1-120f-46c6-b46f-387ef98396a6',
207
- properties: [{ name: 'name', knowledgeGraphId: 'a126ca53-0c8e-48d5-b888-82c734c38935', dataType: 'Text' }],
229
+ properties: [{ name: 'name', knowledgeGraphId: 'a126ca53-0c8e-48d5-b888-82c734c38935', dataType: 'String' }],
208
230
  },
209
231
  ],
210
232
  },
@@ -238,7 +260,7 @@ export const SchemaUnknownDecoder = EffectSchema.decodeUnknownSync(Schema);
238
260
  * properties: [
239
261
  * {
240
262
  * name: "username",
241
- * dataType: "Text",
263
+ * dataType: "String",
242
264
  * knowledgeGraphId: null
243
265
  * }
244
266
  * ]
@@ -297,8 +319,8 @@ export function allRelationPropertyTypesExist(types: ReadonlyArray<SchemaType>):
297
319
  export type GenerateMappingResult = [mapping: Mapping, ops: ReadonlyArray<Op>];
298
320
 
299
321
  // Helper types for internal processing
300
- type PropertyIdMapping = { propName: string; id: Grc20Id.Id };
301
- type TypeIdMapping = Map<string, Grc20Id.Id | null>;
322
+ type PropertyIdMapping = { propName: string; id: Grc20Id };
323
+ type TypeIdMapping = Map<string, Grc20Id | null>;
302
324
  type ProcessedProperty =
303
325
  | { type: 'resolved'; mapping: PropertyIdMapping; ops: Array<Op> }
304
326
  | { type: 'deferred'; property: SchemaTypePropertyRelation };
@@ -342,7 +364,7 @@ function createPropertyWithOps(
342
364
  if (property.knowledgeGraphId) {
343
365
  return {
344
366
  type: 'resolved',
345
- mapping: { propName: property.name, id: Grc20Id.Id(property.knowledgeGraphId) },
367
+ mapping: { propName: property.name, id: Grc20Id(property.knowledgeGraphId) },
346
368
  ops: [],
347
369
  };
348
370
  }
@@ -421,7 +443,7 @@ function processType(type: SchemaType, typeIdMap: TypeIdMapping): ProcessedType
421
443
  if (type.knowledgeGraphId) {
422
444
  const entry: MappingEntry & { typeName: string } = {
423
445
  typeName: toPascalCase(type.name),
424
- typeIds: [Grc20Id.Id(type.knowledgeGraphId)],
446
+ typeIds: [Grc20Id(type.knowledgeGraphId)],
425
447
  };
426
448
 
427
449
  if (EffectArray.isNonEmptyArray(primitiveProperties)) {
@@ -487,7 +509,7 @@ function processType(type: SchemaType, typeIdMap: TypeIdMapping): ProcessedType
487
509
  * @example
488
510
  * ```ts
489
511
  * import { Id } from "@graphprotocol/grc-20"
490
- * import { generateMapping } from "@graphprotocol/typesync"
512
+ * import { generateMapping } from "@graphprotocol/hypergraph"
491
513
  *
492
514
  * const schema: Schema = {
493
515
  * types: [
@@ -497,7 +519,7 @@ function processType(type: SchemaType, typeIdMap: TypeIdMapping): ProcessedType
497
519
  * properties: [
498
520
  * {
499
521
  * name: "username",
500
- * dataType: "Text",
522
+ * dataType: "String",
501
523
  * knowledgeGraphId: "994edcff-6996-4a77-9797-a13e5e3efad8"
502
524
  * },
503
525
  * {
@@ -513,12 +535,12 @@ function processType(type: SchemaType, typeIdMap: TypeIdMapping): ProcessedType
513
535
  * properties: [
514
536
  * {
515
537
  * name: "name",
516
- * dataType: "Text",
538
+ * dataType: "String",
517
539
  * knowledgeGraphId: "3808e060-fb4a-4d08-8069-35b8c8a1902b"
518
540
  * },
519
541
  * {
520
542
  * name: "description",
521
- * dataType: "Text",
543
+ * dataType: "String",
522
544
  * knowledgeGraphId: null
523
545
  * },
524
546
  * {
@@ -535,20 +557,20 @@ function processType(type: SchemaType, typeIdMap: TypeIdMapping): ProcessedType
535
557
  *
536
558
  * expect(mapping).toEqual({
537
559
  * Account: {
538
- * typeIds: [Id.Id("a5fd07b1-120f-46c6-b46f-387ef98396a6")], // comes from input schema
560
+ * typeIds: [Id("a5fd07b1-120f-46c6-b46f-387ef98396a6")], // comes from input schema
539
561
  * properties: {
540
- * username: Id.Id("994edcff-6996-4a77-9797-a13e5e3efad8"), // comes from input schema
541
- * createdAt: Id.Id("8cd7d9ac-a878-4287-8000-e71e6f853117"), // generated from Graph.createProperty Op
562
+ * username: Id("994edcff-6996-4a77-9797-a13e5e3efad8"), // comes from input schema
563
+ * createdAt: Id("8cd7d9ac-a878-4287-8000-e71e6f853117"), // generated from Graph.createProperty Op
542
564
  * }
543
565
  * },
544
566
  * Event: {
545
- * typeIds: [Id.Id("20b3fe39-8e62-41a0-b9cb-92743fd760da")], // generated from Graph.createType Op
567
+ * typeIds: [Id("20b3fe39-8e62-41a0-b9cb-92743fd760da")], // generated from Graph.createType Op
546
568
  * properties: {
547
- * name: Id.Id("3808e060-fb4a-4d08-8069-35b8c8a1902b"), // comes from input schema
548
- * description: Id.Id("8fc4e17c-7581-4d6c-a712-943385afc7b5"), // generated from Graph.createProperty Op
569
+ * name: Id("3808e060-fb4a-4d08-8069-35b8c8a1902b"), // comes from input schema
570
+ * description: Id("8fc4e17c-7581-4d6c-a712-943385afc7b5"), // generated from Graph.createProperty Op
549
571
  * },
550
572
  * relations: {
551
- * speaker: Id.Id("651ce59f-643b-4931-bf7a-5dc0ca0f5a47"), // generated from Graph.createProperty Op
573
+ * speaker: Id("651ce59f-643b-4931-bf7a-5dc0ca0f5a47"), // generated from Graph.createProperty Op
552
574
  * }
553
575
  * }
554
576
  * })
@@ -557,23 +579,23 @@ function processType(type: SchemaType, typeIdMap: TypeIdMapping): ProcessedType
557
579
  * {
558
580
  * type: "CREATE_PROPERTY",
559
581
  * property: {
560
- * id: Id.Id("8cd7d9ac-a878-4287-8000-e71e6f853117"),
561
- * dataType: "TEXT"
582
+ * id: Id("8cd7d9ac-a878-4287-8000-e71e6f853117"),
583
+ * dataType: "String"
562
584
  * }
563
585
  * },
564
586
  * // Graph.createProperty Op for Event.description property
565
587
  * {
566
588
  * type: "CREATE_PROPERTY",
567
589
  * property: {
568
- * id: Id.Id("8fc4e17c-7581-4d6c-a712-943385afc7b5"),
569
- * dataType: "TEXT"
590
+ * id: Id("8fc4e17c-7581-4d6c-a712-943385afc7b5"),
591
+ * dataType: "String"
570
592
  * }
571
593
  * },
572
594
  * // Graph.createProperty Op for Event.speaker property
573
595
  * {
574
596
  * type: "CREATE_PROPERTY",
575
597
  * property: {
576
- * id: Id.Id("651ce59f-643b-4931-bf7a-5dc0ca0f5a47"),
598
+ * id: Id("651ce59f-643b-4931-bf7a-5dc0ca0f5a47"),
577
599
  * dataType: "RELATION"
578
600
  * }
579
601
  * },
@@ -581,7 +603,7 @@ function processType(type: SchemaType, typeIdMap: TypeIdMapping): ProcessedType
581
603
  * {
582
604
  * type: "CREATE_PROPERTY",
583
605
  * property: {
584
- * id: Id.Id("651ce59f-643b-4931-bf7a-5dc0ca0f5a47"),
606
+ * id: Id("651ce59f-643b-4931-bf7a-5dc0ca0f5a47"),
585
607
  * dataType: "RELATION"
586
608
  * }
587
609
  * },
@@ -600,8 +622,8 @@ export function generateMapping(input: Schema): GenerateMappingResult {
600
622
  // Build initial type ID map
601
623
  const typeIdMap: TypeIdMapping = pipe(
602
624
  schema.types,
603
- EffectArray.reduce(new Map<string, Grc20Id.Id | null>(), (map, type) =>
604
- map.set(type.name, type.knowledgeGraphId != null ? Grc20Id.Id(type.knowledgeGraphId) : null),
625
+ EffectArray.reduce(new Map<string, Grc20Id | null>(), (map, type) =>
626
+ map.set(type.name, type.knowledgeGraphId != null ? Grc20Id(type.knowledgeGraphId) : null),
605
627
  ),
606
628
  );
607
629
 
@@ -749,8 +771,8 @@ export class RelationValueTypeDoesNotExistError extends Data.TaggedError(
749
771
  */
750
772
  export function mapSchemaDataTypeToGRC20PropDataType(dataType: SchemaDataType): CreatePropertyParams['dataType'] {
751
773
  switch (true) {
752
- case dataType === 'Checkbox': {
753
- return 'CHECKBOX';
774
+ case dataType === 'Boolean': {
775
+ return 'BOOLEAN';
754
776
  }
755
777
  case dataType === 'Date': {
756
778
  return 'TIME';
@@ -765,7 +787,7 @@ export function mapSchemaDataTypeToGRC20PropDataType(dataType: SchemaDataType):
765
787
  return 'RELATION';
766
788
  }
767
789
  default: {
768
- return 'TEXT';
790
+ return 'STRING';
769
791
  }
770
792
  }
771
793
  }
package/src/type/type.ts CHANGED
@@ -2,10 +2,12 @@ import * as Schema from 'effect/Schema';
2
2
  import { Field } from '../entity/entity.js';
3
3
  import type { AnyNoContext, EntityWithRelation } from '../entity/types.js';
4
4
 
5
- export const Text = Schema.String;
5
+ // biome-ignore lint/suspicious/noShadowRestrictedNames: is part of a namespaces module and therefor ok
6
+ export const String = Schema.String;
6
7
  // biome-ignore lint/suspicious/noShadowRestrictedNames: is part of a namespaces module and therefor ok
7
8
  export const Number = Schema.Number;
8
- export const Checkbox = Schema.Boolean;
9
+ // biome-ignore lint/suspicious/noShadowRestrictedNames: is part of a namespaces module and therefor ok
10
+ export const Boolean = Schema.Boolean;
9
11
  // biome-ignore lint/suspicious/noShadowRestrictedNames: is part of a namespaces module and therefor ok
10
12
  export const Date = Schema.Date;
11
13
  export const Point = Schema.transform(Schema.String, Schema.Array(Number), {
@@ -16,6 +18,8 @@ export const Point = Schema.transform(Schema.String, Schema.Array(Number), {
16
18
  encode: (points: readonly number[]) => points.join(','),
17
19
  });
18
20
 
21
+ export const optional = Schema.optional;
22
+
19
23
  export const Relation = <S extends AnyNoContext>(schema: S) => {
20
24
  const relationSchema = Field({
21
25
  select: Schema.Array(schema) as unknown as Schema.Schema<ReadonlyArray<EntityWithRelation<S>>>,