Skip to content

Commit

Permalink
feat(dev): introduce strict null checks (#99)
Browse files Browse the repository at this point in the history
* feat(dev): introduce strict null checks

* feat(dev): introduce strict null checks

* fix: comply with strict-null-checks
  • Loading branch information
nishantwrp committed Sep 18, 2024
1 parent 7a643ff commit 4a0b645
Show file tree
Hide file tree
Showing 11 changed files with 89 additions and 26 deletions.
8 changes: 4 additions & 4 deletions src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,12 @@ joplin.plugins.register({
}

const getTemplateAndPerformAction = async (action: TemplateAction) => {
const template: Note = JSON.parse(await getUserTemplateSelection());
const template: Note = JSON.parse(await getUserTemplateSelection() || "null");
await performActionWithParsedTemplate(action, template);
}

const getNotebookDefaultTemplatesDisplayData = async (settings: DefaultTemplatesConfigSetting): Promise<NotebookDefaultTemplatesDisplayData[]> => {
const getDisplayDataForNotebook = async (notebookId: string, defaultTemplateNoteId: string, defaultTemplateTodoId: string): Promise<NotebookDefaultTemplatesDisplayData | null> => {
const getDisplayDataForNotebook = async (notebookId: string, defaultTemplateNoteId: string | null, defaultTemplateTodoId: string | null): Promise<NotebookDefaultTemplatesDisplayData | null> => {
const promiseGroup = new PromiseGroup();
promiseGroup.set("notebook", getFolderFromId(notebookId));
promiseGroup.set("noteTemplate", getTemplateFromId(defaultTemplateNoteId));
Expand Down Expand Up @@ -196,7 +196,7 @@ joplin.plugins.register({
name: "setDefaultTemplateForNotebook",
label: "Set default template for notebook",
execute: async () => {
const folder: Folder | null = JSON.parse(await getUserFolderSelection());
const folder: Folder | null = JSON.parse(await getUserFolderSelection() || "null");
if (folder === null) return;

const templateId = await getUserTemplateSelection("id", `Default template for "${folder.title}":`);
Expand All @@ -214,7 +214,7 @@ joplin.plugins.register({
name: "clearDefaultTemplatesForNotebook",
label: "Clear default templates for notebook",
execute: async () => {
const folder: Folder | null = JSON.parse(await getUserFolderSelection());
const folder: Folder | null = JSON.parse(await getUserFolderSelection() || "null");
if (folder === null) return;

await clearDefaultTemplates(folder.id);
Expand Down
4 changes: 2 additions & 2 deletions src/legacyTemplates.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,8 @@ const getTemplatesTag = async (): Promise<string> => {
export const loadLegacyTemplates = async (dateAndTimeUtils: DateAndTimeUtils, profileDir: string): Promise<void> => {
const fs = joplin.require("fs-extra");

let folderId = null;
let templatesTagId = null;
let folderId: string | null = null;
let templatesTagId: string | null = null;

const templatesDir = `${profileDir}/templates`;

Expand Down
16 changes: 12 additions & 4 deletions src/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { Logger } from "./logger";
import { DateAndTimeUtils } from "./utils/dateAndTime";
import { doesFolderExist } from "./utils/folders";
import { Note } from "./utils/templates";
import { notEmpty } from "./utils/typescript";
import { getVariableFromDefinition } from "./variables/parser";
import { CustomVariable } from "./variables/types/base";
import { setTemplateVariablesView } from "./views/templateVariables";
Expand All @@ -23,6 +24,13 @@ export interface NewNote {
todo_due: number | null;
}

interface NoteMetadata {
title: string;
tags: string[];
folder: string | null;
todo_due: number | null;
}

const NOTE_TITLE_VARIABLE_NAME = "template_title";
const NOTE_TAGS_VARIABLE_NAME = "template_tags";
const NOTE_FOLDER_VARIABLE_NAME = "template_notebook";
Expand Down Expand Up @@ -129,8 +137,8 @@ export class Parser {
return res;
}

private async getNoteMetadata(parsedSpecialVariables: Record<string, string>) {
const meta = {
private async getNoteMetadata(parsedSpecialVariables: Record<string, string>): Promise<NoteMetadata> {
const meta: NoteMetadata = {
title: parsedSpecialVariables.fallback_note_title,
tags: [],
folder: null,
Expand Down Expand Up @@ -183,7 +191,7 @@ export class Parser {
} else {
return null;
}
}).filter(val => !!val);
}).filter(notEmpty);

if (!allMatchesAfterFirstMatch.length) {
return null;
Expand Down Expand Up @@ -229,7 +237,7 @@ export class Parser {
return `${variableDefinitionsBlock}${templateContentBlock}`;
}

public async parseTemplate(template: Note | null): Promise<NewNote> {
public async parseTemplate(template: Note | null): Promise<NewNote | null> {
if (!template) {
return null;
}
Expand Down
6 changes: 3 additions & 3 deletions src/utils/dateAndTime.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,14 @@ export class DateAndTimeUtils {
return `${this.dateFormat} ${this.timeFormat}`;
}

public formatMsToLocal(ms: number, format: string = null): string {
public formatMsToLocal(ms: number, format: string | null = null): string {
if (!format) {
format = this.getDateTimeFormat();
}
return moment(ms).format(format);
}

public formatLocalToJoplinCompatibleUnixTime(input: string, format: string = null): number {
public formatLocalToJoplinCompatibleUnixTime(input: string, format: string | null = null): number {
if (!format) {
format = this.getDateTimeFormat();
}
Expand All @@ -60,7 +60,7 @@ export class DateAndTimeUtils {
return date.unix() * 1000;
}

public getCurrentTime(format: string = null): string {
public getCurrentTime(format: string | null = null): string {
return this.formatMsToLocal(new Date().getTime(), format);
}

Expand Down
6 changes: 6 additions & 0 deletions src/utils/typescript.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
/** Can be used to filter non empty values from a collection while adhering to typescript
* strict null checks.
*/
export function notEmpty<T>(value: T | null | undefined): value is T {
return value !== null && value !== undefined;
}
4 changes: 4 additions & 0 deletions src/variables/parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,4 +32,8 @@ export const getVariableFromDefinition = (name: string, definition: unknown): Cu
throw err;
}
}

// This ideally should never happen. "InvalidCustomVariable" accepts
// all definitions.
throw Error("No valid definition for variable: " + name);
}
2 changes: 1 addition & 1 deletion src/variables/types/base.ts
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,7 @@ export class CustomVariable {
static createFromDefinition(name: string, definition: unknown): CustomVariable {
if (typeof definition === "string" && definition.trim() === this.definitionName) {
return new this(name, name);
} else if (typeof definition === "object") {
} else if (typeof definition === "object" && definition !== null) {
if ("type" in definition) {
const variableType = definition["type"];
if (typeof variableType === "string" && variableType.trim() === this.definitionName) {
Expand Down
2 changes: 1 addition & 1 deletion src/variables/types/enum.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ export class EnumCustomVariable extends CustomVariable {
if (typeof definition === "string") {
const options = this.getOptionsFromType(definition);
return new this(name, name, options);
} else if (typeof definition === "object") {
} else if (typeof definition === "object" && definition !== null) {
if ("type" in definition) {
const variableType = definition["type"];
if (typeof variableType === "string") {
Expand Down
Loading

0 comments on commit 4a0b645

Please sign in to comment.