Skip to content

Commit

Permalink
chore: add guard-for-in eslint rule
Browse files Browse the repository at this point in the history
  • Loading branch information
JKRhb committed Jul 11, 2024
1 parent fe9a15a commit 8e172ad
Show file tree
Hide file tree
Showing 17 changed files with 222 additions and 235 deletions.
1 change: 1 addition & 0 deletions .eslintrc.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ module.exports = {
"@typescript-eslint/prefer-nullish-coalescing": "error",
"unused-imports/no-unused-imports": "error",
"@typescript-eslint/strict-boolean-expressions": "error",
"guard-for-in": "error",
"unused-imports/no-unused-vars": [
"warn",
{
Expand Down
4 changes: 2 additions & 2 deletions packages/binding-coap/src/mdns-introducer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,8 +73,8 @@ export class MdnsIntroducer {
private determineTarget(): string {
const interfaces = networkInterfaces();

for (const iface in interfaces) {
for (const entry of interfaces[iface] ?? []) {
for (const iface of Object.values(interfaces ?? {})) {
for (const entry of iface ?? []) {
if (entry.internal === false) {
if (entry.family === this.ipAddressFamily) {
return entry.address;
Expand Down
4 changes: 2 additions & 2 deletions packages/binding-http/src/http-browser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,8 +54,8 @@ export class HttpForm extends TD.Form {

Headers.prototype.raw = function () {
const result: { [key: string]: string[] } = {};
for (const h in this.entries()) {
result[h[0]] = h[1].split(",");
for (const [headerKey, headerValue] of this.entries()) {
result[headerKey] = headerValue.split(",");
}
return result;
};
Expand Down
32 changes: 14 additions & 18 deletions packages/binding-http/src/routes/thing-description.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,35 +26,31 @@ function resetMultiLangInteraction(
interactions: ThingDescription["properties"] | ThingDescription["actions"] | ThingDescription["events"],
prefLang: string
) {
if (interactions) {
for (const interName in interactions) {
if (interactions != null) {
for (const interaction of Object.values(interactions)) {
// unset any current title and/or description
delete interactions[interName].title;
delete interactions[interName].description;
delete interaction.title;
delete interaction.description;

// use new language title
const titles = interactions[interName].titles;
if (titles) {
for (const titleLang in titles) {
if (titleLang.startsWith(prefLang)) {
interactions[interName].title = titles[titleLang];
}
for (const [titleLang, titleValue] of Object.entries(interaction.titles ?? {})) {
if (titleLang.startsWith(prefLang)) {
interaction.title = titleValue;
break;
}
}

// use new language description
const descriptions = interactions[interName].descriptions;
if (descriptions) {
for (const descLang in descriptions) {
if (descLang.startsWith(prefLang)) {
interactions[interName].description = descriptions[descLang];
}
for (const [descLang, descriptionValue] of Object.entries(interaction.descriptions ?? {})) {
if (descLang.startsWith(prefLang)) {
interaction.description = descriptionValue;
break;
}
}

// unset any multilanguage titles and/or descriptions
delete interactions[interName].titles;
delete interactions[interName].descriptions;
delete interaction.titles;
delete interaction.descriptions;
}
}
}
Expand Down
6 changes: 3 additions & 3 deletions packages/binding-mqtt/src/mqtt-broker-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -108,15 +108,15 @@ export default class MqttBrokerServer implements ProtocolServer {

this.things.set(name, thing);

for (const propertyName in thing.properties) {
for (const propertyName of Object.keys(thing.properties)) {
this.exposeProperty(name, propertyName, thing);
}

for (const actionName in thing.actions) {
for (const actionName of Object.keys(thing.actions)) {
this.exposeAction(name, actionName, thing);
}

for (const eventName in thing.events) {
for (const eventName of Object.keys(thing.events)) {
this.exposeEvent(name, eventName, thing);
}

Expand Down
5 changes: 3 additions & 2 deletions packages/binding-netconf/src/codecs/netconf-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,8 +126,9 @@ export default class NetconfCodec {
let nsFound = false;
let aliasNs = "";
let value;
for (const key in properties) {
const el = properties[key];
// TODO: Use correct type for el
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for (const [key, el] of Object.entries(properties) as [string, any]) {
const payloadField = payload[key];
if (payloadField == null) {
throw new Error(`Payload is missing '${key}' field specified in TD`);
Expand Down
17 changes: 6 additions & 11 deletions packages/binding-websockets/src/ws-server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -120,8 +120,8 @@ export default class WebSocketServer implements ProtocolServer {
public stop(): Promise<void> {
debug(`WebSocketServer stopping on port ${this.port}`);
return new Promise<void>((resolve, reject) => {
for (const pathSocket in this.socketServers) {
this.socketServers[pathSocket].close();
for (const socketServer of Object.values(this.socketServers)) {
socketServer.close();
}

// stop promise handles all errors from now on
Expand Down Expand Up @@ -162,15 +162,14 @@ export default class WebSocketServer implements ProtocolServer {

// TODO more efficient routing to ExposedThing without ResourceListeners in each server

for (const propertyName in thing.properties) {
for (const [propertyName, property] of Object.entries(thing.properties)) {
const path =
"/" +
encodeURIComponent(urlPath) +
"/" +
this.PROPERTY_DIR +
"/" +
encodeURIComponent(propertyName);
const property = thing.properties[propertyName];

// Populate forms related to the property
for (const address of Helpers.getAddresses()) {
Expand Down Expand Up @@ -231,26 +230,22 @@ export default class WebSocketServer implements ProtocolServer {
});
}

for (const actionName in thing.actions) {
for (const [actionName, action] of Object.entries(thing.actions)) {
const path =
"/" + encodeURIComponent(urlPath) + "/" + this.ACTION_DIR + "/" + encodeURIComponent(actionName);
// eslint-disable-next-line unused-imports/no-unused-vars
const action = thing.actions[actionName];

for (const address of Helpers.getAddresses()) {
const href = `${this.scheme}://${address}:${this.getPort()}${path}`;
const form = new TD.Form(href, ContentSerdes.DEFAULT);
form.op = ["invokeaction"];
thing.actions[actionName].forms.push(form);
action.forms.push(form);
debug(`WebSocketServer on port ${this.getPort()} assigns '${href}' to Action '${actionName}'`);
}
}

for (const eventName in thing.events) {
for (const [eventName, event] of Object.entries(thing.events)) {
const path =
"/" + encodeURIComponent(urlPath) + "/" + this.EVENT_DIR + "/" + encodeURIComponent(eventName);
// eslint-disable-next-line unused-imports/no-unused-vars
const event = thing.events[eventName];

// Populate forms related to the event
for (const address of Helpers.getAddresses()) {
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/codecs/netconf-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -79,8 +79,9 @@ export default class NetconfCodec implements ContentCodec {
let nsFound = false;
let aliasNs = "";
let value;
for (const key in properties) {
const el = properties[key];
// TODO: Use correct type for el
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for (const [key, el] of Object.entries(properties) as [string, any]) {
if (payload[key] == null) {
throw new Error(`Payload is missing '${key}' field specified in TD`);
}
Expand Down
5 changes: 3 additions & 2 deletions packages/core/src/codecs/octetstream-codec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -604,11 +604,12 @@ export default class OctetstreamCodec implements ContentCodec {
}

result = result ?? Buffer.alloc(length);
for (const propertyName in schema.properties) {
// TODO: Use correct type for propertySchema
// eslint-disable-next-line @typescript-eslint/no-explicit-any
for (const [propertyName, propertySchema] of Object.entries(schema.properties) as [string, any]) {
if (Object.hasOwnProperty.call(value, propertyName) === false) {
throw new Error(`Missing property '${propertyName}'`);
}
const propertySchema = schema.properties[propertyName];
const propertyValue = value[propertyName];
const propertyOffset = parseInt(propertySchema["ex:bitOffset"]);
const propertyLength = parseInt(propertySchema["ex:bitLength"]);
Expand Down
26 changes: 11 additions & 15 deletions packages/core/src/consumed-thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,19 +381,16 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
}

extendInteractions(): void {
for (const propertyName in this.properties) {
const newProp = Helpers.extend(
this.properties[propertyName],
new ConsumedThingProperty(propertyName, this)
);
for (const [propertyName, property] of Object.entries(this.properties)) {
const newProp = Helpers.extend(property, new ConsumedThingProperty(propertyName, this));
this.properties[propertyName] = newProp;
}
for (const actionName in this.actions) {
const newAction = Helpers.extend(this.actions[actionName], new ConsumedThingAction(actionName, this));
for (const [actionName, action] of Object.entries(this.actions)) {
const newAction = Helpers.extend(action, new ConsumedThingAction(actionName, this));
this.actions[actionName] = newAction;
}
for (const eventName in this.events) {
const newEvent = Helpers.extend(this.events[eventName], new ConsumedThingEvent(eventName, this));
for (const [eventName, event] of Object.entries(this.events)) {
const newEvent = Helpers.extend(event, new ConsumedThingEvent(eventName, this));
this.events[eventName] = newEvent;
}
}
Expand Down Expand Up @@ -612,14 +609,15 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {

readAllProperties(options?: WoT.InteractionOptions): Promise<WoT.PropertyReadMap> {
const propertyNames: string[] = [];
for (const propertyName in this.properties) {

for (const [propertyName, property] of Object.entries(this.properties)) {
// collect attributes that are "readable" only
const tp = this.properties[propertyName];
const { form } = this.getClientFor(tp.forms, "readproperty", Affordance.PropertyAffordance, options);
const { form } = this.getClientFor(property.forms, "readproperty", Affordance.PropertyAffordance, options);
if (form != null) {
propertyNames.push(propertyName);
}
}

return this._readProperties(propertyNames);
}

Expand Down Expand Up @@ -656,9 +654,7 @@ export default class ConsumedThing extends TD.Thing implements IConsumedThing {
async writeMultipleProperties(valueMap: WoT.PropertyWriteMap, options?: WoT.InteractionOptions): Promise<void> {
// collect all single promises into array
const promises: Promise<void>[] = [];
for (const propertyName in valueMap) {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
const value = valueMap.get(propertyName)!;
for (const [propertyName, value] of valueMap.entries()) {
promises.push(this.writeProperty(propertyName, value));
}
// wait for all promises to succeed and create response
Expand Down
12 changes: 4 additions & 8 deletions packages/core/src/exposed-thing.ts
Original file line number Diff line number Diff line change
Expand Up @@ -458,10 +458,7 @@ export default class ExposedThing extends TD.Thing implements WoT.ExposedThing {
public async handleReadAllProperties(
options: WoT.InteractionOptions & { formIndex: number }
): Promise<PropertyContentMap> {
const propertyNames: string[] = [];
for (const propertyName in this.properties) {
propertyNames.push(propertyName);
}
const propertyNames = Object.keys(this.properties);
return await this._handleReadProperties(propertyNames, options);
}

Expand Down Expand Up @@ -513,16 +510,15 @@ export default class ExposedThing extends TD.Thing implements WoT.ExposedThing {
): Promise<void> {
// collect all single promises into array
const promises: Promise<void>[] = [];
for (const propertyName in valueMap) {
for (const [propertyName, property] of Object.entries(valueMap)) {
// Note: currently only DataSchema properties are supported
const form = this.properties[propertyName].forms.find(
(form) => form.contentType === "application/json" || form.contentType == null
);
if (!form) {
if (form == null) {
continue;
}
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion -- we know that the property exists
promises.push(this.handleWriteProperty(propertyName, valueMap.get(propertyName)!, options));
promises.push(this.handleWriteProperty(propertyName, property, options));
}
try {
await Promise.all(promises);
Expand Down
22 changes: 10 additions & 12 deletions packages/core/src/helpers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -87,8 +87,8 @@ export default class Helpers implements Resolver {
} else {
const interfaces = os.networkInterfaces();

for (const iface in interfaces) {
interfaces[iface]?.forEach((entry) => {
for (const iface of Object.values(interfaces)) {
iface?.forEach((entry) => {
debug(`AddressHelper found ${entry.address}`);
if (entry.internal === false) {
if (entry.family === "IPv4") {
Expand Down Expand Up @@ -197,12 +197,12 @@ export default class Helpers implements Resolver {
*/
public static extend<T, U>(first: T, second: U): T & U {
const result = <T & U>{};
for (const id in first) {
(<Record<string, unknown>>result)[id] = (<Record<string, unknown>>first)[id];
for (const [id, value] of Object.entries(first as Record<string, unknown>)) {
(<Record<string, unknown>>result)[id] = value;
}
for (const id in second) {
for (const [id, value] of Object.entries(second as Record<string, unknown>)) {
if (!Object.prototype.hasOwnProperty.call(result, id)) {
(<Record<string, unknown>>result)[id] = (<Record<string, unknown>>second)[id];
(<Record<string, unknown>>result)[id] = value;
}
}
return result;
Expand Down Expand Up @@ -242,9 +242,9 @@ export default class Helpers implements Resolver {
}
}

if (tdSchemaCopy.definitions !== undefined) {
for (const prop in tdSchemaCopy.definitions) {
tdSchemaCopy.definitions[prop] = this.createExposeThingInitSchema(tdSchemaCopy.definitions[prop]);
if (tdSchemaCopy.definitions != null) {
for (const [prop, propValue] of Object.entries(tdSchemaCopy.definitions) ?? []) {
tdSchemaCopy.definitions[prop] = this.createExposeThingInitSchema(propValue);
}
}

Expand Down Expand Up @@ -307,9 +307,7 @@ export default class Helpers implements Resolver {
options = { uriVariables: {} };
}

for (const varKey in thingUriVariables) {
const varValue = thingUriVariables[varKey];

for (const [varKey, varValue] of Object.entries(thingUriVariables)) {
if (!(varKey in uriVariables) && "default" in varValue) {
uriVariables[varKey] = varValue.default;
}
Expand Down
27 changes: 12 additions & 15 deletions packages/core/src/servient.ts
Original file line number Diff line number Diff line change
Expand Up @@ -54,20 +54,20 @@ export default class Servient {

// initializing forms fields
thing.forms = [];
for (const name in thing.properties) {
for (const property of Object.values(thing.properties)) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
thing.properties[name].forms = [];
property.forms = [];
}
for (const name in thing.actions) {
for (const action of Object.values(thing.actions)) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
thing.actions[name].forms = [];
action.forms = [];
}
for (const name in thing.events) {
for (const event of Object.values(thing.events)) {
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
// @ts-ignore
thing.events[name].forms = [];
event.forms = [];
}

const serverPromises: Promise<void>[] = [];
Expand Down Expand Up @@ -178,16 +178,13 @@ export default class Servient {
}

public addCredentials(credentials: Record<string, unknown>): void {
if (typeof credentials === "object") {
for (const i in credentials) {
debug(`Servient storing credentials for '${i}'`);
let currentCredentials = this.credentialStore.get(i);
if (!currentCredentials) {
currentCredentials = [];
this.credentialStore.set(i, currentCredentials);
}
currentCredentials.push(credentials[i]);
for (const [credentialKey, credentialValue] of Object.entries(credentials ?? {})) {
debug(`Servient storing credentials for '${credentialKey}'`);
const currentCredentials = this.credentialStore.get(credentialKey) ?? [];
if (currentCredentials.length === 0) {
this.credentialStore.set(credentialKey, currentCredentials);
}
currentCredentials.push(credentialValue);
}
}

Expand Down
Loading

0 comments on commit 8e172ad

Please sign in to comment.