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 12 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"]
}
}
6 changes: 1 addition & 5 deletions packages/core/src/codecs/json-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,11 +24,7 @@ export default class JsonCodec implements ContentCodec {
private subMediaType: string;

constructor(subMediaType?: string) {
if (!subMediaType) {
this.subMediaType = ContentSerdes.DEFAULT; // 'application/json'
} else {
this.subMediaType = subMediaType;
}
this.subMediaType = subMediaType ?? ContentSerdes.DEFAULT;
}

getMediaType(): string {
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 @@ export default class NetconfCodec implements ContentCodec {
if (hasNamespace) {
// expect to have xmlns
const properties = schema.properties;
if (!properties) {
if (properties == null) {
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) {
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) {
// 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) {
value = payload[key];
}
}
Expand All @@ -102,10 +102,10 @@ export default class NetconfCodec implements ContentCodec {
}
}

if (schema && schema.type && schema.type === "object" && schema.properties) {
if (schema?.type === "object" && schema.properties != null) {
// nested object, go down
let tmpObj;
if (schema.properties && schema["nc:container"]) {
if (schema["nc:container"] != null) {
// check the root level
tmpObj = this.getPayloadNamespaces(schema, payload, NSs, true); // root case
} else {
Expand All @@ -118,10 +118,10 @@ export default class NetconfCodec implements ContentCodec {

// 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) {
// 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) {
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 @@ export default class OctetstreamCodec implements ContentCodec {
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 @@ export default class OctetstreamCodec implements ContentCodec {
}

// 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 @@ export default class OctetstreamCodec implements ContentCodec {
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 @@ export default class OctetstreamCodec implements ContentCodec {

switch (dataType) {
case "boolean":
return Buffer.alloc(length ?? 1, value ? 255 : 0);
return Buffer.alloc(length ?? 1, value != null ? 255 : 0);
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
64 changes: 30 additions & 34 deletions packages/core/src/consumed-thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -166,14 +166,12 @@ 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) {
options.formIndex = this.matchingUnsubscribeForm();
}
options.formIndex ??= this.matchingUnsubscribeForm();
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 +217,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 +254,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 +293,14 @@ 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) {
options.formIndex = this.matchingUnsubscribeForm();
}
options.formIndex ??= this.matchingUnsubscribeForm();

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 +313,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 +446,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 +467,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 +547,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 +596,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 +614,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 +657,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 +687,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 +710,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 +768,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