Skip to content

Commit ad0f39c

Browse files
committed
fix: enable strict properties, begin fixing errors
1 parent b3afa71 commit ad0f39c

22 files changed

+126
-238
lines changed

config/tsconfig.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,11 @@
1919
"noImplicitThis": true,
2020
"paths": {},
2121
"sourceMap": true,
22+
"strict": true,
2223
"strictBindCallApply": true,
2324
"strictFunctionTypes": true,
2425
"strictNullChecks": true,
26+
"strictPropertyInitialization": true,
2527
"target": "es2017",
2628
"types": [
2729
"chai-as-promised",

src/Bot.ts

Lines changed: 16 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ import { ContextFetchOptions, Listener, ListenerData } from 'src/listener/Listen
1414
import { ServiceModule } from 'src/module/ServiceModule';
1515
import { Parser, ParserData } from 'src/parser/Parser';
1616
import { Service, ServiceDefinition, ServiceEvent } from 'src/Service';
17-
import { filterNil, mustFind } from 'src/utils';
17+
import { filterNil, mustFind, mustExist } from 'src/utils';
1818
import { incrementServiceCounter } from 'src/utils/metrics/Service';
1919
import { StorageLogger, StorageLoggerOptions } from 'src/utils/StorageLogger';
2020

@@ -39,11 +39,11 @@ export class Bot extends BaseService<BotData> implements Service {
3939
protected readonly container: Container;
4040
protected readonly metrics: Registry;
4141

42-
protected storage: Connection;
42+
protected storage?: Connection;
4343

4444
// counters
45-
protected cmdCounter: Counter;
46-
protected msgCounter: Counter;
45+
protected cmdCounter!: Counter;
46+
protected msgCounter!: Counter;
4747

4848
// services
4949
protected controllers: Array<Controller>;
@@ -77,11 +77,11 @@ export class Bot extends BaseService<BotData> implements Service {
7777
this.incoming = new Subject();
7878
this.outgoing = new Subject();
7979

80-
bindAll(this, 'looseError');
80+
this.startMetrics();
8181
}
8282

8383
public getStorage(): Connection {
84-
return this.storage;
84+
return mustExist(this.storage);
8585
}
8686

8787
public async notify(event: ServiceEvent) {
@@ -103,17 +103,13 @@ export class Bot extends BaseService<BotData> implements Service {
103103
*/
104104
public async start() {
105105
await super.start();
106-
107106
this.logger.info('starting bot');
108107

109-
this.logger.info('setting up streams');
110-
/* tslint:disable:no-unbound-method */
111-
this.commands.subscribe((next) => this.receiveCommand(next).catch(this.looseError));
112-
this.incoming.subscribe((next) => this.receive(next).catch(this.looseError));
113-
this.outgoing.subscribe((next) => this.receiveMessage(next).catch(this.looseError));
114-
/* tslint:enable */
108+
const streamError = (err: Error) => this.looseError(err);
109+
this.commands.subscribe((next) => this.receiveCommand(next).catch(streamError));
110+
this.incoming.subscribe((next) => this.receive(next).catch(streamError));
111+
this.outgoing.subscribe((next) => this.receiveMessage(next).catch(streamError));
115112

116-
await this.startMetrics();
117113
await this.startStorage();
118114
await this.startServices();
119115

@@ -174,9 +170,10 @@ export class Bot extends BaseService<BotData> implements Service {
174170
* Add a message to the send queue.
175171
*/
176172
public async sendMessage(...messages: Array<Message>): Promise<Array<Message>> {
173+
const storage = mustExist(this.storage);
177174
const results = [];
178175
for (const data of messages) {
179-
const msg = await this.storage.getRepository(Message).save(data);
176+
const msg = await storage.getRepository(Message).save(data);
180177
this.logger.debug({ msg }, 'message saved');
181178
this.outgoing.next(msg);
182179
results.push(msg);
@@ -185,9 +182,10 @@ export class Bot extends BaseService<BotData> implements Service {
185182
}
186183

187184
public async executeCommand(...commands: Array<Command>): Promise<Array<Command>> {
185+
const storage = mustExist(this.storage);
188186
const results = [];
189187
for (const data of commands) {
190-
const cmd = await this.storage.getRepository(Command).save(data);
188+
const cmd = await storage.getRepository(Command).save(data);
191189
this.commands.next(cmd);
192190
results.push(cmd);
193191
}
@@ -281,7 +279,7 @@ export class Bot extends BaseService<BotData> implements Service {
281279
return commands;
282280
}
283281

284-
protected async startMetrics() {
282+
protected startMetrics() {
285283
this.logger.info('setting up metrics');
286284

287285
this.cmdCounter = new Counter({
@@ -354,7 +352,7 @@ export class Bot extends BaseService<BotData> implements Service {
354352
* Note: this method is already bound, so it can be passed with `this.looseError`. Using that requires
355353
* `tslint:disable:no-unbound-method` as well.
356354
*/
357-
protected async looseError(err: Error) {
355+
protected looseError(err: Error) {
358356
this.logger.error(err, 'bot stream did not handle error');
359357
}
360358
}

src/controller/CompletionController.ts

Lines changed: 10 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ export type CompletionControllerOptions = ControllerOptions<CompletionController
2525
export class CompletionController extends BaseController<CompletionControllerData> implements Controller {
2626
protected readonly storage: Connection;
2727
protected readonly fragmentRepository: Repository<Fragment>;
28-
protected target: Listener;
28+
protected target?: Listener;
2929

3030
constructor(options: CompletionControllerOptions) {
3131
super(options, 'isolex#/definitions/service-controller-completion', [NOUN_FRAGMENT]);
@@ -37,7 +37,7 @@ export class CompletionController extends BaseController<CompletionControllerDat
3737
public async start() {
3838
await super.start();
3939

40-
this.target = this.services.getService(this.data.defaultTarget);
40+
this.target = this.services.getService<Listener>(this.data.defaultTarget);
4141
}
4242

4343
@HandleNoun(NOUN_FRAGMENT)
@@ -51,15 +51,14 @@ export class CompletionController extends BaseController<CompletionControllerDat
5151
const parserId = cmd.getHead('parser');
5252
const verb = cmd.getHead('verb') as CommandVerb;
5353

54-
const fragment = await this.fragmentRepository.save(new Fragment({
55-
data: cmd.data,
56-
key,
57-
labels: cmd.labels,
58-
noun,
59-
parserId,
60-
userId: user.id,
61-
verb,
62-
}));
54+
const fragment = new Fragment();
55+
fragment.data = cmd.data;
56+
fragment.key = key;
57+
fragment.labels = cmd.labels;
58+
fragment.noun = noun;
59+
fragment.parserId = parserId;
60+
fragment.userId = user.id;
61+
fragment.verb = verb;
6362

6463
const context = await this.createContext(cmd.context);
6564
this.logger.debug({ context, fragment }, 'creating fragment for later completion');

src/controller/helpers.ts

Lines changed: 7 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,28 +6,27 @@ import { NOUN_FRAGMENT } from 'src/controller/CompletionController';
66
import { Command, CommandVerb } from 'src/entity/Command';
77
import { InvalidArgumentError } from 'src/error/InvalidArgumentError';
88
import { Schema } from 'src/schema';
9-
import { Dict, mapToDict } from 'src/utils/Map';
9+
import { Dict, mapToDict, dictToMap } from 'src/utils/Map';
1010

1111
export function createCompletion(cmd: Command, key: string, msg: string): Command {
1212
if (isNil(cmd.context.parser)) {
1313
throw new InvalidArgumentError('command has no parser to prompt for completion');
1414
}
1515

1616
const existingData = mapToDict(cmd.data);
17-
return new Command({
18-
context: cmd.context,
19-
data: {
17+
const fragment = new Command();
18+
fragment.context = cmd.context;
19+
fragment.data = dictToMap({
2020
...existingData,
2121
key: [key],
2222
msg: [msg],
2323
noun: [cmd.noun],
2424
parser: [cmd.context.parser.id],
2525
verb: [cmd.verb],
26-
},
27-
labels: {},
28-
noun: NOUN_FRAGMENT,
29-
verb: CommandVerb.Create,
3026
});
27+
fragment.noun = NOUN_FRAGMENT;
28+
fragment.verb = CommandVerb.Create;
29+
return fragment;
3130
}
3231

3332
type CollectData = number | string | Array<string>;

src/entity/Command.ts

Lines changed: 4 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -35,18 +35,10 @@ export class Command extends BaseCommand implements CommandOptions {
3535
cascade: true,
3636
})
3737
@JoinColumn()
38-
public context: Context;
38+
public context!: Context;
3939

4040
@PrimaryGeneratedColumn('uuid')
41-
public id: string;
42-
43-
constructor(options?: CommandOptions) {
44-
super(options);
45-
46-
if (options && options.context) {
47-
this.context = options.context;
48-
}
49-
}
41+
public id: string = '';
5042

5143
public extend(options: Partial<CommandOptions>) {
5244
if (options.noun) {
@@ -56,7 +48,8 @@ export class Command extends BaseCommand implements CommandOptions {
5648
throw new InvalidArgumentError('extended commands may not change verb');
5749
}
5850

59-
const cmd = new Command(this);
51+
const cmd = new Command();
52+
Object.assign(cmd, this); // TODO: is this right?
6053
if (options.context) {
6154
cmd.context = options.context;
6255
}

src/entity/Context.ts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -47,13 +47,13 @@ export const TABLE_CONTEXT = 'context';
4747
@Entity(TABLE_CONTEXT)
4848
export class Context extends BaseEntity implements ContextOptions {
4949
@Column('simple-json')
50-
public channel: ChannelData;
50+
public channel!: ChannelData;
5151

5252
@PrimaryGeneratedColumn('uuid')
53-
public id: string;
53+
public id: string = '';
5454

5555
@Column()
56-
public name: string;
56+
public name: string = '';
5757

5858
public parser?: Parser;
5959

@@ -64,7 +64,7 @@ export class Context extends BaseEntity implements ContextOptions {
6464
public token?: Token;
6565

6666
@Column()
67-
public uid: string;
67+
public uid: string = '';
6868

6969
public user?: User;
7070

src/entity/Fragment.ts

Lines changed: 4 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -25,30 +25,16 @@ export interface FragmentOptions extends CommandOptions {
2525
@Entity(TABLE_FRAGMENT)
2626
export class Fragment extends BaseCommand implements FragmentOptions {
2727
@PrimaryGeneratedColumn('uuid')
28-
public id: string;
28+
public id: string = '';
2929

3030
@Column()
31-
public key: string;
31+
public key: string = '';
3232

3333
@Column()
34-
public parserId: string;
34+
public parserId: string = '';
3535

3636
@Column()
37-
public userId: string;
38-
39-
constructor(options?: FragmentOptions) {
40-
super(options);
41-
42-
if (!isNil(options)) {
43-
this.data = dictToMap(options.data);
44-
this.key = options.key;
45-
this.labels = dictToMap(options.labels);
46-
this.noun = options.noun;
47-
this.parserId = options.parserId;
48-
this.userId = options.userId;
49-
this.verb = options.verb;
50-
}
51-
}
37+
public userId: string = '';
5238

5339
public toJSON() {
5440
return {

src/entity/Message.ts

Lines changed: 11 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { LabelEntity } from 'src/entity/base/LabelEntity';
55
import { Context, GRAPH_OUTPUT_CONTEXT } from 'src/entity/Context';
66
import { GRAPH_INPUT_NAME_MULTI_VALUE_PAIR, GRAPH_INPUT_NAME_VALUE_PAIR } from 'src/schema/graph/input/Pairs';
77
import { GRAPH_OUTPUT_NAME_MULTI_VALUE_PAIR, GRAPH_OUTPUT_NAME_VALUE_PAIR } from 'src/schema/graph/output/Pairs';
8+
import { TYPE_TEXT } from 'src/utils/Mime';
89

910
export interface MessageOptions {
1011
body: string;
@@ -22,46 +23,34 @@ export class Message extends LabelEntity implements MessageOptions {
2223
}
2324

2425
public static reply(context: Context, type: string, body: string): Message {
25-
return new Message({
26-
body,
27-
context,
28-
reactions: [],
29-
type,
30-
});
26+
const msg = new Message();
27+
msg.body = body;
28+
msg.context = context;
29+
msg.type = type;
30+
return msg;
3131
}
3232

3333
@Column()
34-
public body: string;
34+
public body: string = '';
3535

3636
@OneToOne((type) => Context, (context) => context.id, {
3737
cascade: true,
3838
})
3939
@JoinColumn()
40-
public context: Context;
40+
public context!: Context;
4141

4242
@PrimaryGeneratedColumn('uuid')
43-
public id: string;
43+
public id: string = '';
4444

4545
@Column('simple-json')
46-
public reactions: Array<string>;
46+
public reactions: Array<string> = [];
4747

4848
/**
4949
* MIME type of the message. Typically `text/plain`, but can be an `image/*` or `audio/*` type, depending on the
5050
* listener.
5151
*/
5252
@Column()
53-
public type: string;
54-
55-
constructor(options?: MessageOptions) {
56-
super();
57-
58-
if (options) {
59-
this.body = options.body;
60-
this.context = options.context;
61-
this.reactions = Array.from(options.reactions || []);
62-
this.type = options.type;
63-
}
64-
}
53+
public type: string = TYPE_TEXT;
6554

6655
public toJSON(): object {
6756
return {

src/entity/Tick.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@ export const TABLE_TICK = 'tick';
88
@Entity(TABLE_TICK)
99
export class Tick extends BaseEntity {
1010
@PrimaryGeneratedColumn('uuid')
11-
public id: string;
11+
public id: string = '';
1212

1313
@Column()
14-
public intervalId: string;
14+
public intervalId: string = '';
1515

1616
@Column()
17-
public status: number;
17+
public status: number = 0;
1818

1919
public toJSON(): object {
2020
return {

src/entity/auth/Role.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,24 +13,15 @@ export const TABLE_ROLE = 'role';
1313
@Entity(TABLE_ROLE)
1414
export class Role extends BaseEntity implements RoleOptions {
1515
@PrimaryGeneratedColumn('uuid')
16-
public id: string;
16+
public id: string = '';
1717

1818
@Column({
1919
unique: true,
2020
})
21-
public name: string;
21+
public name: string = '';
2222

2323
@Column('simple-json')
24-
public grants: Array<string>;
25-
26-
constructor(options?: RoleOptions) {
27-
super();
28-
29-
if (options) {
30-
this.grants = Array.from(options.grants);
31-
this.name = options.name;
32-
}
33-
}
24+
public grants: Array<string> = [];
3425

3526
public toJSON() {
3627
return {

0 commit comments

Comments
 (0)