diff --git a/.eslintignore b/.eslintignore index f00c859..380eb8a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ # don't lint build output (make sure it's set to your correct build folder name) dist # don't lint nyc coverage output -coverage \ No newline at end of file +coverage +.eslintrc.js diff --git a/.eslintignore b/.eslintignore index f00c859..380eb8a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ # don't lint build output (make sure it's set to your correct build folder name) dist # don't lint nyc coverage output -coverage \ No newline at end of file +coverage +.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index a62b06b..53d3dd5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,8 +4,16 @@ plugins: [ "@typescript-eslint", ], + parserOptions: { + tsconfigRootDir: __dirname, + project: ["./tsconfig.json"], + }, extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", ], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off" + }, } diff --git a/.eslintignore b/.eslintignore index f00c859..380eb8a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ # don't lint build output (make sure it's set to your correct build folder name) dist # don't lint nyc coverage output -coverage \ No newline at end of file +coverage +.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index a62b06b..53d3dd5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,8 +4,16 @@ plugins: [ "@typescript-eslint", ], + parserOptions: { + tsconfigRootDir: __dirname, + project: ["./tsconfig.json"], + }, extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", ], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off" + }, } diff --git a/src/DataAccessGenerator.ts b/src/DataAccessGenerator.ts index 96ef56a..acece01 100644 --- a/src/DataAccessGenerator.ts +++ b/src/DataAccessGenerator.ts @@ -17,7 +17,6 @@ defineParseEntity(collection.entities), defineParseCollection(collection), defineLoad(collection), - defineGeneral(), ]; return { @@ -28,8 +27,10 @@ function defineImports(collection: Collection): string { const entity = collection.entities; - return `import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; -import * as fs from "fs";`; + return `/* eslint-disable @typescript-eslint/no-explicit-any */ +import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; +import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty, canReadFile } from "./util";`; } function defineSave(collection: Collection): string { @@ -39,43 +40,6 @@ }`; } -function defineGeneral(): string { - return `function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - -function canReadFile(path: string): boolean { - try { - fs.accessSync(path, fs.constants.R_OK); - return true; - } catch (error) { - return false; - } -}`; -} - function defineParseEntity(entity: Entity): string { const propParser = entity.properties.map(p => parseStringProperty(entity.name, p)).join("\n"); return `function parse${entity.name}(data: any): ${entity.name} @@ -109,6 +73,7 @@ }; } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parse${collection.name}(data); }`; diff --git a/.eslintignore b/.eslintignore index f00c859..380eb8a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ # don't lint build output (make sure it's set to your correct build folder name) dist # don't lint nyc coverage output -coverage \ No newline at end of file +coverage +.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index a62b06b..53d3dd5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,8 +4,16 @@ plugins: [ "@typescript-eslint", ], + parserOptions: { + tsconfigRootDir: __dirname, + project: ["./tsconfig.json"], + }, extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", ], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off" + }, } diff --git a/src/DataAccessGenerator.ts b/src/DataAccessGenerator.ts index 96ef56a..acece01 100644 --- a/src/DataAccessGenerator.ts +++ b/src/DataAccessGenerator.ts @@ -17,7 +17,6 @@ defineParseEntity(collection.entities), defineParseCollection(collection), defineLoad(collection), - defineGeneral(), ]; return { @@ -28,8 +27,10 @@ function defineImports(collection: Collection): string { const entity = collection.entities; - return `import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; -import * as fs from "fs";`; + return `/* eslint-disable @typescript-eslint/no-explicit-any */ +import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; +import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty, canReadFile } from "./util";`; } function defineSave(collection: Collection): string { @@ -39,43 +40,6 @@ }`; } -function defineGeneral(): string { - return `function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - -function canReadFile(path: string): boolean { - try { - fs.accessSync(path, fs.constants.R_OK); - return true; - } catch (error) { - return false; - } -}`; -} - function defineParseEntity(entity: Entity): string { const propParser = entity.properties.map(p => parseStringProperty(entity.name, p)).join("\n"); return `function parse${entity.name}(data: any): ${entity.name} @@ -109,6 +73,7 @@ }; } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parse${collection.name}(data); }`; diff --git a/src/ExampleOutput/DataAccess.ts b/src/ExampleOutput/DataAccess.ts index a25cac4..f39f6db 100644 --- a/src/ExampleOutput/DataAccess.ts +++ b/src/ExampleOutput/DataAccess.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { Graph, GraphNode } from "./Model"; import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty } from "./util"; type GraphStorage = Graph & { $schema: string; }; @@ -29,34 +31,6 @@ }; } -function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -export function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - - - function canReadFile(path: string): boolean { try { fs.accessSync(path, fs.constants.R_OK); @@ -77,6 +51,7 @@ return emptyGraph(); } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parseGraph(data); } diff --git a/.eslintignore b/.eslintignore index f00c859..380eb8a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ # don't lint build output (make sure it's set to your correct build folder name) dist # don't lint nyc coverage output -coverage \ No newline at end of file +coverage +.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index a62b06b..53d3dd5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,8 +4,16 @@ plugins: [ "@typescript-eslint", ], + parserOptions: { + tsconfigRootDir: __dirname, + project: ["./tsconfig.json"], + }, extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", ], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off" + }, } diff --git a/src/DataAccessGenerator.ts b/src/DataAccessGenerator.ts index 96ef56a..acece01 100644 --- a/src/DataAccessGenerator.ts +++ b/src/DataAccessGenerator.ts @@ -17,7 +17,6 @@ defineParseEntity(collection.entities), defineParseCollection(collection), defineLoad(collection), - defineGeneral(), ]; return { @@ -28,8 +27,10 @@ function defineImports(collection: Collection): string { const entity = collection.entities; - return `import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; -import * as fs from "fs";`; + return `/* eslint-disable @typescript-eslint/no-explicit-any */ +import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; +import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty, canReadFile } from "./util";`; } function defineSave(collection: Collection): string { @@ -39,43 +40,6 @@ }`; } -function defineGeneral(): string { - return `function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - -function canReadFile(path: string): boolean { - try { - fs.accessSync(path, fs.constants.R_OK); - return true; - } catch (error) { - return false; - } -}`; -} - function defineParseEntity(entity: Entity): string { const propParser = entity.properties.map(p => parseStringProperty(entity.name, p)).join("\n"); return `function parse${entity.name}(data: any): ${entity.name} @@ -109,6 +73,7 @@ }; } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parse${collection.name}(data); }`; diff --git a/src/ExampleOutput/DataAccess.ts b/src/ExampleOutput/DataAccess.ts index a25cac4..f39f6db 100644 --- a/src/ExampleOutput/DataAccess.ts +++ b/src/ExampleOutput/DataAccess.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { Graph, GraphNode } from "./Model"; import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty } from "./util"; type GraphStorage = Graph & { $schema: string; }; @@ -29,34 +31,6 @@ }; } -function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -export function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - - - function canReadFile(path: string): boolean { try { fs.accessSync(path, fs.constants.R_OK); @@ -77,6 +51,7 @@ return emptyGraph(); } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parseGraph(data); } diff --git a/src/ExampleOutput/Middleware.ts b/src/ExampleOutput/Middleware.ts index 23c2f70..b67ea03 100644 --- a/src/ExampleOutput/Middleware.ts +++ b/src/ExampleOutput/Middleware.ts @@ -7,7 +7,7 @@ const parseName = andThen(compose(parseRequiredMember("name"), parseString)); const parseDescription = andThen(compose(parseRequiredMember("description"), parseString)); -function parseGraphNodeInput(data: any): Result { +function parseGraphNodeInput(data: unknown): Result { const obj = andThen(parseObject)(parseNotNull(data)); const members: ParseObject = { name: parseName(obj), diff --git a/.eslintignore b/.eslintignore index f00c859..380eb8a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ # don't lint build output (make sure it's set to your correct build folder name) dist # don't lint nyc coverage output -coverage \ No newline at end of file +coverage +.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index a62b06b..53d3dd5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,8 +4,16 @@ plugins: [ "@typescript-eslint", ], + parserOptions: { + tsconfigRootDir: __dirname, + project: ["./tsconfig.json"], + }, extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", ], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off" + }, } diff --git a/src/DataAccessGenerator.ts b/src/DataAccessGenerator.ts index 96ef56a..acece01 100644 --- a/src/DataAccessGenerator.ts +++ b/src/DataAccessGenerator.ts @@ -17,7 +17,6 @@ defineParseEntity(collection.entities), defineParseCollection(collection), defineLoad(collection), - defineGeneral(), ]; return { @@ -28,8 +27,10 @@ function defineImports(collection: Collection): string { const entity = collection.entities; - return `import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; -import * as fs from "fs";`; + return `/* eslint-disable @typescript-eslint/no-explicit-any */ +import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; +import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty, canReadFile } from "./util";`; } function defineSave(collection: Collection): string { @@ -39,43 +40,6 @@ }`; } -function defineGeneral(): string { - return `function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - -function canReadFile(path: string): boolean { - try { - fs.accessSync(path, fs.constants.R_OK); - return true; - } catch (error) { - return false; - } -}`; -} - function defineParseEntity(entity: Entity): string { const propParser = entity.properties.map(p => parseStringProperty(entity.name, p)).join("\n"); return `function parse${entity.name}(data: any): ${entity.name} @@ -109,6 +73,7 @@ }; } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parse${collection.name}(data); }`; diff --git a/src/ExampleOutput/DataAccess.ts b/src/ExampleOutput/DataAccess.ts index a25cac4..f39f6db 100644 --- a/src/ExampleOutput/DataAccess.ts +++ b/src/ExampleOutput/DataAccess.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { Graph, GraphNode } from "./Model"; import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty } from "./util"; type GraphStorage = Graph & { $schema: string; }; @@ -29,34 +31,6 @@ }; } -function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -export function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - - - function canReadFile(path: string): boolean { try { fs.accessSync(path, fs.constants.R_OK); @@ -77,6 +51,7 @@ return emptyGraph(); } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parseGraph(data); } diff --git a/src/ExampleOutput/Middleware.ts b/src/ExampleOutput/Middleware.ts index 23c2f70..b67ea03 100644 --- a/src/ExampleOutput/Middleware.ts +++ b/src/ExampleOutput/Middleware.ts @@ -7,7 +7,7 @@ const parseName = andThen(compose(parseRequiredMember("name"), parseString)); const parseDescription = andThen(compose(parseRequiredMember("description"), parseString)); -function parseGraphNodeInput(data: any): Result { +function parseGraphNodeInput(data: unknown): Result { const obj = andThen(parseObject)(parseNotNull(data)); const members: ParseObject = { name: parseName(obj), diff --git a/src/ExampleOutput/util.ts b/src/ExampleOutput/util.ts index 7f9648c..39c85a4 100644 --- a/src/ExampleOutput/util.ts +++ b/src/ExampleOutput/util.ts @@ -1,3 +1,8 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/ban-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import * as fs from "fs"; + export interface Ok { isSuccessful: true; value: T; @@ -24,22 +29,24 @@ else return { isSuccessful: true, value: data }; } -export function parseObject(data: any): Result { +export function parseObject(data: any): Result> { if (typeof data === "object") return { isSuccessful: true, value: data }; else return { isSuccessful: false, errorMessage: "Input is not an object." }; } export const parseRequiredMember = (fieldName: keyof T) => (data: any): Result => { if (fieldName in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return { isSuccessful: true, value: data[fieldName] }; } else { - return { isSuccessful: false, errorMessage: `Required member "${fieldName}" could not be found.` }; + return { isSuccessful: false, errorMessage: `Required member "${fieldName.toString()}" could not be found.` }; } } export const parseNullableMember = (fieldName: keyof T) => (data: any): Result => { if (fieldName in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return { isSuccessful: true, value: data[fieldName] }; } else { @@ -64,6 +71,35 @@ }; } +export function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] +{ + if(fieldName in data) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + const valueList = data[fieldName]; + if(Array.isArray(valueList)) + { + return valueList.map(itemParser); + } + } + return []; +} + +export function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T +{ + if(fieldName in obj) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + const fieldValue = obj[fieldName]; + if(typeof fieldValue === type) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return fieldValue; + } + } + return defaultValue; +} + export function resolve(members: ParseObject): Result { const obj: Partial = {}; for (const key in members) { @@ -77,3 +113,12 @@ } return { isSuccessful: true, value: (obj as T) }; } + +export function canReadFile(path: string): boolean { + try { + fs.accessSync(path, fs.constants.R_OK); + return true; + } catch (error) { + return false; + } +} diff --git a/.eslintignore b/.eslintignore index f00c859..380eb8a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ # don't lint build output (make sure it's set to your correct build folder name) dist # don't lint nyc coverage output -coverage \ No newline at end of file +coverage +.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index a62b06b..53d3dd5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,8 +4,16 @@ plugins: [ "@typescript-eslint", ], + parserOptions: { + tsconfigRootDir: __dirname, + project: ["./tsconfig.json"], + }, extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", ], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off" + }, } diff --git a/src/DataAccessGenerator.ts b/src/DataAccessGenerator.ts index 96ef56a..acece01 100644 --- a/src/DataAccessGenerator.ts +++ b/src/DataAccessGenerator.ts @@ -17,7 +17,6 @@ defineParseEntity(collection.entities), defineParseCollection(collection), defineLoad(collection), - defineGeneral(), ]; return { @@ -28,8 +27,10 @@ function defineImports(collection: Collection): string { const entity = collection.entities; - return `import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; -import * as fs from "fs";`; + return `/* eslint-disable @typescript-eslint/no-explicit-any */ +import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; +import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty, canReadFile } from "./util";`; } function defineSave(collection: Collection): string { @@ -39,43 +40,6 @@ }`; } -function defineGeneral(): string { - return `function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - -function canReadFile(path: string): boolean { - try { - fs.accessSync(path, fs.constants.R_OK); - return true; - } catch (error) { - return false; - } -}`; -} - function defineParseEntity(entity: Entity): string { const propParser = entity.properties.map(p => parseStringProperty(entity.name, p)).join("\n"); return `function parse${entity.name}(data: any): ${entity.name} @@ -109,6 +73,7 @@ }; } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parse${collection.name}(data); }`; diff --git a/src/ExampleOutput/DataAccess.ts b/src/ExampleOutput/DataAccess.ts index a25cac4..f39f6db 100644 --- a/src/ExampleOutput/DataAccess.ts +++ b/src/ExampleOutput/DataAccess.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { Graph, GraphNode } from "./Model"; import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty } from "./util"; type GraphStorage = Graph & { $schema: string; }; @@ -29,34 +31,6 @@ }; } -function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -export function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - - - function canReadFile(path: string): boolean { try { fs.accessSync(path, fs.constants.R_OK); @@ -77,6 +51,7 @@ return emptyGraph(); } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parseGraph(data); } diff --git a/src/ExampleOutput/Middleware.ts b/src/ExampleOutput/Middleware.ts index 23c2f70..b67ea03 100644 --- a/src/ExampleOutput/Middleware.ts +++ b/src/ExampleOutput/Middleware.ts @@ -7,7 +7,7 @@ const parseName = andThen(compose(parseRequiredMember("name"), parseString)); const parseDescription = andThen(compose(parseRequiredMember("description"), parseString)); -function parseGraphNodeInput(data: any): Result { +function parseGraphNodeInput(data: unknown): Result { const obj = andThen(parseObject)(parseNotNull(data)); const members: ParseObject = { name: parseName(obj), diff --git a/src/ExampleOutput/util.ts b/src/ExampleOutput/util.ts index 7f9648c..39c85a4 100644 --- a/src/ExampleOutput/util.ts +++ b/src/ExampleOutput/util.ts @@ -1,3 +1,8 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/ban-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import * as fs from "fs"; + export interface Ok { isSuccessful: true; value: T; @@ -24,22 +29,24 @@ else return { isSuccessful: true, value: data }; } -export function parseObject(data: any): Result { +export function parseObject(data: any): Result> { if (typeof data === "object") return { isSuccessful: true, value: data }; else return { isSuccessful: false, errorMessage: "Input is not an object." }; } export const parseRequiredMember = (fieldName: keyof T) => (data: any): Result => { if (fieldName in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return { isSuccessful: true, value: data[fieldName] }; } else { - return { isSuccessful: false, errorMessage: `Required member "${fieldName}" could not be found.` }; + return { isSuccessful: false, errorMessage: `Required member "${fieldName.toString()}" could not be found.` }; } } export const parseNullableMember = (fieldName: keyof T) => (data: any): Result => { if (fieldName in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return { isSuccessful: true, value: data[fieldName] }; } else { @@ -64,6 +71,35 @@ }; } +export function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] +{ + if(fieldName in data) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + const valueList = data[fieldName]; + if(Array.isArray(valueList)) + { + return valueList.map(itemParser); + } + } + return []; +} + +export function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T +{ + if(fieldName in obj) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + const fieldValue = obj[fieldName]; + if(typeof fieldValue === type) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return fieldValue; + } + } + return defaultValue; +} + export function resolve(members: ParseObject): Result { const obj: Partial = {}; for (const key in members) { @@ -77,3 +113,12 @@ } return { isSuccessful: true, value: (obj as T) }; } + +export function canReadFile(path: string): boolean { + try { + fs.accessSync(path, fs.constants.R_OK); + return true; + } catch (error) { + return false; + } +} diff --git a/src/MiddlewareGenerator.ts b/src/MiddlewareGenerator.ts index 7e95816..6d6baf6 100644 --- a/src/MiddlewareGenerator.ts +++ b/src/MiddlewareGenerator.ts @@ -113,7 +113,7 @@ const propParsers = entity.properties.map(p => definePropertyParser(entity, p)).join("\n"); return `${propParsers} -function parse${entity.name}Input(data: any): Result<${entity.name}Input> { +function parse${entity.name}Input(data: unknown): Result<${entity.name}Input> { const obj = andThen(parseObject)(parseNotNull(data)); const members: ParseObject<${entity.name}Input> = { ${entity.properties.map(p => `${p.key}: parse${p.key}(obj),`).join("\n\t\t")} diff --git a/.eslintignore b/.eslintignore index f00c859..380eb8a 100644 --- a/.eslintignore +++ b/.eslintignore @@ -3,4 +3,5 @@ # don't lint build output (make sure it's set to your correct build folder name) dist # don't lint nyc coverage output -coverage \ No newline at end of file +coverage +.eslintrc.js diff --git a/.eslintrc.js b/.eslintrc.js index a62b06b..53d3dd5 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -4,8 +4,16 @@ plugins: [ "@typescript-eslint", ], + parserOptions: { + tsconfigRootDir: __dirname, + project: ["./tsconfig.json"], + }, extends: [ "eslint:recommended", "plugin:@typescript-eslint/recommended", + "plugin:@typescript-eslint/recommended-requiring-type-checking", ], + rules: { + "@typescript-eslint/explicit-module-boundary-types": "off" + }, } diff --git a/src/DataAccessGenerator.ts b/src/DataAccessGenerator.ts index 96ef56a..acece01 100644 --- a/src/DataAccessGenerator.ts +++ b/src/DataAccessGenerator.ts @@ -17,7 +17,6 @@ defineParseEntity(collection.entities), defineParseCollection(collection), defineLoad(collection), - defineGeneral(), ]; return { @@ -28,8 +27,10 @@ function defineImports(collection: Collection): string { const entity = collection.entities; - return `import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; -import * as fs from "fs";`; + return `/* eslint-disable @typescript-eslint/no-explicit-any */ +import { ${collection.name}, ${entity.name} } from "./${modelModuleName(collection)}"; +import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty, canReadFile } from "./util";`; } function defineSave(collection: Collection): string { @@ -39,43 +40,6 @@ }`; } -function defineGeneral(): string { - return `function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - -function canReadFile(path: string): boolean { - try { - fs.accessSync(path, fs.constants.R_OK); - return true; - } catch (error) { - return false; - } -}`; -} - function defineParseEntity(entity: Entity): string { const propParser = entity.properties.map(p => parseStringProperty(entity.name, p)).join("\n"); return `function parse${entity.name}(data: any): ${entity.name} @@ -109,6 +73,7 @@ }; } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parse${collection.name}(data); }`; diff --git a/src/ExampleOutput/DataAccess.ts b/src/ExampleOutput/DataAccess.ts index a25cac4..f39f6db 100644 --- a/src/ExampleOutput/DataAccess.ts +++ b/src/ExampleOutput/DataAccess.ts @@ -1,5 +1,7 @@ +/* eslint-disable @typescript-eslint/no-explicit-any */ import { Graph, GraphNode } from "./Model"; import * as fs from "fs"; +import { parseArrayProperty, parsePrimitiveProperty } from "./util"; type GraphStorage = Graph & { $schema: string; }; @@ -29,34 +31,6 @@ }; } -function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] -{ - if(fieldName in data) - { - const valueList = data[fieldName]; - if(Array.isArray(valueList)) - { - return valueList.map(itemParser); - } - } - return []; -} - -export function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T -{ - if(fieldName in obj) - { - const fieldValue = obj[fieldName]; - if(typeof fieldValue === type) - { - return fieldValue; - } - } - return defaultValue; -} - - - function canReadFile(path: string): boolean { try { fs.accessSync(path, fs.constants.R_OK); @@ -77,6 +51,7 @@ return emptyGraph(); } const content = fs.readFileSync(fileName).toString(); + // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment const data = JSON.parse(content); return parseGraph(data); } diff --git a/src/ExampleOutput/Middleware.ts b/src/ExampleOutput/Middleware.ts index 23c2f70..b67ea03 100644 --- a/src/ExampleOutput/Middleware.ts +++ b/src/ExampleOutput/Middleware.ts @@ -7,7 +7,7 @@ const parseName = andThen(compose(parseRequiredMember("name"), parseString)); const parseDescription = andThen(compose(parseRequiredMember("description"), parseString)); -function parseGraphNodeInput(data: any): Result { +function parseGraphNodeInput(data: unknown): Result { const obj = andThen(parseObject)(parseNotNull(data)); const members: ParseObject = { name: parseName(obj), diff --git a/src/ExampleOutput/util.ts b/src/ExampleOutput/util.ts index 7f9648c..39c85a4 100644 --- a/src/ExampleOutput/util.ts +++ b/src/ExampleOutput/util.ts @@ -1,3 +1,8 @@ +/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/ban-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import * as fs from "fs"; + export interface Ok { isSuccessful: true; value: T; @@ -24,22 +29,24 @@ else return { isSuccessful: true, value: data }; } -export function parseObject(data: any): Result { +export function parseObject(data: any): Result> { if (typeof data === "object") return { isSuccessful: true, value: data }; else return { isSuccessful: false, errorMessage: "Input is not an object." }; } export const parseRequiredMember = (fieldName: keyof T) => (data: any): Result => { if (fieldName in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return { isSuccessful: true, value: data[fieldName] }; } else { - return { isSuccessful: false, errorMessage: `Required member "${fieldName}" could not be found.` }; + return { isSuccessful: false, errorMessage: `Required member "${fieldName.toString()}" could not be found.` }; } } export const parseNullableMember = (fieldName: keyof T) => (data: any): Result => { if (fieldName in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return { isSuccessful: true, value: data[fieldName] }; } else { @@ -64,6 +71,35 @@ }; } +export function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] +{ + if(fieldName in data) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + const valueList = data[fieldName]; + if(Array.isArray(valueList)) + { + return valueList.map(itemParser); + } + } + return []; +} + +export function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T +{ + if(fieldName in obj) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + const fieldValue = obj[fieldName]; + if(typeof fieldValue === type) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return fieldValue; + } + } + return defaultValue; +} + export function resolve(members: ParseObject): Result { const obj: Partial = {}; for (const key in members) { @@ -77,3 +113,12 @@ } return { isSuccessful: true, value: (obj as T) }; } + +export function canReadFile(path: string): boolean { + try { + fs.accessSync(path, fs.constants.R_OK); + return true; + } catch (error) { + return false; + } +} diff --git a/src/MiddlewareGenerator.ts b/src/MiddlewareGenerator.ts index 7e95816..6d6baf6 100644 --- a/src/MiddlewareGenerator.ts +++ b/src/MiddlewareGenerator.ts @@ -113,7 +113,7 @@ const propParsers = entity.properties.map(p => definePropertyParser(entity, p)).join("\n"); return `${propParsers} -function parse${entity.name}Input(data: any): Result<${entity.name}Input> { +function parse${entity.name}Input(data: unknown): Result<${entity.name}Input> { const obj = andThen(parseObject)(parseNotNull(data)); const members: ParseObject<${entity.name}Input> = { ${entity.properties.map(p => `${p.key}: parse${p.key}(obj),`).join("\n\t\t")} diff --git a/src/UtilGenerator.ts b/src/UtilGenerator.ts index 0c14092..66de2ff 100644 --- a/src/UtilGenerator.ts +++ b/src/UtilGenerator.ts @@ -1,4 +1,9 @@ -export const UtilCode = `export interface Ok { +export const UtilCode = `/* eslint-disable @typescript-eslint/no-unsafe-assignment */ +/* eslint-disable @typescript-eslint/ban-types */ +/* eslint-disable @typescript-eslint/no-explicit-any */ +import * as fs from "fs"; + +export interface Ok { isSuccessful: true; value: T; } @@ -24,22 +29,24 @@ else return { isSuccessful: true, value: data }; } -export function parseObject(data: any): Result { +export function parseObject(data: any): Result> { if (typeof data === "object") return { isSuccessful: true, value: data }; else return { isSuccessful: false, errorMessage: "Input is not an object." }; } export const parseRequiredMember = (fieldName: keyof T) => (data: any): Result => { if (fieldName in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return { isSuccessful: true, value: data[fieldName] }; } else { - return { isSuccessful: false, errorMessage: \`Required member "\${fieldName}" could not be found.\` }; + return { isSuccessful: false, errorMessage: \`Required member "\${fieldName.toString()}" could not be found.\` }; } } export const parseNullableMember = (fieldName: keyof T) => (data: any): Result => { if (fieldName in data) { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access return { isSuccessful: true, value: data[fieldName] }; } else { @@ -64,6 +71,35 @@ }; } +export function parseArrayProperty(fieldName: keyof O, itemParser: (item: any) => T, data: any): T[] +{ + if(fieldName in data) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + const valueList = data[fieldName]; + if(Array.isArray(valueList)) + { + return valueList.map(itemParser); + } + } + return []; +} + +export function parsePrimitiveProperty(type: T extends string ? "string" : "number", fieldName: keyof O, defaultValue: T, obj: any): T +{ + if(fieldName in obj) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access, @typescript-eslint/no-unsafe-assignment + const fieldValue = obj[fieldName]; + if(typeof fieldValue === type) + { + // eslint-disable-next-line @typescript-eslint/no-unsafe-return + return fieldValue; + } + } + return defaultValue; +} + export function resolve(members: ParseObject): Result { const obj: Partial = {}; for (const key in members) { @@ -77,4 +113,13 @@ } return { isSuccessful: true, value: (obj as T) }; } + +export function canReadFile(path: string): boolean { + try { + fs.accessSync(path, fs.constants.R_OK); + return true; + } catch (error) { + return false; + } +} `;