Skip to content

Commit

Permalink
refactor: fix linting errors (#13)
Browse files Browse the repository at this point in the history
* build: adds more liniting options

* refactor: fixes `Unsafe use of expression of type 'any'` lint errors

* refactor: fixes `Expression is always true` lint errors

* refactor: mark private member as readonly

* refactor: fixes `his type is not allowed in the 'if' condition because it could be a string` lint error

* refactor: ignores two lint errors

The next tslint version will include an option to disable this specific
check (palantir/tslint#3279)

* build: enables linting before publishing, fixes #5
  • Loading branch information
danielmenzel committed Jan 23, 2019
1 parent 9776f74 commit 74287e5
Show file tree
Hide file tree
Showing 6 changed files with 38 additions and 24 deletions.
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@
"types": "lib/index.d.ts",
"scripts": {
"prepare": "npm run build",
"prepublishOnly": "npm test",
"prepublishOnly": "npm run lint && npm test",
"build": "npx tsc",
"watch": "npx tsc -watch",
"test": "npx jest test",
Expand Down
34 changes: 18 additions & 16 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,20 +3,23 @@ import { SchemaChecker, SchemaError } from './schemaChecker';
import { memoized } from './memoized.decorator';
export { Spec };

function checkDocumentSchema(doc: { [k: string]: any }) {
function checkDocumentSchema(doc: Spec.JsonApiDocument) {
SchemaChecker.fromData(doc, 'Document')
.singleObject()
.atLeastOneOf(['data', 'errors', 'meta'])
.allowedMembers(['data', 'errors', 'meta', 'jsonapi', 'links', 'included']);
if ('data' in doc) {
const res: object[] = Array.isArray(doc['data']) ? doc['data'] : [doc['data']];
for (const r of res) {
checkResourceObjectSchema(r);
if (Array.isArray(doc['data'])) {
for (const r of doc['data'] as object[]) {
checkResourceObjectSchema(r);
}
} else if (doc['data'] !== undefined) {
checkResourceObjectSchema(doc['data']);
}
}
}

function checkResourceObjectSchema(res: object) {
function checkResourceObjectSchema(res: object | null) {
if (res === null) {
return;
}
Expand Down Expand Up @@ -121,6 +124,7 @@ export namespace JsonApi {
@memoized()
get includedResources(): IncludedResourcesMap {
const res: IncludedResourcesMap = {};
// tslint:disable-next-line:strict-boolean-expressions
for (const includedResource of this.rawData.included || []) {
if (!(includedResource.type in res)) {
res[includedResource.type] = {};
Expand All @@ -146,19 +150,17 @@ export namespace JsonApi {
export class RelatedResourceAccessor<T extends RelationshipToResource> implements ProxyHandler<T> {
constructor(private readonly parent: Resource) {}
async get(target: T, relationshipName: string, receiver: any): Promise<Resource | null | undefined> {
const rel = this.parent.relationships[relationshipName];
if (rel !== undefined) {
return rel.resource();
if (relationshipName in this.parent.relationships) {
return this.parent.relationships[relationshipName].resource();
}
}
}

export class RelatedResourcesAccessor<T extends RelationshipToResources> implements ProxyHandler<T> {
constructor(private readonly parent: Resource) {}
async get(target: T, relationshipName: string, receiver: any): Promise<Resource[]> {
const rel = this.parent.relationships[relationshipName];
if (rel !== undefined) {
return rel.resources();
if (relationshipName in this.parent.relationships) {
return this.parent.relationships[relationshipName].resources();
}
return [];
}
Expand All @@ -167,9 +169,8 @@ export namespace JsonApi {
export class RelatedDocumentAccessor<T extends RelationshipToDocument> implements ProxyHandler<T> {
constructor(private readonly parent: Resource) {}
async get(target: T, relationshipName: string, receiver: any): Promise<Document | undefined> {
const rel = this.parent.relationships[relationshipName];
if (rel !== undefined) {
return rel.relatedDocument();
if (relationshipName in this.parent.relationships) {
return this.parent.relationships[relationshipName].relatedDocument();
}
}
}
Expand Down Expand Up @@ -330,6 +331,7 @@ export namespace JsonApi {
const primaryDataArray = this.document.hasManyResources
? <Spec.ResourceObject[]>this.document.rawData.data
: [<Spec.ResourceObject>this.document.rawData.data];
// tslint:disable-next-line:strict-boolean-expressions
const candidates = primaryDataArray.concat(this.document.rawData.included || []);
const filtered = candidates.filter(
resourceObject => resourceObject.type === this.type && resourceObject.id === this.id
Expand Down Expand Up @@ -483,11 +485,11 @@ export namespace JsonApi {
}

export class ClientDocument {
private rawData: Spec.ClientJsonApiDocument;
private readonly rawData: Spec.ClientJsonApiDocument;

constructor(resourceType: string, id?: string) {
this.rawData = { data: { type: resourceType } };
if (id) {
if (id !== undefined) {
this.rawData.data.id = id;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/jsonapiSpec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { XOR } from './typeHelpers';
* https://jsonapi.org/format/#document-meta
*/
export type MetaObject = {
links?: LinksObject,
[propName: string]: any;
};

Expand Down
10 changes: 5 additions & 5 deletions src/memoized.decorator.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,19 +10,19 @@ export function memoized() {
descriptor.get = newFunction(descriptor.get, propName);
return descriptor;
}
if (descriptor.value) {
descriptor.value = newFunction(descriptor.value, propName);
if (descriptor.value && typeof descriptor.value === 'function') {
descriptor.value = newFunction(<() => any>descriptor.value, propName);
return descriptor;
}
throw new TypeError('@memoized works only on getters and methods without arguments');
};
}

function newFunction(original: () => any, propName: string) {
return function(...args: any[]) {
function newFunction(original: () => any, propName: string): () => any {
return function (this: {[k: string]: any}, ...args: any[]): any {
if (args.length > 0) {
throw new TypeError('@memoized works only on methods without arguments');
}
return this.hasOwnProperty(propName) ? this[propName] : (this[propName] = original.apply(this, args));
return this.hasOwnProperty(propName) ? this[propName] : (this[propName] = original.apply(this));
};
}
5 changes: 4 additions & 1 deletion tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@
"lib": ["dom", "es2015", "es2016.array.include"],
"esModuleInterop": true,
"noImplicitAny": true,
"noImplicitThis": true,
"strictNullChecks": true,
"alwaysStrict": true,
"noUnusedLocals": true
"noUnusedLocals": true,
"forceConsistentCasingInFileNames": true,
"strict": true
},
"exclude": ["lib", "**/*.spec.ts"]
}
10 changes: 9 additions & 1 deletion tslint.json
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
"unified-signatures": true,
"triple-equals": true,
"strict-type-predicates": true,
"strict-boolean-expressions": true,
"strict-boolean-expressions": [true, "allow-undefined-union"],
"return-undefined": true,
"quotemark": false,
"promise-function-async": true,
Expand All @@ -36,6 +36,14 @@
"no-this-assignment": true,
"no-trailing-whitespace": true,
"no-irregular-whitespace": true,
"no-duplicate-super": true,
"no-duplicate-switch-case": true,
"no-duplicate-variable": true,
"no-return-await": true,
"no-shadowed-variable": true,
"no-unused-expression": true,
"no-floating-promises": true,
"no-invalid-this": true,
"semicolon": true,
"trailing-comma": true
}
Expand Down

0 comments on commit 74287e5

Please sign in to comment.