Skip to content

Commit

Permalink
fix(store,world): minor config validation fixes (#2517)
Browse files Browse the repository at this point in the history
  • Loading branch information
alvrs committed Mar 21, 2024
1 parent 1f952c3 commit 4a6b459
Show file tree
Hide file tree
Showing 13 changed files with 89 additions and 20 deletions.
10 changes: 10 additions & 0 deletions .changeset/dry-toes-lay.md
@@ -0,0 +1,10 @@
---
"@latticexyz/store": patch
"@latticexyz/world": patch
---

Minor fixes to config input validations:

- `systems.openAccess` incorrectly expected `true` as the only valid input. It now allows `boolean`.
- The config complained if parts of it were defined `as const` outside the config input. This is now possible.
- Shorthand inputs are now enabled.
2 changes: 1 addition & 1 deletion packages/store/package.json
Expand Up @@ -59,7 +59,7 @@
"test:ci": "pnpm run test"
},
"dependencies": {
"@arktype/util": "0.0.25",
"@arktype/util": "0.0.27",
"@latticexyz/common": "workspace:*",
"@latticexyz/config": "workspace:*",
"@latticexyz/protocol-parser": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/store/ts/config/v2/input.ts
Expand Up @@ -38,7 +38,7 @@ export type StoreInput = {
export type TableShorthandInput = SchemaInput | string;

export type TablesWithShorthandsInput = {
[key: string]: TableInput | TableShorthandInput;
readonly [key: string]: TableInput | TableShorthandInput;
};

export type StoreWithShorthandsInput = Omit<StoreInput, "tables"> & { tables: TablesWithShorthandsInput };
21 changes: 21 additions & 0 deletions packages/store/ts/config/v2/store.test.ts
Expand Up @@ -495,4 +495,25 @@ describe("defineStore", () => {
}),
).throwsAndHasTypeError("Overrides of `name` and `namespace` are not allowed for tables in a store config");
});

it("should allow const enum as input", () => {
const enums = {
Example: ["First", "Second"],
} as const;

attest(defineStore({ enums }).enums).equals(enums);
});

