Prechádzať zdrojové kódy

Upgrade ESLint to v9 (#334)

* Upgrade to Eslint 9

* Fix new linting errors

* Adjust configs

* Use tseslint.config helper

* Update eslint.config.mjs

* Update turbo.json

* Enable @typescript-eslint/no-unsafe-return

* Enable @typescript-eslint/unbound-method

* Enable @typescript-eslint/no-base-to-string

* Enable @typescript-eslint/no-unsafe-argument

* Enable @typescript-eslint/no-unsafe-assignment

* Enable @typescript-eslint/no-unsafe-call

* Enable @typescript-eslint/no-unsafe-enum-comparison

* Enable @typescript-eslint/no-unsafe-member-access

* Enable @typescript-eslint/only-throw-error

* Enable @typescript-eslint/prefer-promise-reject-errors

* Enable @typescript-eslint/restrict-plus-operands

* Enable @typescript-eslint/restrict-template-expressions

* Update index.ts

* Add changeset

* Try disabling new rules again for CI

Despite it working locally... :sob:

* Revert "Try disabling new rules again for CI"

This reverts commit 88bab9e6072c52c5334b76486082277b87cb46ec.

* Fix @typescript-eslint/no-unused-vars

* Update tsconfig.json

* Build before lint in CI

* Update tsconfig.json

* Simplify script
Loris Leiva 11 mesiacov pred
rodič
commit
2622727abf
40 zmenil súbory, kde vykonal 713 pridanie a 259 odobranie
  1. 13 0
      .changeset/rich-pans-cough.md
  2. 0 5
      .eslintrc.js
  3. 3 0
      .github/workflows/main.yml
  4. 17 0
      eslint.config.mjs
  5. 8 7
      package.json
  6. 1 1
      packages/dynamic-codecs/src/codecs.ts
  7. 1 1
      packages/dynamic-codecs/src/values.ts
  8. 0 1
      packages/dynamic-parsers/src/parsers.ts
  9. 2 2
      packages/errors/src/cli.ts
  10. 30 31
      packages/errors/src/codes.ts
  11. 1 1
      packages/errors/src/message-formatter.ts
  12. 1 1
      packages/errors/test/error.typetest.ts
  13. 2 2
      packages/internals/scripts/lint.mjs
  14. 0 6
      packages/node-types/.eslintrc.cjs
  15. 1 1
      packages/nodes-from-anchor/src/index.ts
  16. 2 2
      packages/nodes-from-anchor/src/v00/ProgramNode.ts
  17. 1 2
      packages/nodes-from-anchor/src/v00/idl.ts
  18. 0 1
      packages/nodes-from-anchor/src/v00/typeNodes/EnumTypeNode.ts
  19. 4 12
      packages/nodes-from-anchor/src/v00/typeNodes/TypeNode.ts
  20. 3 6
      packages/nodes-from-anchor/src/v01/typeNodes/TypeNode.ts
  21. 0 6
      packages/nodes/.eslintrc.cjs
  22. 3 3
      packages/renderers-js-umi/src/getTypeManifestVisitor.ts
  23. 1 1
      packages/renderers-js-umi/src/getValidatorBagVisitor.ts
  24. 1 1
      packages/renderers-js-umi/test/_setup.ts
  25. 9 11
      packages/renderers-js/src/fragments/instructionInputDefault.ts
  26. 13 13
      packages/renderers-js/src/getTypeManifestVisitor.ts
  27. 1 1
      packages/renderers-js/test/_setup.ts
  28. 3 3
      packages/renderers-js/test/instructionsPage.test.ts
  29. 3 3
      packages/renderers-js/test/types/remainderOption.test.ts
  30. 6 6
      packages/renderers-js/test/types/zeroableOption.test.ts
  31. 2 2
      packages/renderers-rust/src/renderVisitor.ts
  32. 5 1
      packages/visitors-core/src/NodeStack.ts
  33. 0 1
      packages/visitors-core/src/consoleLogVisitor.ts
  34. 1 1
      packages/visitors-core/src/mergeVisitor.ts
  35. 1 0
      packages/visitors-core/src/pipe.ts
  36. 2 2
      packages/visitors-core/test/topDownTransformerVisitor.test.ts
  37. 1 1
      packages/visitors/src/setInstructionAccountDefaultValuesVisitor.ts
  38. 560 118
      pnpm-lock.yaml
  39. 3 1
      tsconfig.json
  40. 8 2
      turbo.json

+ 13 - 0
.changeset/rich-pans-cough.md

@@ -0,0 +1,13 @@
+---
+'@codama/nodes-from-anchor': patch
+'@codama/renderers-js-umi': patch
+'@codama/dynamic-parsers': patch
+'@codama/dynamic-codecs': patch
+'@codama/renderers-rust': patch
+'@codama/visitors-core': patch
+'@codama/renderers-js': patch
+'@codama/visitors': patch
+'@codama/errors': patch
+---
+
+Bump dependencies

+ 0 - 5
.eslintrc.js

@@ -1,5 +0,0 @@
-module.exports = {
-    extends: ['turbo', '@solana/eslint-config-solana'],
-    root: true,
-    ignorePatterns: ['.eslintrc.js', '.eslintrc.cjs', 'dist/', '*.json', '*.njk'],
-};

+ 3 - 0
.github/workflows/main.yml

@@ -32,6 +32,9 @@ jobs:
       - name: Install dependencies
         run: pnpm install --frozen-lockfile
 
+      - name: Compile JS and types
+        run: pnpm run build
+
       - name: Check linting
         run: pnpm run lint
 

+ 17 - 0
eslint.config.mjs

@@ -0,0 +1,17 @@
+import solanaConfig from '@solana/eslint-config-solana';
+import tseslint from 'typescript-eslint';
+
+export default tseslint.config([
+    {
+        files: ['**/*.ts', '**/*.(c|m)?js'],
+        ignores: ['**/dist/**', '**/e2e/**'],
+        extends: [solanaConfig],
+    },
+    {
+        files: ['packages/nodes/**', 'packages/node-types/**'],
+        rules: {
+            'sort-keys-fix/sort-keys-fix': 'off',
+            'typescript-sort-keys/interface': 'off',
+        },
+    },
+]);

+ 8 - 7
package.json

@@ -15,15 +15,16 @@
         "@changesets/changelog-github": "^0.5.0",
         "@changesets/cli": "^2.27.10",
         "@codama/internals": "workspace:*",
-        "@solana/eslint-config-solana": "^3.0.3",
+        "@eslint/js": "^9.13.0",
+        "@eslint/json": "^0.8.0",
+        "@solana/eslint-config-solana": "^4.0.0",
         "@solana/prettier-config-solana": "0.0.5",
-        "@types/node": "^20",
-        "@typescript-eslint/eslint-plugin": "^6.21.0",
-        "@typescript-eslint/parser": "^6.0.0",
+        "@types/node": "^22",
+        "@typescript-eslint/eslint-plugin": "^8.16.0",
+        "@typescript-eslint/parser": "^8.16.0",
         "agadoo": "^3.0.0",
-        "eslint": "^8.57.1",
-        "eslint-config-turbo": "^2.3.3",
-        "eslint-plugin-simple-import-sort": "^10.0.0",
+        "eslint": "^9.15.0",
+        "eslint-plugin-simple-import-sort": "^12.1.1",
         "eslint-plugin-sort-keys-fix": "^1.1.2",
         "eslint-plugin-typescript-sort-keys": "^3.3.0",
         "happy-dom": "^15.11.7",

+ 1 - 1
packages/dynamic-codecs/src/codecs.ts

@@ -249,7 +249,7 @@ export function getNodeCodecVisitor(
             return transformCodec(
                 getMapCodec(key, value, { size }),
                 (value: object) => new Map(Object.entries(value)),
-                (map: Map<unknown, unknown>): object => Object.fromEntries(map),
+                (map: Map<unknown, unknown>) => Object.fromEntries(map) as object,
             ) as Codec<unknown>;
         },
         visitNumberType(node) {

+ 1 - 1
packages/dynamic-codecs/src/values.ts

@@ -67,7 +67,7 @@ export function getValueNodeVisitor(
                     const value = visit(entry.value, this);
                     return [key, value];
                 }),
-            );
+            ) as unknown;
         },
         visitNoneValue() {
             return { __option: 'None' };

+ 0 - 1
packages/dynamic-parsers/src/parsers.ts

@@ -53,7 +53,6 @@ export function parseInstruction(
 ): ParsedInstruction | undefined {
     const parsedData = parseInstructionData(root, instruction.data);
     if (!parsedData) return undefined;
-    instruction.accounts;
     const instructionNode = getLastNodeFromPath(parsedData.path);
     const accounts: ParsedInstructionAccounts = instructionNode.accounts.flatMap((account, index) => {
         const accountMeta = instruction.accounts[index];

+ 2 - 2
packages/errors/src/cli.ts

@@ -32,11 +32,11 @@ program
     .argument('[encodedContext]', 'encoded context to interpolate into the error message', encodedContext => {
         try {
             return decodeEncodedContext(encodedContext);
-        } catch (e) {
+        } catch {
             throw new InvalidArgumentError('Encoded context malformed');
         }
     })
-    .action((code: number, context) => {
+    .action((code: number, context: object | undefined) => {
         const message = getHumanReadableErrorMessage(code as CodamaErrorCode, context);
         console.log(`
 ${

+ 30 - 31
packages/errors/src/codes.ts

@@ -25,46 +25,45 @@
  *     - `_MISSING`: Some required input is missing. E.g. `TRANSACTION_FEE_PAYER_MISSING`.
  *     - `_UNIMPLEMENTED`: Some required component is not available in the environment. E.g. `SUBTLE_CRYPTO_VERIFY_FUNCTION_UNIMPLEMENTED`.
  */
-export const CODAMA_ERROR__UNRECOGNIZED_NODE_KIND = 1 as const;
-export const CODAMA_ERROR__UNEXPECTED_NODE_KIND = 2 as const;
-export const CODAMA_ERROR__UNEXPECTED_NESTED_NODE_KIND = 3 as const;
-export const CODAMA_ERROR__LINKED_NODE_NOT_FOUND = 4 as const;
-export const CODAMA_ERROR__NODE_FILESYSTEM_FUNCTION_UNAVAILABLE = 5 as const;
-export const CODAMA_ERROR__VERSION_MISMATCH = 6 as const;
-export const CODAMA_ERROR__UNRECOGNIZED_NUMBER_FORMAT = 7 as const;
-export const CODAMA_ERROR__UNRECOGNIZED_BYTES_ENCODING = 8 as const;
-export const CODAMA_ERROR__ENUM_VARIANT_NOT_FOUND = 9 as const;
-export const CODAMA_ERROR__DISCRIMINATOR_FIELD_NOT_FOUND = 10 as const;
-export const CODAMA_ERROR__DISCRIMINATOR_FIELD_HAS_NO_DEFAULT_VALUE = 11 as const;
+export const CODAMA_ERROR__UNRECOGNIZED_NODE_KIND = 1;
+export const CODAMA_ERROR__UNEXPECTED_NODE_KIND = 2;
+export const CODAMA_ERROR__UNEXPECTED_NESTED_NODE_KIND = 3;
+export const CODAMA_ERROR__LINKED_NODE_NOT_FOUND = 4;
+export const CODAMA_ERROR__NODE_FILESYSTEM_FUNCTION_UNAVAILABLE = 5;
+export const CODAMA_ERROR__VERSION_MISMATCH = 6;
+export const CODAMA_ERROR__UNRECOGNIZED_NUMBER_FORMAT = 7;
+export const CODAMA_ERROR__UNRECOGNIZED_BYTES_ENCODING = 8;
+export const CODAMA_ERROR__ENUM_VARIANT_NOT_FOUND = 9;
+export const CODAMA_ERROR__DISCRIMINATOR_FIELD_NOT_FOUND = 10;
+export const CODAMA_ERROR__DISCRIMINATOR_FIELD_HAS_NO_DEFAULT_VALUE = 11;
 
 // Visitors-related errors.
 // Reserve error codes in the range [1200000-1200999].
-export const CODAMA_ERROR__VISITORS__CANNOT_ADD_DUPLICATED_PDA_NAMES = 1200000 as const;
-export const CODAMA_ERROR__VISITORS__INVALID_PDA_SEED_VALUES = 1200001 as const;
-export const CODAMA_ERROR__VISITORS__CYCLIC_DEPENDENCY_DETECTED_WHEN_RESOLVING_INSTRUCTION_DEFAULT_VALUES =
-    1200002 as const;
-export const CODAMA_ERROR__VISITORS__CANNOT_USE_OPTIONAL_ACCOUNT_AS_PDA_SEED_VALUE = 1200003 as const;
-export const CODAMA_ERROR__VISITORS__INVALID_INSTRUCTION_DEFAULT_VALUE_DEPENDENCY = 1200004 as const;
-export const CODAMA_ERROR__VISITORS__ACCOUNT_FIELD_NOT_FOUND = 1200005 as const;
-export const CODAMA_ERROR__VISITORS__INVALID_NUMBER_WRAPPER = 1200006 as const;
-export const CODAMA_ERROR__VISITORS__CANNOT_EXTEND_MISSING_VISIT_FUNCTION = 1200007 as const;
-export const CODAMA_ERROR__VISITORS__FAILED_TO_VALIDATE_NODE = 1200008 as const;
-export const CODAMA_ERROR__VISITORS__INSTRUCTION_ENUM_ARGUMENT_NOT_FOUND = 1200009 as const;
-export const CODAMA_ERROR__VISITORS__CANNOT_FLATTEN_STRUCT_WITH_CONFLICTING_ATTRIBUTES = 1200010 as const;
-export const CODAMA_ERROR__VISITORS__RENDER_MAP_KEY_NOT_FOUND = 1200011 as const;
-export const CODAMA_ERROR__VISITORS__CANNOT_REMOVE_LAST_PATH_IN_NODE_STACK = 1200012 as const;
+export const CODAMA_ERROR__VISITORS__CANNOT_ADD_DUPLICATED_PDA_NAMES = 1200000;
+export const CODAMA_ERROR__VISITORS__INVALID_PDA_SEED_VALUES = 1200001;
+export const CODAMA_ERROR__VISITORS__CYCLIC_DEPENDENCY_DETECTED_WHEN_RESOLVING_INSTRUCTION_DEFAULT_VALUES = 1200002;
+export const CODAMA_ERROR__VISITORS__CANNOT_USE_OPTIONAL_ACCOUNT_AS_PDA_SEED_VALUE = 1200003;
+export const CODAMA_ERROR__VISITORS__INVALID_INSTRUCTION_DEFAULT_VALUE_DEPENDENCY = 1200004;
+export const CODAMA_ERROR__VISITORS__ACCOUNT_FIELD_NOT_FOUND = 1200005;
+export const CODAMA_ERROR__VISITORS__INVALID_NUMBER_WRAPPER = 1200006;
+export const CODAMA_ERROR__VISITORS__CANNOT_EXTEND_MISSING_VISIT_FUNCTION = 1200007;
+export const CODAMA_ERROR__VISITORS__FAILED_TO_VALIDATE_NODE = 1200008;
+export const CODAMA_ERROR__VISITORS__INSTRUCTION_ENUM_ARGUMENT_NOT_FOUND = 1200009;
+export const CODAMA_ERROR__VISITORS__CANNOT_FLATTEN_STRUCT_WITH_CONFLICTING_ATTRIBUTES = 1200010;
+export const CODAMA_ERROR__VISITORS__RENDER_MAP_KEY_NOT_FOUND = 1200011;
+export const CODAMA_ERROR__VISITORS__CANNOT_REMOVE_LAST_PATH_IN_NODE_STACK = 1200012;
 
 // Anchor-related errors.
 // Reserve error codes in the range [2100000-2100999].
-export const CODAMA_ERROR__ANCHOR__UNRECOGNIZED_IDL_TYPE = 2100000 as const;
-export const CODAMA_ERROR__ANCHOR__ACCOUNT_TYPE_MISSING = 2100001 as const;
-export const CODAMA_ERROR__ANCHOR__ARGUMENT_TYPE_MISSING = 2100002 as const;
-export const CODAMA_ERROR__ANCHOR__TYPE_PATH_MISSING = 2100003 as const;
-export const CODAMA_ERROR__ANCHOR__SEED_KIND_UNIMPLEMENTED = 2100004 as const;
+export const CODAMA_ERROR__ANCHOR__UNRECOGNIZED_IDL_TYPE = 2100000;
+export const CODAMA_ERROR__ANCHOR__ACCOUNT_TYPE_MISSING = 2100001;
+export const CODAMA_ERROR__ANCHOR__ARGUMENT_TYPE_MISSING = 2100002;
+export const CODAMA_ERROR__ANCHOR__TYPE_PATH_MISSING = 2100003;
+export const CODAMA_ERROR__ANCHOR__SEED_KIND_UNIMPLEMENTED = 2100004;
 
 // Renderers-related errors.
 // Reserve error codes in the range [2800000-2800999].
-export const CODAMA_ERROR__RENDERERS__UNSUPPORTED_NODE = 2800000 as const;
+export const CODAMA_ERROR__RENDERERS__UNSUPPORTED_NODE = 2800000;
 
 /**
  * A union of every Codama error code

+ 1 - 1
packages/errors/src/message-formatter.ts

@@ -13,7 +13,7 @@ export function getHumanReadableErrorMessage<TErrorCode extends CodamaErrorCode>
 ): string {
     const messageFormatString = CodamaErrorMessages[code];
     const message = messageFormatString.replace(/(?<!\\)\$(\w+)/g, (substring, variableName) =>
-        variableName in context ? `${context[variableName as keyof typeof context]}` : substring,
+        variableName in context ? `${context[variableName as keyof typeof context] as string}` : substring,
     );
     return message;
 }

+ 1 - 1
packages/errors/test/error.typetest.ts

@@ -39,7 +39,7 @@ const unexpectedNodeKindError = new CodamaError(CODAMA_ERROR__UNEXPECTED_NODE_KI
 
 unexpectedNodeKindError.context satisfies CodamaErrorContext[typeof CODAMA_ERROR__UNEXPECTED_NODE_KIND];
 // @ts-expect-error Non existent context property.
-unexpectedNodeKindError.context.feePayer;
+unexpectedNodeKindError.context.feePayer satisfies never;
 
 // @ts-expect-error Missing context.
 new CodamaError(CODAMA_ERROR__UNRECOGNIZED_NODE_KIND);

+ 2 - 2
packages/internals/scripts/lint.mjs

@@ -4,7 +4,7 @@ import { $, argv } from 'zx';
 // Lint and format the code.
 $.stdio = 'inherit';
 if (argv.fix) {
-    await $`pnpm eslint --fix "src/*" "test/*" && pnpm prettier --log-level warn --ignore-unknown --write ./*`;
+    await $`pnpm eslint --fix . && pnpm prettier --log-level warn --ignore-unknown --write ./*`;
 } else {
-    await $`pnpm eslint "src/*" "test/*" && pnpm prettier --check .`;
+    await $`pnpm eslint . && pnpm prettier --check .`;
 }

+ 0 - 6
packages/node-types/.eslintrc.cjs

@@ -1,6 +0,0 @@
-module.exports = {
-    extends: ['../../.eslintrc.js'],
-    rules: {
-        'typescript-sort-keys/interface': 'off',
-    },
-};

+ 1 - 1
packages/nodes-from-anchor/src/index.ts

@@ -16,7 +16,7 @@ export function rootNodeFromAnchor(idl: AnchorIdl): RootNode {
 }
 
 export function rootNodeFromAnchorWithoutDefaultVisitor(idl: AnchorIdl): RootNode {
-    if (idl.metadata?.spec === '0.1.0') {
+    if ((idl.metadata as { spec?: string })?.spec === '0.1.0') {
         return rootNodeFromAnchorV01(idl as IdlV01);
     }
 

+ 2 - 2
packages/nodes-from-anchor/src/v00/ProgramNode.ts

@@ -8,7 +8,7 @@ import { instructionNodeFromAnchorV00 } from './InstructionNode';
 import { pdaNodeFromAnchorV00 } from './PdaNode';
 
 export function programNodeFromAnchorV00(idl: IdlV00): ProgramNode {
-    const origin: 'anchor' | 'shank' = idl.metadata?.origin ?? 'anchor';
+    const origin = (idl.metadata as { origin?: 'anchor' | 'shank' }).origin ?? 'anchor';
     const pdas = (idl.accounts ?? []).filter(account => (account.seeds ?? []).length > 0).map(pdaNodeFromAnchorV00);
     const accounts = (idl.accounts ?? []).map(a => accountNodeFromAnchorV00(a, origin));
     const instructions = (idl.instructions ?? []).map(i => instructionNodeFromAnchorV00(i, origin));
@@ -20,7 +20,7 @@ export function programNodeFromAnchorV00(idl: IdlV00): ProgramNode {
         name: idl.name ?? '',
         origin,
         pdas,
-        publicKey: idl.metadata?.address ?? '',
+        publicKey: (idl.metadata as { address?: string })?.address ?? '',
         version: idl.version as ProgramVersion,
     });
 }

+ 1 - 2
packages/nodes-from-anchor/src/v00/idl.ts

@@ -11,8 +11,7 @@ export type IdlV00 = {
     version: string;
 };
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
-export type IdlV00Metadata = any;
+export type IdlV00Metadata = object;
 
 export type IdlV00Constant = {
     name: string;

+ 0 - 1
packages/nodes-from-anchor/src/v00/typeNodes/EnumTypeNode.ts

@@ -22,7 +22,6 @@ export function enumTypeNodeFromAnchorV00(
     });
 }
 
-// eslint-disable-next-line @typescript-eslint/no-explicit-any
 function isStructVariant(variant: IdlV00EnumVariant): variant is IdlV00EnumVariant & { fields: IdlV00EnumFieldsNamed } {
     const field = variant.fields![0];
     return typeof field === 'object' && 'name' in field && 'type' in field;

+ 4 - 12
packages/nodes-from-anchor/src/v00/typeNodes/TypeNode.ts

@@ -10,15 +10,7 @@ import {
     TypeNode,
 } from '@codama/nodes';
 
-import {
-    IdlV00Type,
-    IdlV00TypeDefTy,
-    IdlV00TypeDefTyEnum,
-    IdlV00TypeDefTyStruct,
-    IdlV00TypeMap,
-    IdlV00TypeSet,
-    IdlV00TypeTuple,
-} from '../idl';
+import { IdlV00Type, IdlV00TypeDefTy, IdlV00TypeMap, IdlV00TypeSet } from '../idl';
 import { arrayTypeNodeFromAnchorV00 } from './ArrayTypeNode';
 import { enumTypeNodeFromAnchorV00 } from './EnumTypeNode';
 import { mapTypeNodeFromAnchorV00 } from './MapTypeNode';
@@ -81,7 +73,7 @@ export const typeNodeFromAnchorV00 = (idlType: IdlV00Type | IdlV00TypeDefTy): Ty
 
     // Enum.
     if ('kind' in idlType && idlType.kind === 'enum' && 'variants' in idlType) {
-        return enumTypeNodeFromAnchorV00(idlType as IdlV00TypeDefTyEnum);
+        return enumTypeNodeFromAnchorV00(idlType);
     }
 
     // Map.
@@ -104,12 +96,12 @@ export const typeNodeFromAnchorV00 = (idlType: IdlV00Type | IdlV00TypeDefTy): Ty
 
     // Struct.
     if ('kind' in idlType && 'fields' in idlType && idlType.kind === 'struct') {
-        return structTypeNodeFromAnchorV00(idlType as IdlV00TypeDefTyStruct);
+        return structTypeNodeFromAnchorV00(idlType);
     }
 
     // Tuple.
     if ('tuple' in idlType && Array.isArray(idlType.tuple)) {
-        return tupleTypeNodeFromAnchorV00(idlType as IdlV00TypeTuple);
+        return tupleTypeNodeFromAnchorV00(idlType);
     }
 
     throw new CodamaError(CODAMA_ERROR__ANCHOR__UNRECOGNIZED_IDL_TYPE, {

+ 3 - 6
packages/nodes-from-anchor/src/v01/typeNodes/TypeNode.ts

@@ -16,10 +16,7 @@ import {
     IdlV01DefinedFieldsTuple,
     IdlV01Field,
     IdlV01Type,
-    IdlV01TypeCOption,
     IdlV01TypeDefTy,
-    IdlV01TypeDefTyEnum,
-    IdlV01TypeOption,
 } from '../idl';
 import { arrayTypeNodeFromAnchorV01 } from './ArrayTypeNode';
 import { enumTypeNodeFromAnchorV01 } from './EnumTypeNode';
@@ -82,16 +79,16 @@ export const typeNodeFromAnchorV01 = (idlType: IdlV01Type | IdlV01TypeDefTy): Ty
 
     // Enum.
     if ('kind' in idlType && idlType.kind === 'enum' && 'variants' in idlType) {
-        return enumTypeNodeFromAnchorV01(idlType as IdlV01TypeDefTyEnum);
+        return enumTypeNodeFromAnchorV01(idlType);
     }
 
     // Option.
     if ('option' in idlType) {
-        return optionTypeNodeFromAnchorV01(idlType as IdlV01TypeOption);
+        return optionTypeNodeFromAnchorV01(idlType);
     }
 
     if ('coption' in idlType) {
-        return optionTypeNodeFromAnchorV01(idlType as IdlV01TypeCOption);
+        return optionTypeNodeFromAnchorV01(idlType);
     }
 
     // Struct and Tuple.

+ 0 - 6
packages/nodes/.eslintrc.cjs

@@ -1,6 +0,0 @@
-module.exports = {
-    extends: ['../../.eslintrc.js'],
-    rules: {
-        'sort-keys-fix/sort-keys-fix': 'off',
-    },
-};

+ 3 - 3
packages/renderers-js-umi/src/getTypeManifestVisitor.ts

@@ -114,7 +114,7 @@ export function getTypeManifestVisitor(input: {
                     if (!isUnsignedInteger(resolvedNode)) {
                         throw new Error(
                             `Amount wrappers can only be applied to unsigned ` +
-                                `integer types. Got type [${amountType.number.toString()}].`,
+                                `integer types. Got format [${resolvedNode.format}].`,
                         );
                     }
                     const { unit, decimals } = amountType;
@@ -251,7 +251,7 @@ export function getTypeManifestVisitor(input: {
                     if (!isInteger(dateTimeNumber)) {
                         throw new Error(
                             `DateTime wrappers can only be applied to integer ` +
-                                `types. Got type [${dateTimeNumber.toString()}].`,
+                                `types. Got format [${dateTimeNumber.format}].`,
                         );
                     }
                     numberManifest.strictImports.add('umi', 'DateTime');
@@ -655,7 +655,7 @@ export function getTypeManifestVisitor(input: {
                     if (!isUnsignedInteger(nestedNumber)) {
                         throw new Error(
                             `Amount wrappers can only be applied to unsigned ` +
-                                `integer types. Got type [${nestedNumber.toString()}].`,
+                                `integer types. Got format [${nestedNumber.format}].`,
                         );
                     }
                     const idAndDecimals = `'SOL', 9`;

+ 1 - 1
packages/renderers-js-umi/src/getValidatorBagVisitor.ts

@@ -44,7 +44,7 @@ export function getValidationItemsVisitor(): Visitor<readonly ValidationItem[]>
                 `The ${getNodeTitle(node)} ${exportDetails}` +
                 `conflicts with the ${conflictExportDetails}` +
                 `${getNodeTitle(conflictingNode)}.\n` +
-                `|> Conflicting stack: ${exportConflict.stack}.`;
+                `|> Conflicting stack: ${exportConflict.stack.toString()}.`;
             items.push(validationItem('error', message, node, stack));
         });
         return items;

+ 1 - 1
packages/renderers-js-umi/test/_setup.ts

@@ -76,7 +76,7 @@ export function codeStringAsRegex(code: string) {
 async function normalizeCode(code: string) {
     try {
         code = await format(code, PRETTIER_OPTIONS);
-    } catch (e) {
+    } catch {
         // Ignore errors.
     }
     return code.trim();

+ 9 - 11
packages/renderers-js/src/fragments/instructionInputDefault.ts

@@ -66,7 +66,7 @@ export function getInstructionInputDefaultFragment(
                 const pdaSeeds = defaultValue.pda.seeds.flatMap((seed): Fragment[] => {
                     if (isNode(seed, 'constantPdaSeedNode') && isNode(seed.value, 'programIdValueNode')) {
                         return [
-                            fragment(`getAddressEncoder().encode(${pdaProgram})`)
+                            fragment(`getAddressEncoder().encode(${pdaProgram.render})`)
                                 .mergeImportsWith(pdaProgram)
                                 .addImports('solanaAddresses', 'getAddressEncoder'),
                         ];
@@ -75,10 +75,9 @@ export function getInstructionInputDefaultFragment(
                         const typeManifest = visit(seed.type, typeManifestVisitor);
                         const valueManifest = visit(seed.value, typeManifestVisitor);
                         return [
-                            fragment(`${typeManifest.encoder}.encode(${valueManifest.value})`).mergeImportsWith(
-                                typeManifest.encoder,
-                                valueManifest.value,
-                            ),
+                            fragment(
+                                `${typeManifest.encoder.render}.encode(${valueManifest.value.render})`,
+                            ).mergeImportsWith(typeManifest.encoder, valueManifest.value),
                         ];
                     }
                     if (isNode(seed, 'variablePdaSeedNode')) {
@@ -88,7 +87,7 @@ export function getInstructionInputDefaultFragment(
                         if (isNode(valueSeed, 'accountValueNode')) {
                             return [
                                 fragment(
-                                    `${typeManifest.encoder}.encode(expectAddress(accounts.${camelCase(valueSeed.name)}.value))`,
+                                    `${typeManifest.encoder.render}.encode(expectAddress(accounts.${camelCase(valueSeed.name)}.value))`,
                                 )
                                     .mergeImportsWith(typeManifest.encoder)
                                     .addImports('shared', 'expectAddress'),
@@ -97,7 +96,7 @@ export function getInstructionInputDefaultFragment(
                         if (isNode(valueSeed, 'argumentValueNode')) {
                             return [
                                 fragment(
-                                    `${typeManifest.encoder}.encode(expectSome(args.${camelCase(valueSeed.name)}))`,
+                                    `${typeManifest.encoder.render}.encode(expectSome(args.${camelCase(valueSeed.name)}))`,
                                 )
                                     .mergeImportsWith(typeManifest.encoder)
                                     .addImports('shared', 'expectSome'),
@@ -105,10 +104,9 @@ export function getInstructionInputDefaultFragment(
                         }
                         const valueManifest = visit(valueSeed, typeManifestVisitor);
                         return [
-                            fragment(`${typeManifest.encoder}.encode(${valueManifest.value})`).mergeImportsWith(
-                                typeManifest.encoder,
-                                valueManifest.value,
-                            ),
+                            fragment(
+                                `${typeManifest.encoder.render}.encode(${valueManifest.value.render})`,
+                            ).mergeImportsWith(typeManifest.encoder, valueManifest.value),
                         ];
                     }
                     return [];

+ 13 - 13
packages/renderers-js/src/getTypeManifestVisitor.ts

@@ -397,18 +397,18 @@ export function getTypeManifestVisitor(input: {
                 visitHiddenPrefixType(node, { self }) {
                     const manifest = visit(node.type, self);
                     const prefixes = node.prefix.map(c => visit(c, self).value);
-                    const prefixEncoders = fragment(prefixes.map(c => `getConstantEncoder(${c})`).join(', '))
+                    const prefixEncoders = fragment(prefixes.map(c => `getConstantEncoder(${c.render})`).join(', '))
                         .addImports('solanaCodecsCore', 'getConstantEncoder')
                         .mergeImportsWith(...prefixes);
-                    const prefixDecoders = fragment(prefixes.map(c => `getConstantDecoder(${c})`).join(', '))
+                    const prefixDecoders = fragment(prefixes.map(c => `getConstantDecoder(${c.render})`).join(', '))
                         .addImports('solanaCodecsCore', 'getConstantDecoder')
                         .mergeImportsWith(...prefixes);
                     manifest.encoder
-                        .mapRender(r => `getHiddenPrefixEncoder(${r}, [${prefixEncoders}])`)
+                        .mapRender(r => `getHiddenPrefixEncoder(${r}, [${prefixEncoders.render}])`)
                         .mergeImportsWith(prefixEncoders)
                         .addImports('solanaCodecsDataStructures', 'getHiddenPrefixEncoder');
                     manifest.decoder
-                        .mapRender(r => `getHiddenPrefixDecoder(${r}, [${prefixDecoders}])`)
+                        .mapRender(r => `getHiddenPrefixDecoder(${r}, [${prefixDecoders.render}])`)
                         .mergeImportsWith(prefixDecoders)
                         .addImports('solanaCodecsDataStructures', 'getHiddenPrefixDecoder');
                     return manifest;
@@ -417,18 +417,18 @@ export function getTypeManifestVisitor(input: {
                 visitHiddenSuffixType(node, { self }) {
                     const manifest = visit(node.type, self);
                     const suffixes = node.suffix.map(c => visit(c, self).value);
-                    const suffixEncoders = fragment(suffixes.map(c => `getConstantEncoder(${c})`).join(', '))
+                    const suffixEncoders = fragment(suffixes.map(c => `getConstantEncoder(${c.render})`).join(', '))
                         .addImports('solanaCodecsCore', 'getConstantEncoder')
                         .mergeImportsWith(...suffixes);
-                    const suffixDecoders = fragment(suffixes.map(c => `getConstantDecoder(${c})`).join(', '))
+                    const suffixDecoders = fragment(suffixes.map(c => `getConstantDecoder(${c.render})`).join(', '))
                         .addImports('solanaCodecsCore', 'getConstantDecoder')
                         .mergeImportsWith(...suffixes);
                     manifest.encoder
-                        .mapRender(r => `getHiddenSuffixEncoder(${r}, [${suffixEncoders}])`)
+                        .mapRender(r => `getHiddenSuffixEncoder(${r}, [${suffixEncoders.render}])`)
                         .mergeImportsWith(suffixEncoders)
                         .addImports('solanaCodecsDataStructures', 'getHiddenSuffixEncoder');
                     manifest.decoder
-                        .mapRender(r => `getHiddenSuffixDecoder(${r}, [${suffixDecoders}])`)
+                        .mapRender(r => `getHiddenSuffixDecoder(${r}, [${suffixDecoders.render}])`)
                         .mergeImportsWith(suffixDecoders)
                         .addImports('solanaCodecsDataStructures', 'getHiddenSuffixDecoder');
                     return manifest;
@@ -665,11 +665,11 @@ export function getTypeManifestVisitor(input: {
                     const manifest = visit(node.type, self);
                     const sentinel = visit(node.sentinel, self).value;
                     manifest.encoder
-                        .mapRender(r => `addEncoderSentinel(${r}, ${sentinel})`)
+                        .mapRender(r => `addEncoderSentinel(${r}, ${sentinel.render})`)
                         .mergeImportsWith(sentinel)
                         .addImports('solanaCodecsCore', 'addEncoderSentinel');
                     manifest.decoder
-                        .mapRender(r => `addDecoderSentinel(${r}, ${sentinel})`)
+                        .mapRender(r => `addDecoderSentinel(${r}, ${sentinel.render})`)
                         .mergeImportsWith(sentinel)
                         .addImports('solanaCodecsCore', 'addDecoderSentinel');
                     return manifest;
@@ -706,11 +706,11 @@ export function getTypeManifestVisitor(input: {
                     const manifest = visit(node.type, self);
                     const prefix = visit(node.prefix, self);
                     manifest.encoder
-                        .mapRender(r => `addEncoderSizePrefix(${r}, ${prefix.encoder})`)
+                        .mapRender(r => `addEncoderSizePrefix(${r}, ${prefix.encoder.render})`)
                         .mergeImportsWith(prefix.encoder)
                         .addImports('solanaCodecsCore', 'addEncoderSizePrefix');
                     manifest.decoder
-                        .mapRender(r => `addDecoderSizePrefix(${r}, ${prefix.decoder})`)
+                        .mapRender(r => `addDecoderSizePrefix(${r}, ${prefix.decoder.render})`)
                         .mergeImportsWith(prefix.decoder)
                         .addImports('solanaCodecsCore', 'addDecoderSizePrefix');
                     return manifest;
@@ -758,7 +758,7 @@ export function getTypeManifestVisitor(input: {
                             case 'utf8':
                                 return ['getUtf8Encoder', 'getUtf8Decoder'];
                             default:
-                                throw new Error(`Unsupported string encoding: ${stringType.encoding}`);
+                                throw new Error(`Unsupported string encoding: ${stringType.encoding as string}`);
                         }
                     })();
                     return {

+ 1 - 1
packages/renderers-js/test/_setup.ts

@@ -105,7 +105,7 @@ export function codeStringAsRegex(code: string) {
 async function normalizeCode(code: string) {
     try {
         code = await format(code, PRETTIER_OPTIONS);
-    } catch (e) {
+    } catch {
         // Ignore errors.
     }
     return code.trim();

+ 3 - 3
packages/renderers-js/test/instructionsPage.test.ts

@@ -199,7 +199,7 @@ test('it renders instruction accounts with linked PDAs as default value', async
             'accounts.counter.value = await findCounterPda( { authority: expectAddress ( accounts.authority.value ) } ); ' +
             '}',
     ]);
-    renderMapContainsImports(renderMap, 'instructions/increment.ts', { '../pdas': ['findCounterPda'] });
+    await renderMapContainsImports(renderMap, 'instructions/increment.ts', { '../pdas': ['findCounterPda'] });
 });
 
 test('it renders instruction accounts with inlined PDAs as default value', async () => {
@@ -247,7 +247,7 @@ test('it renders instruction accounts with inlined PDAs as default value', async
             '} ); ' +
             '}',
     ]);
-    renderMapContainsImports(renderMap, 'instructions/increment.ts', {
+    await renderMapContainsImports(renderMap, 'instructions/increment.ts', {
         '@solana/web3.js': ['getProgramDerivedAddress'],
     });
 });
@@ -298,7 +298,7 @@ test('it renders instruction accounts with inlined PDAs from another program as
             '} ); ' +
             '}',
     ]);
-    renderMapContainsImports(renderMap, 'instructions/increment.ts', {
+    await renderMapContainsImports(renderMap, 'instructions/increment.ts', {
         '@solana/web3.js': ['Address', 'getProgramDerivedAddress'],
     });
 });

+ 3 - 3
packages/renderers-js/test/types/remainderOption.test.ts

@@ -5,7 +5,7 @@ import { test } from 'vitest';
 import { getRenderMapVisitor } from '../../src';
 import { renderMapContains, renderMapContainsImports } from '../_setup';
 
-test('it renders remainder option codecs', () => {
+test('it renders remainder option codecs', async () => {
     // Given the following node.
     const node = definedTypeNode({
         name: 'myType',
@@ -16,7 +16,7 @@ test('it renders remainder option codecs', () => {
     const renderMap = visit(node, getRenderMapVisitor());
 
     // Then we expect the following types and codecs to be exported.
-    renderMapContains(renderMap, 'types/myType.ts', [
+    await renderMapContains(renderMap, 'types/myType.ts', [
         'export type MyType = Option<Address>',
         'export type MyTypeArgs = OptionOrNullable<Address>',
         'getOptionEncoder( getAddressEncoder(), { prefix: null } )',
@@ -24,7 +24,7 @@ test('it renders remainder option codecs', () => {
     ]);
 
     // And we expect the following codec imports.
-    renderMapContainsImports(renderMap, 'types/myType.ts', {
+    await renderMapContainsImports(renderMap, 'types/myType.ts', {
         '@solana/web3.js': [
             'getOptionEncoder',
             'getOptionDecoder',

+ 6 - 6
packages/renderers-js/test/types/zeroableOption.test.ts

@@ -11,7 +11,7 @@ import { test } from 'vitest';
 import { getRenderMapVisitor } from '../../src';
 import { renderMapContains, renderMapContainsImports } from '../_setup';
 
-test('it renders zeroable option codecs', () => {
+test('it renders zeroable option codecs', async () => {
     // Given the following node.
     const node = definedTypeNode({
         name: 'myType',
@@ -22,7 +22,7 @@ test('it renders zeroable option codecs', () => {
     const renderMap = visit(node, getRenderMapVisitor());
 
     // Then we expect the following types and codecs to be exported.
-    renderMapContains(renderMap, 'types/myType.ts', [
+    await renderMapContains(renderMap, 'types/myType.ts', [
         'export type MyType = Option<Address>',
         'export type MyTypeArgs = OptionOrNullable<Address>',
         "getOptionEncoder( getAddressEncoder(), { prefix: null, noneValue: 'zeroes' } )",
@@ -30,7 +30,7 @@ test('it renders zeroable option codecs', () => {
     ]);
 
     // And we expect the following codec imports.
-    renderMapContainsImports(renderMap, 'types/myType.ts', {
+    await renderMapContainsImports(renderMap, 'types/myType.ts', {
         '@solana/web3.js': [
             'getOptionEncoder',
             'getOptionDecoder',
@@ -42,7 +42,7 @@ test('it renders zeroable option codecs', () => {
     });
 });
 
-test('it renders zeroable option codecs with custom zero values', () => {
+test('it renders zeroable option codecs with custom zero values', async () => {
     // Given the following node.
     const node = definedTypeNode({
         name: 'myType',
@@ -53,7 +53,7 @@ test('it renders zeroable option codecs with custom zero values', () => {
     const renderMap = visit(node, getRenderMapVisitor());
 
     // Then we expect the following types and codecs to be exported.
-    renderMapContains(renderMap, 'types/myType.ts', [
+    await renderMapContains(renderMap, 'types/myType.ts', [
         'export type MyType = Option<number>',
         'export type MyTypeArgs = OptionOrNullable<number>',
         'getOptionEncoder( getU16Encoder(), { prefix: null, noneValue: new Uint8Array([255, 255]) } )',
@@ -61,7 +61,7 @@ test('it renders zeroable option codecs with custom zero values', () => {
     ]);
 
     // And we expect the following codec imports.
-    renderMapContainsImports(renderMap, 'types/myType.ts', {
+    await renderMapContainsImports(renderMap, 'types/myType.ts', {
         '@solana/web3.js': [
             'getOptionEncoder',
             'getOptionDecoder',

+ 2 - 2
packages/renderers-rust/src/renderVisitor.ts

@@ -41,9 +41,9 @@ function runFormatter(cmd: string, args: string[]) {
         return;
     }
     if (stdout.length > 0) {
-        logWarn(`(cargo-fmt) ${stdout || error}`);
+        logWarn(`(cargo-fmt) ${stdout ? stdout?.toString() : error}`);
     }
     if (stderr.length > 0) {
-        logError(`(cargo-fmt) ${stderr || error}`);
+        logError(`(cargo-fmt) ${stderr ? stderr.toString() : error}`);
     }
 }

+ 5 - 1
packages/visitors-core/src/NodeStack.ts

@@ -1,7 +1,7 @@
 import { CODAMA_ERROR__VISITORS__CANNOT_REMOVE_LAST_PATH_IN_NODE_STACK, CodamaError } from '@codama/errors';
 import { GetNodeFromKind, Node, NodeKind } from '@codama/nodes';
 
-import { assertIsNodePath, NodePath } from './NodePath';
+import { assertIsNodePath, NodePath, nodePathToString } from './NodePath';
 
 type MutableNodePath = Node[];
 
@@ -71,4 +71,8 @@ export class NodeStack {
     public clone(): NodeStack {
         return new NodeStack(...this.stack);
     }
+
+    public toString(): string {
+        return nodePathToString(this.getPath());
+    }
 }

+ 0 - 1
packages/visitors-core/src/consoleLogVisitor.ts

@@ -6,6 +6,5 @@ import { Visitor } from './visitor';
 export function consoleLogVisitor<TNodeKind extends NodeKind = NodeKind>(
     visitor: Visitor<string, TNodeKind>,
 ): Visitor<void, TNodeKind> {
-    // eslint-disable-next-line no-console
     return mapVisitor(visitor, value => console.log(value));
 }

+ 1 - 1
packages/visitors-core/src/mergeVisitor.ts

@@ -8,7 +8,7 @@ export function mergeVisitor<TReturn, TNodeKind extends NodeKind = NodeKind>(
     merge: (node: Node, values: TReturn[]) => TReturn,
     options: { keys?: TNodeKind[] } = {},
 ): Visitor<TReturn, TNodeKind> {
-    const keys: NodeKind[] = options.keys ?? (REGISTERED_NODE_KINDS as NodeKind[]);
+    const keys: NodeKind[] = options.keys ?? REGISTERED_NODE_KINDS;
     const visitor = staticVisitor(leafValue, { keys }) as Visitor<TReturn>;
     const visit =
         (v: Visitor<TReturn>) =>

+ 1 - 0
packages/visitors-core/src/pipe.ts

@@ -109,5 +109,6 @@ export function pipe<TInitial, R1, R2, R3, R4, R5, R6, R7, R8, R9, R10>(
     r9_r10: (r9: R9) => R10,
 ): R10;
 export function pipe<TInitial>(init: TInitial, ...fns: CallableFunction[]) {
+    // eslint-disable-next-line @typescript-eslint/no-unsafe-return, @typescript-eslint/no-unsafe-call
     return fns.reduce((acc, fn) => fn(acc), init);
 }

+ 2 - 2
packages/visitors-core/test/topDownTransformerVisitor.test.ts

@@ -43,7 +43,7 @@ test('it can transform nodes using node selectors', () => {
     const visitor = topDownTransformerVisitor([
         {
             select: '[numberTypeNode]',
-            transform: node => numberTypeNode('u64') as typeof node,
+            transform: _node => numberTypeNode('u64') as typeof _node,
         },
     ]);
 
@@ -117,7 +117,7 @@ test('it can transform nodes using multiple node selectors', () => {
     const visitor = topDownTransformerVisitor([
         {
             select: ['[numberTypeNode]', path => path.length > 2],
-            transform: node => numberTypeNode('u64') as typeof node,
+            transform: _node => numberTypeNode('u64') as typeof _node,
         },
     ]);
 

+ 1 - 1
packages/visitors/src/setInstructionAccountDefaultValuesVisitor.ts

@@ -184,7 +184,7 @@ export function setInstructionAccountDefaultValuesVisitor(rules: InstructionAcco
                                     fillDefaultPdaSeedValuesVisitor(instructionPath, linkables, true),
                                 ),
                             };
-                        } catch (error) {
+                        } catch {
                             return account;
                         }
                     });

Rozdielové dáta súboru neboli zobrazené, pretože súbor je príliš veľký
+ 560 - 118
pnpm-lock.yaml


+ 3 - 1
tsconfig.json

@@ -1 +1,3 @@
-{}
+{
+    "include": ["eslint.config.mjs"]
+}

+ 8 - 2
turbo.json

@@ -24,7 +24,13 @@
             "dependsOn": ["build"]
         },
         "test:types": {},
-        "lint": {},
-        "lint:fix": {}
+        "lint": {
+            "inputs": ["$TURBO_DEFAULT$", "../../eslint.config.*"],
+            "outputs": []
+        },
+        "lint:fix": {
+            "inputs": ["$TURBO_DEFAULT$", "../../eslint.config.*"],
+            "outputs": ["*"]
+        }
     }
 }

Niektoré súbory nie sú zobrazené, pretože je v týchto rozdielových dátach zmenené mnoho súborov