diff --git a/index.ts b/index.ts index 4225690..b9e56ab 100644 --- a/index.ts +++ b/index.ts @@ -107,7 +107,7 @@ export async function action(options: CSVRunOptions ) { for ( const entityChange of EntityChanges.parse(data).entityChanges ) { const writer = writers.get(entityChange.entity); const table = tables.get(entityChange.entity); - if ( !writer || !table ) throw new Error(`Table not found: ${entityChange.entity}`); + if ( !writer || !table ) continue; // skip if table not found const values = getValuesInEntityChange(entityChange); applyReservedFields(values, entityChange, cursor, clock); diff --git a/package-lock.json b/package-lock.json index c5b72b8..12d3be1 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,14 +1,14 @@ { "name": "substreams-sink-csv", - "version": "0.2.9", + "version": "0.2.10", "lockfileVersion": 3, "requires": true, "packages": { "": { "name": "substreams-sink-csv", - "version": "0.2.9", + "version": "0.2.10", "dependencies": { - "@substreams/sink-entity-changes": "^0.3.9", + "@substreams/sink-entity-changes": "^0.3.11", "log-update": "latest", "substreams-sink": "^0.16.0" }, @@ -248,9 +248,9 @@ } }, "node_modules/@substreams/sink-entity-changes": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/@substreams/sink-entity-changes/-/sink-entity-changes-0.3.9.tgz", - "integrity": "sha512-mOKyDlcyTXByj1le0eQwSQb9SXyyzt6T/XY8jJY7L0TBmukYzUa0nE24pJih3MqoyNAoS/swgL77MZeg+sRosw==", + "version": "0.3.11", + "resolved": "https://registry.npmjs.org/@substreams/sink-entity-changes/-/sink-entity-changes-0.3.11.tgz", + "integrity": "sha512-flWn/IiZE5luQDloUCoy9MzIoptQPj416GA0V6sowcFy9mgii2y5hCv/Ck3VlZqW0zPWuNml2DI+SZUTCSvJBw==", "dependencies": { "@bufbuild/protobuf": "latest", "@sinclair/typebox": "latest", diff --git a/package.json b/package.json index 90ee1e4..3da77b1 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "0.2.10", + "version": "0.2.11", "name": "substreams-sink-csv", "description": "Substreams Sink CSV", "type": "module", @@ -24,7 +24,7 @@ "prepublishOnly": "tsc" }, "dependencies": { - "@substreams/sink-entity-changes": "^0.3.9", + "@substreams/sink-entity-changes": "^0.3.11", "log-update": "latest", "substreams-sink": "^0.16.0" }, diff --git a/schema.example.blobs.sql b/schema.example.blobs.sql new file mode 100644 index 0000000..5c249dc --- /dev/null +++ b/schema.example.blobs.sql @@ -0,0 +1,23 @@ +CREATE TABLE Blob +( + id TEXT, + slot TEXT, + index TEXT, + blob TEXT, + kzg_commitment TEXT, + kzg_proof TEXT, + kzg_commitment_inclusion_proof TEXT[], +); + +CREATE TABLE Slot +( + id TEXT, + number BIGINT, + spec TEXT, + proposer_index INT, + parent_root TEXT, + state_root TEXT, + body_root TEXT, + signature TEXT, + timestamp TEXT, +); diff --git a/schema.example.sql b/schema.example.block_meta.sql similarity index 100% rename from schema.example.sql rename to schema.example.block_meta.sql diff --git a/src/getModuleHash.ts b/src/getModuleHash.ts index 342fc99..923788a 100644 --- a/src/getModuleHash.ts +++ b/src/getModuleHash.ts @@ -17,7 +17,7 @@ export async function getModuleHash(options: CSVRunOptions) { for ( const module of substreamPackage.modules.modules ) { if ( module.name === options.moduleName ) { if ( !module.output ) throw new Error("Module has no output"); - if ( module.output.type !== "proto:sf.substreams.sink.entity.v1.EntityChanges" ) throw new Error("Module output is not EntityChanges"); + if ( !module.output.type.includes("entity.v1.EntityChanges") ) throw new Error("Module output is not EntityChanges"); valid = true; } } diff --git a/src/writeRow.spec.ts b/src/writeRow.spec.ts index acaf1e8..183602e 100644 --- a/src/writeRow.spec.ts +++ b/src/writeRow.spec.ts @@ -3,12 +3,20 @@ import { formatValue } from "./writeRow.js"; test("formatValue", () => { const options = {delimiter: ","}; - // expect(formatValue("a", options)).toBe("a"); + expect(formatValue("a", options)).toBe("a"); expect(formatValue("'a'", options)).toBe("'a'"); expect(formatValue("foo bar", options)).toBe("foo bar"); expect(formatValue("foo \" bar", options)).toBe("foo \"\" bar"); expect(formatValue(undefined, options)).toBe(""); expect(formatValue(null, options)).toBe(""); + expect(formatValue("0", options)).toBe("0"); expect(formatValue("a,b", options)).toBe("\"a,b\""); expect(formatValue("a,\"b", options)).toBe("\"a,\"\"b\""); + + // Array + expect(formatValue(["ab", "cd"], options)).toBe("\"[\"\"ab\"\",\"\"cd\"\"]\""); }) + +test.skip("formatValue - recursive array", () => { + // https://github.com/substreams-js/substreams-sink-entity-changes/issues/5 +}); \ No newline at end of file diff --git a/src/writeRow.ts b/src/writeRow.ts index 0c641df..530e9d7 100644 --- a/src/writeRow.ts +++ b/src/writeRow.ts @@ -9,9 +9,13 @@ export function writeRow(writer: fs.WriteStream, columns: any[], options: WriteR writer.write(columns.join(options.delimiter) + '\n'); } -export function formatValue(value: string|undefined|null, options: WriteRowOptions): string { +export function formatValue(value: string|undefined|null|object, options: WriteRowOptions): string { if (value === undefined || value === null) return ""; + if (typeof value == "object") { + value = JSON.stringify(value); + } + if (typeof value == "string") { value = value.replace(/"/g, "\"\"") if ( value.includes(options.delimiter) ) value = `"${value}"`; // escape commas diff --git a/version.ts b/version.ts index 5b6ec32..884009d 100644 --- a/version.ts +++ b/version.ts @@ -1 +1 @@ -export const version = "0.2.10"; \ No newline at end of file +export const version = "0.2.11"; \ No newline at end of file