Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

chore(core): enable eslint/strict-boolean-expressions & strictNullChecks #1096

Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
Show all changes
21 commits
Select commit Hold shift + click to select a range
c27de2c
chore(core): enable eslint/strict-boolean-expressions & strictNullChecks
danielpeintner Sep 22, 2023
919518c
fix problem
danielpeintner Sep 22, 2023
e2f5a08
fix remaining problems for consumed-thing.ts
danielpeintner Sep 22, 2023
9ea628b
Update packages/core/src/consumed-thing.ts
danielpeintner Sep 25, 2023
50f06b3
Update packages/core/src/consumed-thing.ts
danielpeintner Sep 25, 2023
994e1a7
refactor: simplification proposed by Jan
danielpeintner Sep 25, 2023
c8dddc8
Update packages/core/src/exposed-thing.ts
danielpeintner Sep 25, 2023
72691c3
Update packages/core/src/exposed-thing.ts
danielpeintner Sep 25, 2023
73fc642
refactor: simplification proposed by Jan
danielpeintner Sep 25, 2023
84949e3
Update packages/core/src/exposed-thing.ts
danielpeintner Sep 25, 2023
532c674
Update packages/core/src/helpers.ts
danielpeintner Sep 25, 2023
f3987b8
Update packages/core/src/protocol-helpers.ts
danielpeintner Sep 25, 2023
6cfe425
Update packages/core/src/protocol-helpers.ts
danielpeintner Sep 25, 2023
ac41e50
Update packages/core/src/wot-impl.ts
danielpeintner Sep 25, 2023
f49175d
Update packages/core/src/exposed-thing.ts
danielpeintner Sep 25, 2023
0f1b2a0
refactor: reverting one step
danielpeintner Sep 25, 2023
ca24f56
Update packages/core/src/consumed-thing.ts
danielpeintner Sep 25, 2023
567fe1e
refactor: simplify
danielpeintner Sep 25, 2023
f5d4f60
Merge branch 'issue-1046-strict-boolean-expressions-core' of https://…
danielpeintner Sep 25, 2023
53d316b
Update packages/core/src/protocol-helpers.ts
danielpeintner Sep 25, 2023
17cb5ce
Update packages/core/src/protocol-helpers.ts
danielpeintner Sep 26, 2023
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/core/.eslintrc.json
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
{
"extends": "../../.eslintrc.js"
"extends": "../../.eslintrc.js",
"rules": {
"@typescript-eslint/strict-boolean-expressions": ["error"]
}
}
2 changes: 1 addition & 1 deletion packages/core/src/codecs/json-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ export default class JsonCodec implements ContentCodec {
private subMediaType: string;

constructor(subMediaType?: string) {
if (!subMediaType) {
if (subMediaType == null) {
this.subMediaType = ContentSerdes.DEFAULT; // 'application/json'
} else {
this.subMediaType = subMediaType;
danielpeintner marked this conversation as resolved.
Show resolved Hide resolved
Expand Down
16 changes: 8 additions & 8 deletions packages/core/src/codecs/netconf-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,24 +73,24 @@
if (hasNamespace) {
// expect to have xmlns
const properties = schema.properties;
if (!properties) {
if (properties == null) {

Check warning on line 76 in packages/core/src/codecs/netconf-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/netconf-codec.ts#L76

Added line #L76 was not covered by tests
throw new Error(`Missing "properties" field in TD`);
}
let nsFound = false;
let aliasNs = "";
let value;
for (const key in properties) {
const el = properties[key];
if (!payload[key]) {
if (payload[key] == null) {

Check warning on line 84 in packages/core/src/codecs/netconf-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/netconf-codec.ts#L84

Added line #L84 was not covered by tests
throw new Error(`Payload is missing '${key}' field specified in TD`);
}
if (el["nc:attribute"] === true && payload[key]) {
if (el["nc:attribute"] === true && payload[key] != null) {

Check warning on line 87 in packages/core/src/codecs/netconf-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/netconf-codec.ts#L87

Added line #L87 was not covered by tests
// if (el.format && el.format === 'urn')
const ns: string = payload[key] as string;
aliasNs = ns.split(":")[ns.split(":").length - 1];
NSs[aliasNs] = payload[key];
nsFound = true;
} else if (payload[key]) {
} else if (payload[key] != null) {

Check warning on line 93 in packages/core/src/codecs/netconf-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/netconf-codec.ts#L93

Added line #L93 was not covered by tests
value = payload[key];
}
}
Expand All @@ -102,10 +102,10 @@
}
}

if (schema && schema.type && schema.type === "object" && schema.properties) {
if (schema?.type === "object" && schema.properties != null) {

Check warning on line 105 in packages/core/src/codecs/netconf-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/netconf-codec.ts#L105

Added line #L105 was not covered by tests
// nested object, go down
let tmpObj;
if (schema.properties && schema["nc:container"]) {
if (schema["nc:container"] != null) {

Check warning on line 108 in packages/core/src/codecs/netconf-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/netconf-codec.ts#L108

Added line #L108 was not covered by tests
// check the root level
tmpObj = this.getPayloadNamespaces(schema, payload, NSs, true); // root case
} else {
Expand All @@ -118,10 +118,10 @@

// once here schema is properties
for (const key in schema) {
if ((schema[key].type && schema[key].type === "object") || hasNamespace) {
if (schema[key].type === "object" || hasNamespace) {

Check warning on line 121 in packages/core/src/codecs/netconf-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/netconf-codec.ts#L121

Added line #L121 was not covered by tests
// go down only if it is a nested object or it has a namespace
let tmpHasNamespace = false;
if (schema[key].properties && schema[key]["nc:container"]) {
if (schema[key].properties != null && schema[key]["nc:container"] != null) {

Check warning on line 124 in packages/core/src/codecs/netconf-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/netconf-codec.ts#L124

Added line #L124 was not covered by tests
tmpHasNamespace = true;
}
const tmpObj = this.getPayloadNamespaces(
Expand Down
14 changes: 7 additions & 7 deletions packages/core/src/codecs/octetstream-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -59,11 +59,11 @@
debug("OctetstreamCodec parsing", bytes);
debug("Parameters", parameters);

const bigendian = !parameters.byteSeq?.includes(Endianness.LITTLE_ENDIAN); // default to big endian
const bigendian = !(parameters.byteSeq?.includes(Endianness.LITTLE_ENDIAN) === true); // default to big endian
let signed = parameters.signed !== "false"; // default to signed

// check length if specified
if (parameters.length && parseInt(parameters.length) !== bytes.length) {
if (parameters.length != null && parseInt(parameters.length) !== bytes.length) {
throw new Error("Lengths do not match, required: " + parameters.length + " provided: " + bytes.length);
}

Expand All @@ -83,7 +83,7 @@
}

// Handle byte swapping
if (parameters.byteSeq?.includes("BYTE_SWAP") && dataLength > 1) {
if (parameters.byteSeq?.includes("BYTE_SWAP") === true && dataLength > 1) {
bytes.swap16();
}

Expand Down Expand Up @@ -184,13 +184,13 @@
valueToBytes(value: unknown, schema?: DataSchema, parameters: { [key: string]: string | undefined } = {}): Buffer {
debug(`OctetstreamCodec serializing '${value}'`);

if (!parameters.length) {
if (parameters.length == null) {
warn("Missing 'length' parameter necessary for write. I'll do my best");
}

const bigendian = !parameters.byteSeq?.includes(Endianness.LITTLE_ENDIAN); // default to bigendian
const bigendian = !(parameters.byteSeq?.includes(Endianness.LITTLE_ENDIAN) === true); // default to bigendian
let signed = parameters.signed !== "false"; // if signed is undefined -> true (default)
let length = parameters.length ? parseInt(parameters.length) : undefined;
let length = parameters.length != null ? parseInt(parameters.length) : undefined;

if (value === undefined) {
throw new Error("Undefined value");
Expand All @@ -212,7 +212,7 @@

switch (dataType) {
case "boolean":
return Buffer.alloc(length ?? 1, value ? 255 : 0);
return Buffer.alloc(length ?? 1, value != null ? 255 : 0);

Check warning on line 215 in packages/core/src/codecs/octetstream-codec.ts

View check run for this annotation

Codecov / codecov/patch

packages/core/src/codecs/octetstream-codec.ts#L215

Added line #L215 was not covered by tests
case "byte":
case "short":
case "int":
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/codecs/text-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ export default class TextCodec implements ContentCodec {
private subMediaType: string;

constructor(subMediaType?: string) {
this.subMediaType = !subMediaType ? "text/plain" : subMediaType;
this.subMediaType = subMediaType == null ? "text/plain" : subMediaType;
}

getMediaType(): string {
Expand Down
60 changes: 30 additions & 30 deletions packages/core/src/consumed-thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,14 @@ class InternalPropertySubscription extends InternalSubscription {

public async unobserveProperty(options: WoT.InteractionOptions = {}): Promise<void> {
const tp = this.thing.properties[this.name];
if (!tp) {
if (tp == null) {
throw new Error(`ConsumedThing '${this.thing.title}' does not have property ${this.name}`);
}
if (!options.formIndex) {
if (options.formIndex == null) {
options.formIndex = this.matchingUnsubscribeForm();
}
danielpeintner marked this conversation as resolved.
Show resolved Hide resolved
const { form } = this.thing.getClientFor(tp.forms, "unobserveproperty", Affordance.PropertyAffordance, options);
if (!form) {
if (form == null) {
throw new Error(`ConsumedThing '${this.thing.title}' did not get suitable form`);
}

Expand Down Expand Up @@ -219,7 +219,7 @@ class InternalPropertySubscription extends InternalSubscription {
for (let i = 0; i < forms.length; i++) {
let score = 0;
const form = forms[i];
if (form.op === operation || (Array.isArray(form.op) && form.op.includes(operation))) {
if (form.op === operation || (form?.op?.includes(operation) === true && Array.isArray(form.op) === true)) {
JKRhb marked this conversation as resolved.
Show resolved Hide resolved
score += 1;
}

Expand Down Expand Up @@ -256,7 +256,7 @@ function findFormIndexWithScoring(
for (let i = 0; i < forms.length; i++) {
let score = 0;
const form = forms[i];
if (form.op === operation || (Array.isArray(form.op) && form.op.includes(operation))) {
if (form.op === operation || (form?.op?.includes(operation) === true && Array.isArray(form.op) === true)) {
score += 1;
}

Expand Down Expand Up @@ -295,16 +295,16 @@ class InternalEventSubscription extends InternalSubscription {

public async unsubscribeEvent(options: WoT.InteractionOptions = {}): Promise<void> {
const te = this.thing.events[this.name];
if (!te) {
if (te == null) {
throw new Error(`ConsumedThing '${this.thing.title}' does not have event ${this.name}`);
}

if (!options.formIndex) {
if (options.formIndex == null) {
options.formIndex = this.matchingUnsubscribeForm();
}
danielpeintner marked this conversation as resolved.
Show resolved Hide resolved

const { form } = this.thing.getClientFor(te.forms, "unsubscribeevent", Affordance.EventAffordance, options);
if (!form) {
if (form == null) {
throw new Error(`ConsumedThing '${this.thing.title}' did not get suitable form`);
}

Expand All @@ -317,7 +317,7 @@ class InternalEventSubscription extends InternalSubscription {
private matchingUnsubscribeForm(): number {
const refForm = this.thing.events[this.name].forms[this.formIndex];
// Here we have to keep in mind that op default is ["subscribeevent", "unsubscribeevent"]
if (!refForm.op || (Array.isArray(refForm.op) && refForm.op.includes("unsubscribeevent"))) {
if (refForm.op == null || (Array.isArray(refForm.op) && refForm.op.includes("unsubscribeevent"))) {
// we can re-use the same form for unsubscribe
return this.formIndex;
}
Expand Down Expand Up @@ -450,19 +450,19 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
for (const s of security) {
const ws = this.securityDefinitions[s + ""]; // String vs. string (fix wot-typescript-definitions?)
// also push nosec in case of proxy
if (ws) {
if (ws != null) {
scs.push(ws);
}
}
return scs;
}

ensureClientSecurity(client: ProtocolClient, form: TD.Form | undefined): void {
if (this.securityDefinitions) {
if (this.securityDefinitions != null) {
const logStatement = () =>
debug(`ConsumedThing '${this.title}' setting credentials for ${client} based on thing security`);

if (form && Array.isArray(form.security) && form.security.length > 0) {
if (form != null && Array.isArray(form.security) && form.security.length > 0) {
danielpeintner marked this conversation as resolved.
Show resolved Hide resolved
// Note security member in form objects overrides (i.e., completely replace) all definitions activated at the Thing level
// see https://www.w3.org/TR/wot-thing-description/#security-serialization-json

Expand All @@ -471,7 +471,7 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
this.getSecuritySchemes(form.security),
this.getServient().retrieveCredentials(this.id)
);
} else if (this.security && Array.isArray(this.security) && this.security.length > 0) {
} else if (this.security != null && Array.isArray(this.security) && this.security.length > 0) {
danielpeintner marked this conversation as resolved.
Show resolved Hide resolved
logStatement();
client.setSecurity(
this.getSecuritySchemes(this.security as string[]),
JKRhb marked this conversation as resolved.
Show resolved Hide resolved
Expand Down Expand Up @@ -551,15 +551,15 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
async readProperty(propertyName: string, options?: WoT.InteractionOptions): Promise<WoT.InteractionOutput> {
// TODO pass expected form op to getClientFor()
const tp = this.properties[propertyName];
if (!tp) {
if (tp == null) {
throw new Error(`ConsumedThing '${this.title}' does not have property ${propertyName}`);
}

let { client, form } = this.getClientFor(tp.forms, "readproperty", Affordance.PropertyAffordance, options);
if (!form) {
if (form == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable form`);
}
if (!client) {
if (client == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable client for ${form.href}`);
}
debug(`ConsumedThing '${this.title}' reading ${form.href}`);
Expand Down Expand Up @@ -600,7 +600,7 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
// collect attributes that are "readable" only
const tp = this.properties[propertyName];
const { form } = this.getClientFor(tp.forms, "readproperty", Affordance.PropertyAffordance, options);
if (form) {
if (form != null) {
propertyNames.push(propertyName);
}
}
Expand All @@ -618,14 +618,14 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
): Promise<void> {
// TODO pass expected form op to getClientFor()
const tp = this.properties[propertyName];
if (!tp) {
if (tp == null) {
throw new Error(`ConsumedThing '${this.title}' does not have property ${propertyName}`);
}
let { client, form } = this.getClientFor(tp.forms, "writeproperty", Affordance.PropertyAffordance, options);
if (!form) {
if (form == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable form`);
}
if (!client) {
if (client == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable client for ${form.href}`);
}
debug(`ConsumedThing '${this.title}' writing ${form.href} with '${value}'`);
Expand Down Expand Up @@ -661,14 +661,14 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
options?: WoT.InteractionOptions
): Promise<WoT.InteractionOutput> {
const ta = this.actions[actionName];
if (!ta) {
if (ta == null) {
throw new Error(`ConsumedThing '${this.title}' does not have action ${actionName}`);
}
let { client, form } = this.getClientFor(ta.forms, "invokeaction", Affordance.ActionAffordance, options);
if (!form) {
if (form == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable form`);
}
if (!client) {
if (client == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable client for ${form.href}`);
}
debug(
Expand All @@ -691,7 +691,7 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
if (!content.type) content.type = form.contentType ?? "application/json";

// check if returned media type is the same as expected media type (from TD)
if (form.response) {
if (form.response != null) {
if (content.type !== form.response.contentType) {
throw new Error(`Unexpected type in response`);
}
Expand All @@ -714,14 +714,14 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
options?: WoT.InteractionOptions
): Promise<Subscription> {
const tp = this.properties[name];
if (!tp) {
if (tp == null) {
throw new Error(`ConsumedThing '${this.title}' does not have property ${name}`);
}
const { client, form } = this.getClientFor(tp.forms, "observeproperty", Affordance.PropertyAffordance, options);
if (!form) {
if (form == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable form`);
}
if (!client) {
if (client == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable client for ${form.href}`);
}
if (this.observedProperties.has(name)) {
Expand Down Expand Up @@ -772,14 +772,14 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
options?: WoT.InteractionOptions
): Promise<Subscription> {
const te = this.events[name];
if (!te) {
if (te == null) {
throw new Error(`ConsumedThing '${this.title}' does not have event ${name}`);
}
const { client, form } = this.getClientFor(te.forms, "subscribeevent", Affordance.EventAffordance, options);
if (!form) {
if (form == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable form`);
}
if (!client) {
if (client == null) {
throw new Error(`ConsumedThing '${this.title}' did not get suitable client for ${form.href}`);
}
if (this.subscribedEvents.has(name)) {
Expand Down
2 changes: 1 addition & 1 deletion packages/core/src/content-serdes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ export class ContentSerdes {
private offered: Set<string> = new Set<string>();

public static get(): ContentSerdes {
if (!this.instance) {
if (this.instance == null) {
this.instance = new ContentSerdes();
// JSON
this.instance.addCodec(new JsonCodec(), true);
Expand Down
Loading
Loading