Repository: graphprotocol/graph-tooling
Pull request #1971 (2025-02-17 03:47:35)

`graph codegen`: fix bug with id field clash in example entity
#1810 fixed `id` field clash for event entities, but not for example entity

To reproduce, run `graph init` for `0xb89279DEd0AD7cD573D164b03424E1E2BbE1e2Be` on `moonbeam` and choose "N" when asked to index events.

This PR fixes it.

changeset-bot[bot]: ###  🦋  Changeset detected

Latest commit: 2d5af508ae7d919c504dd94639997de003d01712

**The changes in this PR will be included in the next version bump.**

<details><summary>This PR includes changesets to release 1 package</summary>

  | Name                     | Type  |
| ------------------------ | ----- |
| @graphprotocol/graph-cli | Patch |

</details>

Not sure what this means? [Click here  to learn what changesets are](https://github.com/changesets/changesets/blob/main/docs/adding-a-changeset.md).

[Click here if you're a maintainer who wants to add another changeset to this PR](https://github.com/graphprotocol/graph-tooling/new/yaro/fix-example-id-clash?filename=.changeset/tidy-elephants-own.md&value=---%0A%22%40graphprotocol%2Fgraph-cli%22%3A%20patch%0A---%0A%0A%60graph%20codegen%60%3A%20fix%20bug%20with%20id%20field%20clash%20in%20example%20entity%0A)


github-actions[bot]: <!-- changesetsSnapshotPrCommentKey -->
### 🚀 Snapshot Release (`alpha`)

The latest changes of this PR are available as `alpha` on npm (based on the declared `changesets`):
| Package | Version | Info |
|------|---------|----|
| `@graphprotocol/graph-cli` | `0.96.0-alpha-20250217034807-2d5af508ae7d919c504dd94639997de003d01712` | [npm ↗︎](https://www.npmjs.com/package/@graphprotocol/graph-cli/v/0.96.0-alpha-20250217034807-2d5af508ae7d919c504dd94639997de003d01712) [unpkg ↗︎](https://unpkg.com/browse/@graphprotocol/graph-cli@0.96.0-alpha-20250217034807-2d5af508ae7d919c504dd94639997de003d01712/) |
| `@graphprotocol/graph-ts` | `0.38.0-alpha-20250217034807-2d5af508ae7d919c504dd94639997de003d01712` | [npm ↗︎](https://www.npmjs.com/package/@graphprotocol/graph-ts/v/0.38.0-alpha-20250217034807-2d5af508ae7d919c504dd94639997de003d01712) [unpkg ↗︎](https://unpkg.com/browse/@graphprotocol/graph-ts@0.38.0-alpha-20250217034807-2d5af508ae7d919c504dd94639997de003d01712/) |

Patch:
diff --git a/.changeset/@graphprotocol_graph-cli-1834-dependencies.md b/.changeset/@graphprotocol_graph-cli-1834-dependencies.md
deleted file mode 100644
index c4b4c7ae..00000000
--- a/.changeset/@graphprotocol_graph-cli-1834-dependencies.md
+++ /dev/null
@@ -1,12 +0,0 @@
----
-"@graphprotocol/graph-cli": patch
----
-dependencies updates:
-  - Updated dependency [`@oclif/core@4.2.4` ↗︎](https://www.npmjs.com/package/@oclif/core/v/4.2.4) (from `4.0.34`, in `dependencies`)
-  - Updated dependency [`chokidar@4.0.3` ↗︎](https://www.npmjs.com/package/chokidar/v/4.0.3) (from `4.0.1`, in `dependencies`)
-  - Updated dependency [`debug@4.4.0` ↗︎](https://www.npmjs.com/package/debug/v/4.4.0) (from `4.3.7`, in `dependencies`)
-  - Updated dependency [`fs-extra@11.3.0` ↗︎](https://www.npmjs.com/package/fs-extra/v/11.3.0) (from `11.2.0`, in `dependencies`)
-  - Updated dependency [`glob@11.0.1` ↗︎](https://www.npmjs.com/package/glob/v/11.0.1) (from `11.0.0`, in `dependencies`)
-  - Updated dependency [`graphql@16.10.0` ↗︎](https://www.npmjs.com/package/graphql/v/16.10.0) (from `16.9.0`, in `dependencies`)
-  - Updated dependency [`undici@7.3.0` ↗︎](https://www.npmjs.com/package/undici/v/7.3.0) (from `7.2.3`, in `dependencies`)
-  - Updated dependency [`yaml@2.7.0` ↗︎](https://www.npmjs.com/package/yaml/v/2.7.0) (from `2.6.1`, in `dependencies`)
diff --git a/.changeset/@graphprotocol_graph-cli-1932-dependencies.md b/.changeset/@graphprotocol_graph-cli-1932-dependencies.md
deleted file mode 100644
index 5f845092..00000000
--- a/.changeset/@graphprotocol_graph-cli-1932-dependencies.md
+++ /dev/null
@@ -1,6 +0,0 @@
----
-"@graphprotocol/graph-cli": patch
----
-dependencies updates:
-  - Updated dependency [`@oclif/core@4.2.6` ↗︎](https://www.npmjs.com/package/@oclif/core/v/4.2.6) (from `4.2.4`, in `dependencies`)
-  - Updated dependency [`semver@7.7.1` ↗︎](https://www.npmjs.com/package/semver/v/7.7.1) (from `7.6.3`, in `dependencies`)
diff --git a/.changeset/curly-buses-hang.md b/.changeset/curly-buses-hang.md
deleted file mode 100644
index ef7b1341..00000000
--- a/.changeset/curly-buses-hang.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@graphprotocol/graph-cli': minor
----
-
-Add support for subgraph datasource in `graph init`
diff --git a/.changeset/giant-eyes-play.md b/.changeset/giant-eyes-play.md
deleted file mode 100644
index 40e55821..00000000
--- a/.changeset/giant-eyes-play.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@graphprotocol/graph-cli': minor
----
-
-`graph codegen`: handle events with fields with reserved names #1896
diff --git a/.changeset/giant-owls-accept.md b/.changeset/giant-owls-accept.md
deleted file mode 100644
index cbd0815e..00000000
--- a/.changeset/giant-owls-accept.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@graphprotocol/graph-cli': patch
----
-
-Use Sourcify v2 endpoint for contract lookups
diff --git a/.changeset/gold-birds-dream.md b/.changeset/gold-birds-dream.md
deleted file mode 100644
index 2d70f85d..00000000
--- a/.changeset/gold-birds-dream.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@graphprotocol/graph-cli': patch
----
-
-`graph init`: format and validate subgraph slug to match graph-node rules
diff --git a/.changeset/new-rules-bake.md b/.changeset/new-rules-bake.md
new file mode 100644
index 00000000..93c2044c
--- /dev/null
+++ b/.changeset/new-rules-bake.md
@@ -0,0 +1,5 @@
+---
+"@graphprotocol/graph-cli": patch
+---
+
+fix: generate types for mappings when int8 is used as id
diff --git a/.changeset/purple-files-think.md b/.changeset/purple-files-think.md
new file mode 100644
index 00000000..9b2864a6
--- /dev/null
+++ b/.changeset/purple-files-think.md
@@ -0,0 +1,5 @@
+---
+'@graphprotocol/graph-cli': patch
+---
+
+`graph codegen`: fix bug with id field clash in example entity
diff --git a/.changeset/rare-carpets-tell.md b/.changeset/rare-carpets-tell.md
deleted file mode 100644
index 37eb11d9..00000000
--- a/.changeset/rare-carpets-tell.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@graphprotocol/graph-ts': minor
----
-
-feat: add yaml parsing support to mappings
diff --git a/.changeset/smooth-poets-rush.md b/.changeset/smooth-poets-rush.md
deleted file mode 100644
index b7707aec..00000000
--- a/.changeset/smooth-poets-rush.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@graphprotocol/graph-cli': patch
----
-
-chore: move github actions around
diff --git a/.changeset/witty-teachers-smell.md b/.changeset/witty-teachers-smell.md
deleted file mode 100644
index 989a6067..00000000
--- a/.changeset/witty-teachers-smell.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@graphprotocol/graph-cli': patch
----
-
-fix bug with "other wallets" not working #1900
diff --git a/.changeset/yellow-jobs-brake.md b/.changeset/yellow-jobs-brake.md
deleted file mode 100644
index eb287398..00000000
--- a/.changeset/yellow-jobs-brake.md
+++ /dev/null
@@ -1,5 +0,0 @@
----
-'@graphprotocol/graph-cli': patch
----
-
-`graph init`: improve error reporting
diff --git a/packages/cli/CHANGELOG.md b/packages/cli/CHANGELOG.md
index 02844f31..5e845742 100644
--- a/packages/cli/CHANGELOG.md
+++ b/packages/cli/CHANGELOG.md
@@ -1,5 +1,43 @@
 # @graphprotocol/graph-cli
 
+## 0.96.0
+
+### Minor Changes
+
+- [#1920](https://github.com/graphprotocol/graph-tooling/pull/1920) [`b6d7f1c`](https://github.com/graphprotocol/graph-tooling/commit/b6d7f1cd149c5784089aa92bafd63e6a0d9814a1) Thanks [@incrypto32](https://github.com/incrypto32)! - Add support for subgraph datasource in `graph init`
+
+- [#1929](https://github.com/graphprotocol/graph-tooling/pull/1929) [`4311d0e`](https://github.com/graphprotocol/graph-tooling/commit/4311d0e177b37a7698d5befae9b6e9cafa6b37c9) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - `graph codegen`: handle events with fields with reserved names #1896
+
+### Patch Changes
+
+- [#1834](https://github.com/graphprotocol/graph-tooling/pull/1834) [`0058157`](https://github.com/graphprotocol/graph-tooling/commit/0058157e45c8902cf0068c359492da3d751529f8) Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
+
+  - Updated dependency [`@oclif/core@4.2.4` ↗︎](https://www.npmjs.com/package/@oclif/core/v/4.2.4) (from `4.0.34`, in `dependencies`)
+  - Updated dependency [`chokidar@4.0.3` ↗︎](https://www.npmjs.com/package/chokidar/v/4.0.3) (from `4.0.1`, in `dependencies`)
+  - Updated dependency [`debug@4.4.0` ↗︎](https://www.npmjs.com/package/debug/v/4.4.0) (from `4.3.7`, in `dependencies`)
+  - Updated dependency [`fs-extra@11.3.0` ↗︎](https://www.npmjs.com/package/fs-extra/v/11.3.0) (from `11.2.0`, in `dependencies`)
+  - Updated dependency [`glob@11.0.1` ↗︎](https://www.npmjs.com/package/glob/v/11.0.1) (from `11.0.0`, in `dependencies`)
+  - Updated dependency [`graphql@16.10.0` ↗︎](https://www.npmjs.com/package/graphql/v/16.10.0) (from `16.9.0`, in `dependencies`)
+  - Updated dependency [`undici@7.3.0` ↗︎](https://www.npmjs.com/package/undici/v/7.3.0) (from `7.2.3`, in `dependencies`)
+  - Updated dependency [`yaml@2.7.0` ↗︎](https://www.npmjs.com/package/yaml/v/2.7.0) (from `2.6.1`, in `dependencies`)
+
+- [#1932](https://github.com/graphprotocol/graph-tooling/pull/1932) [`80a2ae9`](https://github.com/graphprotocol/graph-tooling/commit/80a2ae9b11260786896665993655056ff048b84b) Thanks [@renovate](https://github.com/apps/renovate)! - dependencies updates:
+
+  - Updated dependency [`@oclif/core@4.2.6` ↗︎](https://www.npmjs.com/package/@oclif/core/v/4.2.6) (from `4.2.4`, in `dependencies`)
+  - Updated dependency [`semver@7.7.1` ↗︎](https://www.npmjs.com/package/semver/v/7.7.1) (from `7.6.3`, in `dependencies`)
+
+- [#1965](https://github.com/graphprotocol/graph-tooling/pull/1965) [`e7b0e72`](https://github.com/graphprotocol/graph-tooling/commit/e7b0e72610c63dceb1c0af9bd2ef2c14b8bf7609) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - `graph init`: get generated apiVersion and specVersion up to date
+
+- [#1957](https://github.com/graphprotocol/graph-tooling/pull/1957) [`e4af888`](https://github.com/graphprotocol/graph-tooling/commit/e4af88808798e11450b7383d2d658b2ee5936979) Thanks [@0237h](https://github.com/0237h)! - Use Sourcify v2 endpoint for contract lookups
+
+- [#1962](https://github.com/graphprotocol/graph-tooling/pull/1962) [`7f22631`](https://github.com/graphprotocol/graph-tooling/commit/7f226318cf95d959bba2752d9c7d2d518c0622d7) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - `graph init`: format and validate subgraph slug to match graph-node rules
+
+- [#1919](https://github.com/graphprotocol/graph-tooling/pull/1919) [`955f7b0`](https://github.com/graphprotocol/graph-tooling/commit/955f7b02629c142b18ea9f05fce0a6745a4921b7) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - chore: move github actions around
+
+- [#1954](https://github.com/graphprotocol/graph-tooling/pull/1954) [`9fc413f`](https://github.com/graphprotocol/graph-tooling/commit/9fc413f6ba39bf0c4cc36a7683bb13a1157e3606) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - fix bug with "other wallets" not working #1900
+
+- [#1960](https://github.com/graphprotocol/graph-tooling/pull/1960) [`33a7148`](https://github.com/graphprotocol/graph-tooling/commit/33a71482283dd2e578ca02ceb8906e85438e09d0) Thanks [@YaroShkvorets](https://github.com/YaroShkvorets)! - `graph init`: improve error reporting
+
 ## 0.95.0
 
 ### Minor Changes
diff --git a/packages/cli/package.json b/packages/cli/package.json
index ed5462be..c36b3596 100644
--- a/packages/cli/package.json
+++ b/packages/cli/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@graphprotocol/graph-cli",
-  "version": "0.95.0",
+  "version": "0.96.0",
   "type": "module",
   "description": "CLI for building for and deploying to The Graph",
   "repository": {
diff --git a/packages/cli/src/codegen/schema.ts b/packages/cli/src/codegen/schema.ts
index ef98482a..3bbcd5c9 100644
--- a/packages/cli/src/codegen/schema.ts
+++ b/packages/cli/src/codegen/schema.ts
@@ -16,8 +16,9 @@ import * as util from './util.js';
 class IdField {
   static BYTES = Symbol('Bytes');
   static STRING = Symbol('String');
+  static INT8 = Symbol('Int8');
 
-  private kind: typeof IdField.BYTES | typeof IdField.STRING;
+  private kind: typeof IdField.BYTES | typeof IdField.INT8 | typeof IdField.STRING;
 
   constructor(idField: FieldDefinitionNode | undefined) {
     if (idField?.type.kind !== 'NonNullType') {
@@ -27,15 +28,46 @@ class IdField {
       throw Error('id field must be a named type');
     }
     const typeName = idField.type.type.name.value;
-    this.kind = typeName === 'Bytes' ? IdField.BYTES : IdField.STRING;
+    switch (typeName) {
+      case 'Bytes':
+        this.kind = IdField.BYTES;
+        break;
+      case 'Int8':
+        this.kind = IdField.INT8;
+        break;
+      case 'String':
+        this.kind = IdField.STRING;
+        break;
+      default:
+        this.kind = IdField.STRING;
+        break;
+    }
   }
 
   typeName() {
-    return this.kind === IdField.BYTES ? 'Bytes' : 'string';
+    switch (this.kind) {
+      case IdField.BYTES:
+        return 'Bytes';
+      case IdField.INT8:
+        return 'Int8';
+      case IdField.STRING:
+        return 'string';
+      default:
+        return 'string';
+    }
   }
 
   gqlTypeName() {
-    return this.kind === IdField.BYTES ? 'Bytes' : 'String';
+    switch (this.kind) {
+      case IdField.BYTES:
+        return 'Bytes';
+      case IdField.INT8:
+        return 'Int8';
+      case IdField.STRING:
+        return 'String';
+      default:
+        return 'String';
+    }
   }
 
   tsNamedType() {
@@ -43,19 +75,55 @@ class IdField {
   }
 
   tsValueFrom() {
-    return this.kind === IdField.BYTES ? 'Value.fromBytes(id)' : 'Value.fromString(id)';
+    switch (this.kind) {
+      case IdField.BYTES:
+        return 'Value.fromBytes(id)';
+      case IdField.INT8:
+        return 'Value.fromI64(id)';
+      case IdField.STRING:
+        return 'Value.fromString(id)';
+      default:
+        return 'Value.fromString(id)';
+    }
   }
 
   tsValueKind() {
-    return this.kind === IdField.BYTES ? 'ValueKind.BYTES' : 'ValueKind.STRING';
+    switch (this.kind) {
+      case IdField.BYTES:
+        return 'ValueKind.BYTES';
+      case IdField.INT8:
+        return 'ValueKind.INT8';
+      case IdField.STRING:
+        return 'ValueKind.STRING';
+      default:
+        return 'ValueKind.STRING';
+    }
   }
 
   tsValueToString() {
-    return this.kind == IdField.BYTES ? 'id.toBytes().toHexString()' : 'id.toString()';
+    switch (this.kind) {
+      case IdField.BYTES:
+        return 'id.toBytes().toHexString()';
+      case IdField.INT8:
+        return 'id.toI64().toString()';
+      case IdField.STRING:
+        return 'id.toString()';
+      default:
+        return 'id.toString()';
+    }
   }
 
   tsToString() {
-    return this.kind == IdField.BYTES ? 'id.toHexString()' : 'id';
+    switch (this.kind) {
+      case IdField.BYTES:
+        return 'id.toHexString()';
+      case IdField.INT8:
+        return 'id.toString()';
+      case IdField.STRING:
+        return 'id';
+      default:
+        return 'id';
+    }
   }
 
   static fromFields(fields: readonly FieldDefinitionNode[] | undefined) {
@@ -92,6 +160,7 @@ export default class SchemaCodeGenerator {
           'Bytes',
           'BigInt',
           'BigDecimal',
+          'Int8',
         ],
         '@graphprotocol/graph-ts',
       ),
diff --git a/packages/cli/src/protocols/ethereum/scaffold/manifest.ts b/packages/cli/src/protocols/ethereum/scaffold/manifest.ts
index 5bfa7d02..e49bc942 100644
--- a/packages/cli/src/protocols/ethereum/scaffold/manifest.ts
+++ b/packages/cli/src/protocols/ethereum/scaffold/manifest.ts
@@ -22,7 +22,7 @@ export const source = ({
 
 export const mapping = ({ abi, contractName }: { abi: ABI; contractName: string }) => `
       kind: ethereum/events
-      apiVersion: 0.0.7
+      apiVersion: 0.0.9
       language: wasm/assemblyscript
       entities:
         ${abiEvents(abi)
diff --git a/packages/cli/src/protocols/subgraph/scaffold/manifest.ts b/packages/cli/src/protocols/subgraph/scaffold/manifest.ts
index 32e4eaad..1acf8f76 100644
--- a/packages/cli/src/protocols/subgraph/scaffold/manifest.ts
+++ b/packages/cli/src/protocols/subgraph/scaffold/manifest.ts
@@ -20,7 +20,7 @@ export const mapping = ({
   contractName: string;
 }) => `
       kind: ethereum/events
-      apiVersion: 0.0.7
+      apiVersion: 0.0.9
       language: wasm/assemblyscript
       entities:
        - ExampleEntity
diff --git a/packages/cli/src/scaffold/index.ts b/packages/cli/src/scaffold/index.ts
index d80c780c..2b9ae634 100644
--- a/packages/cli/src/scaffold/index.ts
+++ b/packages/cli/src/scaffold/index.ts
@@ -20,7 +20,7 @@ const GRAPH_CLI_VERSION = process.env.GRAPH_CLI_TESTS
     undefined
   : // For scaffolding real subgraphs
     version;
-const GRAPH_TS_VERSION = '0.36.0';
+const GRAPH_TS_VERSION = '0.37.0';
 const GRAPH_MATCHSTICK_VERSION = '0.6.0';
 
 export interface ScaffoldOptions {
@@ -141,7 +141,7 @@ export default class Scaffold {
 
     return await prettier.format(
       `
-specVersion: 1.0.0
+specVersion: 1.2.0
 indexerHints:
   prune: auto
 schema:
diff --git a/packages/cli/src/scaffold/schema.ts b/packages/cli/src/scaffold/schema.ts
index e3b00b9b..9f66b506 100644
--- a/packages/cli/src/scaffold/schema.ts
+++ b/packages/cli/src/scaffold/schema.ts
@@ -89,11 +89,10 @@ export const generateExampleEntityType = (protocol: Protocol, events: any[]) =>
   id: Bytes!
   count: BigInt!
   ${events[0].inputs
-    .reduce(
-      (acc: any[], input: any, index: number) =>
-        acc.concat(generateEventFields({ input, index, protocolName: protocol.name })),
-      [],
-    )
+    .reduce((acc: any[], input: any, index: number) => {
+      input.name = renameNameIfNeeded(input.name);
+      return acc.concat(generateEventFields({ input, index, protocolName: protocol.name }));
+    }, [])
     .slice(0, 2)
     .join('\n')}
 }`;
diff --git a/packages/ts/CHANGELOG.md b/packages/ts/CHANGELOG.md
index 5d90888a..5f964d3c 100644
--- a/packages/ts/CHANGELOG.md
+++ b/packages/ts/CHANGELOG.md
@@ -1,5 +1,11 @@
 # @graphprotocol/graph-ts
 
+## 0.38.0
+
+### Minor Changes
+
+- [#1935](https://github.com/graphprotocol/graph-tooling/pull/1935) [`0c36a02`](https://github.com/graphprotocol/graph-tooling/commit/0c36a024e0516bbf883ae62b8312dba3d9945f04) Thanks [@isum](https://github.com/isum)! - feat: add yaml parsing support to mappings
+
 ## 0.37.0
 
 ### Minor Changes
diff --git a/packages/ts/common/value.ts b/packages/ts/common/value.ts
index ce2a576e..8f7a2959 100644
--- a/packages/ts/common/value.ts
+++ b/packages/ts/common/value.ts
@@ -339,6 +339,14 @@ export class Value {
     return Value.fromArray(output);
   }
 
+  static fromI64Array(input: Array<i64>): Value {
+    const output = new Array<Value>(input.length);
+    for (let i: i64 = 0; i < input.length; i++) {
+      output[i] = Value.fromI64(input[i]);
+    }
+    return Value.fromArray(output);
+  }
+
   static fromBigIntArray(input: Array<BigInt>): Value {
     const output = new Array<Value>(input.length);
     for (let i: i32 = 0; i < input.length; i++) {
diff --git a/packages/ts/package.json b/packages/ts/package.json
index 2750dee4..8a0575ff 100644
--- a/packages/ts/package.json
+++ b/packages/ts/package.json
@@ -1,6 +1,6 @@
 {
   "name": "@graphprotocol/graph-ts",
-  "version": "0.37.0",
+  "version": "0.38.0",
   "description": "TypeScript/AssemblyScript library for writing subgraph mappings for The Graph",
   "repository": {
     "type": "git",


Test patch:
diff --git a/packages/cli/src/codegen/schema.test.ts b/packages/cli/src/codegen/schema.test.ts
index cbf3002c..fd1da33f 100644
--- a/packages/cli/src/codegen/schema.test.ts
+++ b/packages/cli/src/codegen/schema.test.ts
@@ -583,6 +583,134 @@ describe('Schema code generator', { concurrent: true }, () => {
     });
   });
 
+  test('Should handle references with Int8 id types', async () => {
+    const codegen = createSchemaCodeGen(`
+    interface Employee {
+      id: Int8!
+      name: String!
+     }
+
+    type Worker implements Employee @entity {
+      id: Int8!
+      name: String!
+      tasks: [Task!]
+   }
+
+    type Task @entity {
+      id: Int8!
+      employee: Employee!
+      workers: [Worker!] @derivedFrom(field: "tasks")
+      worker: Worker!
+   }
+`);
+
+    const generatedTypes = codegen.generateTypes();
+    await testEntity(generatedTypes, {
+      name: 'Task',
+      members: [],
+      methods: [
+        {
+          name: 'constructor',
+          params: [new Param('id', new NamedType('Int8'))],
+          returnType: undefined,
+          body: "\n      super()\n      this.set('id', Value.fromI64(id))\n      ",
+        },
+        {
+          name: 'save',
+          params: [],
+          returnType: new NamedType('void'),
+          body:
+            '\n' +
+            "        let id = this.get('id')\n" +
+            '        assert(id != null,\n' +
+            "               'Cannot save Task entity without an ID')\n" +
+            '        if (id) {\n' +
+            '          assert(id.kind == ValueKind.INT8,\n' +
+            "                 `Entities of type Task must have an ID of type Int8 but the id '${id.displayData()}' is of type ${id.displayKind()}`)\n" +
+            "          store.set('Task', id.toI64().toString(), this)\n" +
+            '        }',
+        },
+        {
+          name: 'loadInBlock',
+          static: true,
+          params: [new Param('id', new NamedType('Int8'))],
+          returnType: new NullableType(new NamedType('Task')),
+          body:
+            '\n' +
+            "        return changetype<Task | null>(store.get_in_block('Task', id.toString()))\n" +
+            '        ',
+        },
+        {
+          name: 'load',
+          static: true,
+          params: [new Param('id', new NamedType('Int8'))],
+          returnType: new NullableType(new NamedType('Task')),
+          body:
+            '\n' +
+            "        return changetype<Task | null>(store.get('Task', id.toString()))\n" +
+            '        ',
+        },
+        {
+          name: 'get id',
+          params: [],
+          returnType: new NamedType('i64'),
+          body: `let value = this.get("id")
+            if (!value || value.kind == ValueKind.NULL) {
+               return 0;
+             } else {
+               return value.toI64()
+             }`,
+        },
+        {
+          name: 'set id',
+          params: [new Param('value', new NamedType('i64'))],
+          returnType: undefined,
+          body: "\n      this.set('id', Value.fromI64(value))\n    ",
+        },
+        {
+          name: 'get employee',
+          params: [],
+          returnType: new NamedType('i64'),
+          body: `let value = this.get('employee')
+            if (!value || value.kind == ValueKind.NULL) {
+              return 0;
+            } else {
+              return value.toI64()
+            }`,
+        },
+        {
+          name: 'set employee',
+          params: [new Param('value', new NamedType('i64'))],
+          returnType: undefined,
+          body: "\n      this.set('employee', Value.fromI64(value))\n    ",
+        },
+        {
+          name: 'get worker',
+          params: [],
+          returnType: new NamedType('i64'),
+          body: `let value = this.get('worker')
+          if (!value || value.kind == ValueKind.NULL) {
+            return 0;
+          } else {
+            return value.toI64()
+          }`,
+        },
+        {
+          name: 'set worker',
+          params: [new Param('value', new NamedType('i64'))],
+          returnType: undefined,
+          body: "\n      this.set('worker', Value.fromI64(value))\n    ",
+        },
+        {
+          name: 'get workers',
+          params: [],
+          returnType: new NamedType('WorkerLoader'),
+          body: "\n      return new WorkerLoader('Task', this.get('id')!.toString(), 'workers')\n    ",
+        },
+      ],
+    });
+  });
+
   test('get related method for WithBytes entity', async () => {
     const codegen = createSchemaCodeGen(`
       type WithBytes @entity {
diff --git a/packages/cli/src/scaffold/__snapshots__/cosmos.test.ts.snap b/packages/cli/src/scaffold/__snapshots__/cosmos.test.ts.snap
index f9e5d47a..53189f25 100644
--- a/packages/cli/src/scaffold/__snapshots__/cosmos.test.ts.snap
+++ b/packages/cli/src/scaffold/__snapshots__/cosmos.test.ts.snap
@@ -1,7 +1,7 @@
 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
 exports[`Cosmos subgraph scaffolding > Manifest 1`] = `
-"specVersion: 1.0.0
+"specVersion: 1.2.0
 indexerHints:
   prune: auto
 schema:
diff --git a/packages/cli/src/scaffold/__snapshots__/ethereum.test.ts.snap b/packages/cli/src/scaffold/__snapshots__/ethereum.test.ts.snap
index b76a3860..5bc28e0f 100644
--- a/packages/cli/src/scaffold/__snapshots__/ethereum.test.ts.snap
+++ b/packages/cli/src/scaffold/__snapshots__/ethereum.test.ts.snap
@@ -1,7 +1,7 @@
 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
 exports[`Ethereum subgraph scaffolding > Manifest 1`] = `
-"specVersion: 1.0.0
+"specVersion: 1.2.0
 indexerHints:
   prune: auto
 schema:
@@ -16,7 +16,7 @@ dataSources:
       startBlock: 12345
     mapping:
       kind: ethereum/events
-      apiVersion: 0.0.7
+      apiVersion: 0.0.9
       language: wasm/assemblyscript
       entities:
         - ExampleEvent
diff --git a/packages/cli/src/scaffold/__snapshots__/near.test.ts.snap b/packages/cli/src/scaffold/__snapshots__/near.test.ts.snap
index d5fb1f80..60867ffa 100644
--- a/packages/cli/src/scaffold/__snapshots__/near.test.ts.snap
+++ b/packages/cli/src/scaffold/__snapshots__/near.test.ts.snap
@@ -1,7 +1,7 @@
 // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
 
 exports[`NEAR subgraph scaffolding > Manifest 1`] = `
-"specVersion: 1.0.0
+"specVersion: 1.2.0
 indexerHints:
   prune: auto
 schema:
diff --git a/packages/cli/tests/cli/add/expected/subgraph.yaml b/packages/cli/tests/cli/add/expected/subgraph.yaml
index 5756ec28..a0782a9c 100644
--- a/packages/cli/tests/cli/add/expected/subgraph.yaml
+++ b/packages/cli/tests/cli/add/expected/subgraph.yaml
@@ -35,7 +35,7 @@ dataSources:
       startBlock: 6175244
     mapping:
       kind: ethereum/events
-      apiVersion: 0.0.7
+      apiVersion: 0.0.9
       language: wasm/assemblyscript
       entities:
         - GravatarNewGravatar