Skip to content

Commit

Permalink
chore: Check for errors with TypeScript (#446)
Browse files Browse the repository at this point in the history
  • Loading branch information
lukehesluke authored Mar 11, 2024
1 parent ca0997f commit d6a8dba
Show file tree
Hide file tree
Showing 9 changed files with 78 additions and 9 deletions.
1 change: 1 addition & 0 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ this.createError(
#### Adding to the core library

* You should write a test for your rule.
* Add the rule's file, as well as its test file to tsconfig.json's `include` array, so that TypeScript can check for errors.
* Add the rule to the list in `rules/index`, so that it is processed.

#### Adding to your own application
Expand Down
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -229,10 +229,10 @@ To run tests locally, run:
$ npm test
```

The test run will also include a run of [eslint](https://eslint.org/). To run the tests without these, use:
The test run will also include a run of [eslint](https://eslint.org/) and [TypeScript](https://www.typescriptlang.org/). To run the tests without these, use:

```shell
$ npm run test-no-lint
$ npm run run-tests
```

### Contributing
Expand Down
12 changes: 8 additions & 4 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,19 +38,23 @@
"write-file-atomic": "^3.0.3"
},
"devDependencies": {
"@types/jasmine": "^5.1.4",
"@types/jasmine-expect": "^3.8.1",
"@types/node": "^20.11.24",
"eslint": "^8.36.0",
"eslint-config-airbnb": "^19.0.4",
"eslint-plugin-import": "^2.27.5",
"jasmine": "^4.6.0",
"nock": "^13.3.0",
"sync-request": "^6.1.0"
"sync-request": "^6.1.0",
"typescript": "^5.3.3"
},
"scripts": {
"lint": "eslint \"src/**/*.js\"",
"lint-fix": "eslint \"src/**/*.js\" --fix",
"pretest": "npm run lint",
"test": "npm run test-no-lint",
"test-no-lint": "jasmine",
"pretest": "npm run lint && tsc",
"test": "npm run run-tests",
"run-tests": "jasmine",
"test-debug": "node --inspect-brk -i ./node_modules/jasmine/bin/jasmine.js",
"postpublish": "git push",
"publish-patch": "npm test && git pull && git push && npm version patch && npm publish"
Expand Down
2 changes: 2 additions & 0 deletions src/classes/field.js
Original file line number Diff line number Diff line change
Expand Up @@ -301,7 +301,9 @@ const Field = class {
actualTypeKey = actualTypeKey.substr(1);
}
if (
// @ts-expect-error
typeof (this.constructor.canBeTypeOfMapping[testTypeKey]) !== 'undefined'
// @ts-expect-error
&& this.constructor.canBeTypeOfMapping[testTypeKey] === actualTypeKey
) {
return true;
Expand Down
3 changes: 3 additions & 0 deletions src/classes/model-node.js
Original file line number Diff line number Diff line change
Expand Up @@ -128,6 +128,7 @@ const ModelNode = class {
// Does our property allow us to inherit?
&& typeof this.parentNode.model.fields[this.cleanName] !== 'undefined'
&& typeof this.parentNode.model.fields[this.cleanName].inheritsTo !== 'undefined'
// @ts-expect-error
&& this.constructor.checkInheritRule(
this.parentNode.model.fields[this.cleanName].inheritsTo,
field,
Expand All @@ -142,6 +143,7 @@ const ModelNode = class {
const modelField = this.model.fields[fieldKey];
const fieldValue = this.getValue(fieldKey);
if (typeof modelField.inheritsFrom !== 'undefined'
// @ts-expect-error
&& this.constructor.checkInheritRule(modelField.inheritsFrom, field)
&& typeof fieldValue === 'object'
&& !(fieldValue instanceof Array)
Expand All @@ -162,6 +164,7 @@ const ModelNode = class {
}
}
if (parentModel) {
// @ts-expect-error
const parentNode = new this.constructor(
modelField.fieldName,
fieldValue,
Expand Down
2 changes: 2 additions & 0 deletions src/classes/model.js
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@ const Model = class {
}

hasRequiredField(field) {
// @ts-expect-error
return PropertyHelper.arrayHasField(this.requiredFields, field, this.version);
}

Expand Down Expand Up @@ -143,6 +144,7 @@ const Model = class {
}

hasRecommendedField(field) {
// @ts-expect-error
return PropertyHelper.arrayHasField(this.recommendedFields, field, this.version);
}

Expand Down
5 changes: 4 additions & 1 deletion src/helpers/json-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,7 @@ async function getFromFsCacheIfExists(baseCachePath, url) {
// Probably just doesn't exist
return { exists: false };
}
// @ts-expect-error
const parsed = JSON.parse(rawCacheContents);
return {
exists: true,
Expand Down Expand Up @@ -132,6 +133,7 @@ async function saveToFsCache(baseCachePath, url, fileObject) {
async function getFromRemoteUrl(url) {
let response;
try {
// @ts-expect-error
response = await axios.get(url, {
headers: {
'Content-Type': 'application/ld+json',
Expand All @@ -146,6 +148,7 @@ async function getFromRemoteUrl(url) {
if (match !== null) {
const { origin } = new URL(url);
const linkUrl = match[1];
// @ts-expect-error
response = await axios.get(origin + linkUrl, {
headers: {
'Content-Type': 'application/ld+json',
Expand Down Expand Up @@ -217,7 +220,7 @@ async function getFileLoadRemote(url) {
*
* @param {string} url
* @param {Object} options
* @returns {Object}
* @returns {Promise<any>}
*/
async function getFileLoadRemoteAndCacheToFs(url, options) {
{
Expand Down
36 changes: 34 additions & 2 deletions src/rules/rule.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,26 @@ const ValidationError = require('../errors/validation-error');
class Rule {
constructor(options) {
this.options = options || new OptionsHelper();
/** @type {string[] | '*'} */
this.targetModels = [];
/** @type {'*' | {[model: string]: '*' | string[]}} */
this.targetFields = {};
/** @type {string[] | '*'} */
this.targetValidationModes = '*';
/**
* @type {{
* name: string;
* description: string;
* tests: {[key: string]: {
* description?: string;
* message: string;
* sampleValues?: { [messageTemplateArg: string]: string };
* category: string;
* severity: string;
* type: string;
* }}
* }}
*/
this.meta = {
name: 'Rule',
description: 'This is a base rule description that should be overridden.',
Expand Down Expand Up @@ -38,11 +55,22 @@ class Rule {
return errors;
}

validateModel(/* node */) {
/**
* @param {import('../classes/model-node').ModelNodeType} node
* @returns {Promise<import('../errors/validation-error')[]>}
*/
// eslint-disable-next-line no-unused-vars
validateModel(node) {
throw Error('Model validation rule not implemented');
}

async validateField(/* node, field */) {
/**
* @param {import('../classes/model-node').ModelNodeType} node
* @param {string} field
* @returns {Promise<import('../errors/validation-error')[]>}
*/
// eslint-disable-next-line no-unused-vars
async validateField(node, field) {
throw Error('Field validation rule not implemented');
}

Expand Down Expand Up @@ -88,6 +116,10 @@ class Rule {
);
}

/**
* @param {import('../classes/model')} model
* @param {string} field
*/
isFieldTargeted(model, field) {
if (this.targetFields === '*') {
return true;
Expand Down
22 changes: 22 additions & 0 deletions tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
{
"compilerOptions": {
"noEmit": true,
"allowJs": true,
"checkJs": true,
"downlevelIteration": true,
"target": "ES2019",
"moduleResolution": "node",
"types": ["jasmine", "node", "jasmine-expect"]
},
"include": [
"src/classes/**/*.js",
"src/errors/**/*.js",
"src/helpers/**/*.js",
"src/rules/rule.js",
// TODO add other rules
"src/exceptions.js"
],
"exclude": [
"src/helpers/graph.js"
]
}

0 comments on commit d6a8dba

Please sign in to comment.