From afde0de9946cc919cd29659b00935380b7bae052 Mon Sep 17 00:00:00 2001 From: Kevin Ingersoll Date: Fri, 5 Jul 2024 13:51:16 +0100 Subject: [PATCH] fix name type, add more tests --- packages/store/ts/config/v2/table.test.ts | 50 ++++++++++++++++++++++- packages/store/ts/config/v2/table.ts | 12 +++++- 2 files changed, 59 insertions(+), 3 deletions(-) diff --git a/packages/store/ts/config/v2/table.test.ts b/packages/store/ts/config/v2/table.test.ts index a3f41ab404..50fad14a39 100644 --- a/packages/store/ts/config/v2/table.test.ts +++ b/packages/store/ts/config/v2/table.test.ts @@ -141,6 +141,32 @@ describe("resolveTable", () => { attest(table.deploy).equals(expected); }); + it("should truncate label to form name", () => { + const table = defineTable({ + schema: { id: "address", name: "string", age: "uint256" }, + key: ["age"], + label: "ThisIsALongTableName", + }); + + const expected = { + tableId: resourceToHex({ type: "table", namespace: "", name: "ThisIsALongTable" }), + schema: { + id: { type: "address", internalType: "address" }, + name: { type: "string", internalType: "string" }, + age: { type: "uint256", internalType: "uint256" }, + }, + key: ["age"], + label: "ThisIsALongTableName", + name: "ThisIsALongTable", + namespace: "", + codegen: { ...TABLE_CODEGEN_DEFAULTS, dataStruct: true as boolean }, + type: "table", + deploy: TABLE_DEPLOY_DEFAULTS, + } as const; + + attest(table).equals(expected); + }); + it("should throw if the provided key is a dynamic ABI type", () => { attest(() => defineTable({ @@ -252,7 +278,29 @@ describe("resolveTable", () => { // @ts-expect-error Key `keySchema` does not exist in TableInput keySchema: { id: "address" }, }), - ).type.errors("Key `keySchema` does not exist in TableInput "); + ).type.errors("Key `keySchema` does not exist in TableInput"); + }); + + it("should throw if an invalid namespace is provided", () => { + attest(() => + defineTable({ + schema: { id: "address" }, + key: ["id"], + label: "", + namespace: "ThisNamespaceIsTooLong", + }), + ).throws('Table `namespace` must fit into a `bytes14`, but "ThisNamespaceIsTooLong" is too long.'); + }); + + it("should throw if an invalid name is provided", () => { + attest(() => + defineTable({ + schema: { id: "address" }, + key: ["id"], + label: "", + name: "ThisNameIsTooLong", + }), + ).throws('Table `name` must fit into a `bytes16`, but "ThisNameIsTooLong" is too long.'); }); }); diff --git a/packages/store/ts/config/v2/table.ts b/packages/store/ts/config/v2/table.ts index 15a2830e4a..3a1e18dabd 100644 --- a/packages/store/ts/config/v2/table.ts +++ b/packages/store/ts/config/v2/table.ts @@ -136,12 +136,20 @@ export function resolveTableCodegen(input: input): res } satisfies TableCodegen as never; } +// TODO: is this helper worth it for the strongly typed substring? +// https://stackoverflow.com/a/66218917 +type truncate< + T extends string, + N extends number, + L extends unknown[] = [], + A extends string = "", +> = N extends L["length"] ? A : T extends `${infer F}${infer R}` ? truncate : A; + export type resolveTable = input extends TableInput ? { readonly tableId: Hex; readonly label: input["label"]; - // TODO: return `string` instead of label, since we can't truncate label in TS - readonly name: undefined extends input["name"] ? input["label"] : input["name"]; + readonly name: undefined extends input["name"] ? truncate : input["name"]; readonly namespace: undefined extends input["namespace"] ? typeof TABLE_DEFAULTS.namespace : input["namespace"]; readonly type: undefined extends input["type"] ? typeof TABLE_DEFAULTS.type : input["type"]; readonly key: Readonly;