it("should allow a const config as input", () => {
const config = {
tables: {
Example: {
schema: { id: "address", name: "string", age: "uint256" },
key: ["age"],
},
},
} as const;

defineStore(config);
});
});
10 changes: 5 additions & 5 deletions packages/store/ts/config/v2/table.test.ts
Expand Up @@ -9,7 +9,7 @@ import { getKeySchema, getValueSchema } from "@latticexyz/protocol-parser/intern
describe("validateKeys", () => {
it("should return a tuple of valid keys", () => {
attest<
["static"],
readonly ["static"],
validateKeys<getStaticAbiTypeKeys<{ static: "uint256"; dynamic: "string" }, AbiTypeScope>, ["static"]>
>();
});
Expand All @@ -18,7 +18,7 @@ describe("validateKeys", () => {
const scope = extendScope(AbiTypeScope, { static: "address", dynamic: "string" });

attest<
["static", "customStatic"],
readonly ["static", "customStatic"],
validateKeys<
getStaticAbiTypeKeys<
{ static: "uint256"; dynamic: "string"; customStatic: "static"; customDynamic: "dynamic" },
Expand All @@ -33,7 +33,7 @@ describe("validateKeys", () => {
const scope = extendScope(AbiTypeScope, { static: "address", dynamic: "string" });

attest<
["static", "customStatic"],
readonly ["static", "customStatic"],
validateKeys<
getStaticAbiTypeKeys<
{ static: "uint256"; dynamic: "string"; customStatic: "static"; customDynamic: "dynamic" },
Expand Down Expand Up @@ -218,13 +218,13 @@ describe("resolveTable", () => {
attest(() =>
defineTable({
schema: { id: "address" },
// @ts-expect-error Type 'string' is not assignable to type 'string[]'
// @ts-expect-error Type 'string' is not assignable to type 'readonly string[]'
key: "",
name: "",
}),
)
.throws('Invalid key. Expected `("id")[]`, received ``')
.type.errors("Type 'string' is not assignable to type 'string[]'");
.type.errors("Type 'string' is not assignable to type 'readonly string[]'");
});

it("should throw if a string is provided as schema", () => {
Expand Down
6 changes: 3 additions & 3 deletions packages/store/ts/config/v2/table.ts
Expand Up @@ -37,11 +37,11 @@ export function isValidPrimaryKey<schema extends SchemaInput, scope extends Scop
);
}

export type validateKeys<validKeys extends PropertyKey, keys> = keys extends string[]
export type validateKeys<validKeys extends PropertyKey, keys> = keys extends readonly string[]
? {
[i in keyof keys]: keys[i] extends validKeys ? keys[i] : validKeys;
readonly [i in keyof keys]: keys[i] extends validKeys ? keys[i] : validKeys;
}
: string[];
: readonly string[];

export type ValidateTableOptions = { inStoreContext: boolean };

Expand Down
2 changes: 1 addition & 1 deletion packages/store/ts/exports/index.ts
Expand Up @@ -16,5 +16,5 @@ export {
export { storeEventsAbi } from "../storeEventsAbi";
export type { StoreEventsAbi, StoreEventsAbiItem } from "../storeEventsAbi";

export { defineStore } from "../config/v2/store";
export { defineStoreWithShorthands as defineStore } from "../config/v2/storeWithShorthands";
export type { Store } from "../config/v2/output";
2 changes: 1 addition & 1 deletion packages/world/package.json
Expand Up @@ -54,7 +54,7 @@
"test:ci": "pnpm run test"
},
"dependencies": {
"@arktype/util": "0.0.25",
"@arktype/util": "0.0.27",
"@latticexyz/common": "workspace:*",
"@latticexyz/config": "workspace:*",
"@latticexyz/schema-type": "workspace:*",
Expand Down
2 changes: 1 addition & 1 deletion packages/world/ts/config/v2/input.ts
Expand Up @@ -14,7 +14,7 @@ export type SystemInput = {
*/
registerFunctionSelectors?: boolean;
/** If openAccess is true, any address can call the system */
openAccess?: true;
openAccess?: boolean;
/** An array of addresses or system names that can access the system */
accessList?: string[];
};
Expand Down
25 changes: 25 additions & 0 deletions packages/world/ts/config/v2/world.test.ts
Expand Up @@ -727,4 +727,29 @@ describe("defineWorld", () => {
}),
).type.errors("Namespaces config will be enabled soon.");
});

it("should allow setting openAccess of a system to false", () => {
const config = defineWorld({
systems: {
Example: {
openAccess: false,
},
},
});

attest<false>(config.systems.Example.openAccess).equals(false);
});

it("should allow a const config as input", () => {
const config = {
tables: {
Example: {
schema: { id: "address", name: "string", age: "uint256" },
key: ["age"],
},
},
} as const;

defineWorld(config);
});
});
13 changes: 13 additions & 0 deletions packages/world/ts/config/v2/worldWithShorthands.test.ts
Expand Up @@ -321,4 +321,17 @@ describe("defineWorldWithShorthands", () => {
"Invalid schema. Expected an `id` field with a static ABI type or an explicit `key` option.",
);
});

it("should allow a const config as input", () => {
const config = {
tables: {
Example: {
schema: { id: "address", name: "string", age: "uint256" },
key: ["age"],
},
},
} as const;

defineWorldWithShorthands(config);
});
});
2 changes: 1 addition & 1 deletion packages/world/ts/exports/index.ts
Expand Up @@ -6,5 +6,5 @@

export { helloWorldEvent, worldDeployedEvent } from "../worldEvents";

export { defineWorld } from "../config/v2/world";
export { defineWorldWithShorthands as defineWorld } from "../config/v2/worldWithShorthands";
export type { World } from "../config/v2/output";
12 changes: 6 additions & 6 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 4a6b459

Please sign in to comment.