From b1f03c0cf42d1902492c86ce0f139279f393d29e Mon Sep 17 00:00:00 2001 From: Mari Date: Sun, 10 Oct 2021 00:43:18 -0400 Subject: [PATCH] Add sleep record (only supports a single record atm though) --- .gulp.json | 5 + gulpfile.js => gulpfile.cjs | 0 package-lock.json | 147 ++++++- package.json | 4 + src/commands/AddEntry.ts | 31 +- src/commands/UpdateEmpathyGuide.ts | 14 +- src/datatypes/Condition.ts | 2 +- src/datatypes/EmpathyGroup.ts | 2 +- src/datatypes/EmpathyGroupList.ts | 2 +- src/datatypes/EmpathyGuide.ts | 4 +- src/datatypes/Entry.ts | 17 +- src/datatypes/GuidedEmpathy.ts | 6 +- src/datatypes/Journal.ts | 4 +- src/datatypes/Persona.ts | 2 +- src/datatypes/SleepRecord.ts | 96 +++++ src/datatypes/Suicidality.ts | 2 +- src/index.ts | 12 +- src/prompts/Inquire.ts | 6 +- .../implementations/ConditionPrompt.ts | 14 +- .../implementations/EmpathyGroupListPrompt.ts | 8 +- .../implementations/EmpathyGroupPrompt.ts | 6 +- .../implementations/EmpathyGuidePrompt.ts | 16 +- .../implementations/EntryMainMenuPrompt.ts | 13 +- src/prompts/implementations/EntryPrompt.ts | 10 +- .../GuidedEmpathyListPrompt.ts | 14 +- .../implementations/GuidedEmpathyPrompt.ts | 14 +- .../implementations/JournalEntryPrompt.ts | 8 +- .../implementations/SleepRecordPrompt.ts | 196 +++++++++ .../implementations/SuicidalityPrompt.ts | 8 +- src/prompts/implementations/SummaryPrompt.ts | 8 +- src/prompts/types/DateInput.ts | 386 ++++++++++++++++++ .../types/HierarchicalCheckboxInput.ts | 19 +- src/prompts/types/MultiTextInput.ts | 8 +- src/prompts/types/index.ts | 8 +- src/repository/LocalRepository.ts | 8 +- src/schemata/SchemaData.ts | 2 +- src/schemata/YAMLPrompt.ts | 4 +- tsconfig.json | 2 +- 38 files changed, 965 insertions(+), 143 deletions(-) create mode 100644 .gulp.json rename gulpfile.js => gulpfile.cjs (100%) create mode 100644 src/datatypes/SleepRecord.ts create mode 100644 src/prompts/implementations/SleepRecordPrompt.ts create mode 100644 src/prompts/types/DateInput.ts diff --git a/.gulp.json b/.gulp.json new file mode 100644 index 0000000..1f8e32b --- /dev/null +++ b/.gulp.json @@ -0,0 +1,5 @@ +{ + "flags": { + "gulpfile": "gulpfile.cjs" + } +} \ No newline at end of file diff --git a/gulpfile.js b/gulpfile.cjs similarity index 100% rename from gulpfile.js rename to gulpfile.cjs diff --git a/package-lock.json b/package-lock.json index ee5da84..53440d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,17 +5,20 @@ "requires": true, "packages": { "": { + "name": "mari-guided-journal", "version": "1.0.0", "license": "ISC", "dependencies": { "ajv": "^8.6.2", "capitalize": "^2.0.3", "chalk": "^2.4.2", + "cli-cursor": "^4.0.0", "env-paths": "^2.2.1", "figures": "^3.2.0", "fuzzy": "^0.1.3", "inquirer": "^8.1.2", "js-yaml": "^4.1.0", + "luxon": "^2.0.2", "make-dir": "^2.1.0", "pluralize": "^8.0.0", "rxjs": "^6.6.7", @@ -30,6 +33,7 @@ "@types/concurrently": "^5.2.1", "@types/inquirer": "^7.3.3", "@types/js-yaml": "^4.0.2", + "@types/luxon": "^2.0.4", "@types/node-fetch": "^2.5.4", "@types/pluralize": "^0.0.29", "@types/yargs": "^17.0.0", @@ -1664,6 +1668,12 @@ "integrity": "sha512-KbeHS/Y4R+k+5sWXEYzAZKuB1yQlZtEghuhRxrVRLaqhtoG5+26JwQsa4HyS3AWX8v1Uwukma5HheduUDskasA==", "dev": true }, + "node_modules/@types/luxon": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.4.tgz", + "integrity": "sha512-l3xuhmyF2kBldy15SeY6d6HbK2BacEcSK1qTF1ISPtPHr29JH0C1fndz9ExXLKpGl0J6pZi+dGp1i5xesMt60Q==", + "dev": true + }, "node_modules/@types/node": { "version": "16.4.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.13.tgz", @@ -2784,14 +2794,17 @@ } }, "node_modules/cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "dependencies": { - "restore-cursor": "^3.1.0" + "restore-cursor": "^4.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/cli-spinners": { @@ -4735,6 +4748,17 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/inquirer/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/inquirer/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -4759,6 +4783,18 @@ "node": ">=8" } }, + "node_modules/inquirer/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/inquirer/node_modules/rxjs": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.3.0.tgz", @@ -5464,6 +5500,14 @@ "node": ">=0.10.0" } }, + "node_modules/luxon": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.0.2.tgz", + "integrity": "sha512-ZRioYLCgRHrtTORaZX1mx+jtxKtKuI5ZDvHNAmqpUzGqSrR+tL4FVLn/CUGMA3h0+AKD1MAxGI5GnCqR5txNqg==", + "engines": { + "node": "*" + } + }, "node_modules/make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -6174,6 +6218,17 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/ora/node_modules/cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "dependencies": { + "restore-cursor": "^3.1.0" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ora/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -6198,6 +6253,18 @@ "node": ">=8" } }, + "node_modules/ora/node_modules/restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "dependencies": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/ora/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7026,15 +7093,18 @@ } }, "node_modules/restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "dependencies": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/ret": { @@ -9558,6 +9628,12 @@ "integrity": "sha512-KbeHS/Y4R+k+5sWXEYzAZKuB1yQlZtEghuhRxrVRLaqhtoG5+26JwQsa4HyS3AWX8v1Uwukma5HheduUDskasA==", "dev": true }, + "@types/luxon": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/@types/luxon/-/luxon-2.0.4.tgz", + "integrity": "sha512-l3xuhmyF2kBldy15SeY6d6HbK2BacEcSK1qTF1ISPtPHr29JH0C1fndz9ExXLKpGl0J6pZi+dGp1i5xesMt60Q==", + "dev": true + }, "@types/node": { "version": "16.4.13", "resolved": "https://registry.npmjs.org/@types/node/-/node-16.4.13.tgz", @@ -10425,11 +10501,11 @@ "dev": true }, "cli-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", - "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz", + "integrity": "sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==", "requires": { - "restore-cursor": "^3.1.0" + "restore-cursor": "^4.0.0" } }, "cli-spinners": { @@ -11992,6 +12068,14 @@ "supports-color": "^7.1.0" } }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -12010,6 +12094,15 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "rxjs": { "version": "7.3.0", "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-7.3.0.tgz", @@ -12550,6 +12643,11 @@ "integrity": "sha512-G2Lj61tXDnVFFOi8VZds+SoQjtQC3dgokKdDG2mTm1tx4m50NUHBOZSBwQQHyy0V12A0JTG4icfZQH+xPyh8VA==", "dev": true }, + "luxon": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/luxon/-/luxon-2.0.2.tgz", + "integrity": "sha512-ZRioYLCgRHrtTORaZX1mx+jtxKtKuI5ZDvHNAmqpUzGqSrR+tL4FVLn/CUGMA3h0+AKD1MAxGI5GnCqR5txNqg==" + }, "make-dir": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-2.1.0.tgz", @@ -13101,6 +13199,14 @@ "supports-color": "^7.1.0" } }, + "cli-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-3.1.0.tgz", + "integrity": "sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==", + "requires": { + "restore-cursor": "^3.1.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -13119,6 +13225,15 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==" }, + "restore-cursor": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", + "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "requires": { + "onetime": "^5.1.0", + "signal-exit": "^3.0.2" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -13773,9 +13888,9 @@ } }, "restore-cursor": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-3.1.0.tgz", - "integrity": "sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-4.0.0.tgz", + "integrity": "sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==", "requires": { "onetime": "^5.1.0", "signal-exit": "^3.0.2" diff --git a/package.json b/package.json index 3c5327a..fcd1149 100644 --- a/package.json +++ b/package.json @@ -12,6 +12,7 @@ "prestart": "npm run --silent build", "debug": "npm run --silent start --inspect" }, + "type": "module", "keywords": [], "author": "Mari", "license": "ISC", @@ -19,11 +20,13 @@ "ajv": "^8.6.2", "capitalize": "^2.0.3", "chalk": "^2.4.2", + "cli-cursor": "^4.0.0", "env-paths": "^2.2.1", "figures": "^3.2.0", "fuzzy": "^0.1.3", "inquirer": "^8.1.2", "js-yaml": "^4.1.0", + "luxon": "^2.0.2", "make-dir": "^2.1.0", "pluralize": "^8.0.0", "rxjs": "^6.6.7", @@ -38,6 +41,7 @@ "@types/concurrently": "^5.2.1", "@types/inquirer": "^7.3.3", "@types/js-yaml": "^4.0.2", + "@types/luxon": "^2.0.4", "@types/node-fetch": "^2.5.4", "@types/pluralize": "^0.0.29", "@types/yargs": "^17.0.0", diff --git a/src/commands/AddEntry.ts b/src/commands/AddEntry.ts index 59c4ffb..760f566 100644 --- a/src/commands/AddEntry.ts +++ b/src/commands/AddEntry.ts @@ -1,17 +1,18 @@ -import {Separator} from "inquirer"; -import {inquire} from "../prompts/Inquire"; -import {summaryPrompt} from "../prompts/implementations/SummaryPrompt"; -import {journalEntryPrompt} from "../prompts/implementations/JournalEntryPrompt"; -import {guidedEmpathyListPrompt} from "../prompts/implementations/GuidedEmpathyListPrompt"; -import {entryMainMenuPrompt} from "../prompts/implementations/EntryMainMenuPrompt"; +import {Separator} from "../prompts/Inquire.js"; +import {inquire} from "../prompts/Inquire.js"; +import {summaryPrompt} from "../prompts/implementations/SummaryPrompt.js"; +import {journalEntryPrompt} from "../prompts/implementations/JournalEntryPrompt.js"; +import {guidedEmpathyListPrompt} from "../prompts/implementations/GuidedEmpathyListPrompt.js"; +import {entryMainMenuPrompt} from "../prompts/implementations/EntryMainMenuPrompt.js"; import {CommandModule} from "yargs"; -import { registerPrompts } from "../prompts/types"; -import {LocalRepository} from "../repository/LocalRepository"; -import {conditionPrompt} from "../prompts/implementations/ConditionPrompt"; -import {entryPrompt} from "../prompts/implementations/EntryPrompt"; -import {guidedEmpathyPrompt} from "../prompts/implementations/GuidedEmpathyPrompt"; -import {suicidalityPrompt} from "../prompts/implementations/SuicidalityPrompt"; -import {yamlPrompt} from "../schemata/YAMLPrompt"; +import { registerPrompts } from "../prompts/types/index.js"; +import {LocalRepository} from "../repository/LocalRepository.js"; +import {conditionPrompt} from "../prompts/implementations/ConditionPrompt.js"; +import {entryPrompt} from "../prompts/implementations/EntryPrompt.js"; +import {guidedEmpathyPrompt} from "../prompts/implementations/GuidedEmpathyPrompt.js"; +import {suicidalityPrompt} from "../prompts/implementations/SuicidalityPrompt.js"; +import {yamlPrompt} from "../schemata/YAMLPrompt.js"; +import {sleepRecordPrompt} from "../prompts/implementations/SleepRecordPrompt.js"; export function addEntryCommand(): CommandModule { return { @@ -26,6 +27,7 @@ export function addEntryCommand(): CommandModule { const summary = summaryPrompt({inquire}) const journal = journalEntryPrompt({inquire}) const suicidality = suicidalityPrompt({inquire}) + const sleep = sleepRecordPrompt({inquire}) const empathy = guidedEmpathyPrompt({ inquire, guideFactory: () => empathyGuide, @@ -45,6 +47,7 @@ export function addEntryCommand(): CommandModule { new Separator(), journal.mainMenu, empathyList.mainMenu, + sleep.mainMenu, // TODO: Modified HierarchicalCheckboxInput to allow for putting more things in the main menu than // there are letters // TODO: gratitude journaling @@ -54,7 +57,7 @@ export function addEntryCommand(): CommandModule { /* { name: typeof entry.needs === "object" ? "Check back in on needs" : "Check in on needs", - // TODO: physical needs: food, water, sleep, exercise tracking, possibly with autocompletes for each saved in a file like the empathy guide + // TODO: physical needs: food, water, exercise tracking, possibly with autocompletes for each saved in a file like the empathy guide value: NEEDS, key: "n" }, diff --git a/src/commands/UpdateEmpathyGuide.ts b/src/commands/UpdateEmpathyGuide.ts index 9b18153..5647dbc 100644 --- a/src/commands/UpdateEmpathyGuide.ts +++ b/src/commands/UpdateEmpathyGuide.ts @@ -1,11 +1,11 @@ import {CommandModule} from "yargs"; -import {inquire} from "../prompts/Inquire"; -import {registerPrompts} from "../prompts/types"; -import {LocalRepository} from "../repository/LocalRepository"; -import {empathyGroupPrompt} from "../prompts/implementations/EmpathyGroupPrompt"; -import {empathyGroupListPrompt} from "../prompts/implementations/EmpathyGroupListPrompt"; -import {empathyGuidePrompt} from "../prompts/implementations/EmpathyGuidePrompt"; -import {yamlPrompt} from "../schemata/YAMLPrompt"; +import {inquire} from "../prompts/Inquire.js"; +import {registerPrompts} from "../prompts/types/index.js"; +import {LocalRepository} from "../repository/LocalRepository.js"; +import {empathyGroupPrompt} from "../prompts/implementations/EmpathyGroupPrompt.js"; +import {empathyGroupListPrompt} from "../prompts/implementations/EmpathyGroupListPrompt.js"; +import {empathyGuidePrompt} from "../prompts/implementations/EmpathyGuidePrompt.js"; +import {yamlPrompt} from "../schemata/YAMLPrompt.js"; export function updateEmpathyGuideCommand(): CommandModule { return { diff --git a/src/datatypes/Condition.ts b/src/datatypes/Condition.ts index 92b4250..8f6298f 100644 --- a/src/datatypes/Condition.ts +++ b/src/datatypes/Condition.ts @@ -1,4 +1,4 @@ -import {schema} from "../schemata/SchemaData"; +import {schema} from "../schemata/SchemaData.js"; export enum Condition { CRITICAL = "Critical", diff --git a/src/datatypes/EmpathyGroup.ts b/src/datatypes/EmpathyGroup.ts index 1134ef5..c5570c6 100644 --- a/src/datatypes/EmpathyGroup.ts +++ b/src/datatypes/EmpathyGroup.ts @@ -1,4 +1,4 @@ -import {schema} from "../schemata/SchemaData"; +import {schema} from "../schemata/SchemaData.js"; export interface EmpathyGroup { readonly header: string diff --git a/src/datatypes/EmpathyGroupList.ts b/src/datatypes/EmpathyGroupList.ts index 44fb19d..02a3b4a 100644 --- a/src/datatypes/EmpathyGroupList.ts +++ b/src/datatypes/EmpathyGroupList.ts @@ -1,4 +1,4 @@ -import {EmpathyGroup} from "./EmpathyGroup"; +import {EmpathyGroup} from "./EmpathyGroup.js"; export function totalItems(groups: readonly EmpathyGroup[]): number { return groups.map((group) => group.items.length).reduce((a, b) => a + b) diff --git a/src/datatypes/EmpathyGuide.ts b/src/datatypes/EmpathyGuide.ts index 6222933..c4efc9a 100644 --- a/src/datatypes/EmpathyGuide.ts +++ b/src/datatypes/EmpathyGuide.ts @@ -1,5 +1,5 @@ -import {schema} from "../schemata/SchemaData"; -import {EmpathyGroup, EmpathyGroupJTD} from "./EmpathyGroup"; +import {schema} from "../schemata/SchemaData.js"; +import {EmpathyGroup, EmpathyGroupJTD} from "./EmpathyGroup.js"; export interface EmpathyGuide { readonly feelings?: { diff --git a/src/datatypes/Entry.ts b/src/datatypes/Entry.ts index 8c2b844..9f76265 100644 --- a/src/datatypes/Entry.ts +++ b/src/datatypes/Entry.ts @@ -1,15 +1,17 @@ -import {Condition, ConditionJTD} from "./Condition"; -import {GuidedEmpathy, GuidedEmpathyJTD} from "./GuidedEmpathy"; -import {Suicidality, SuicidalityJTD} from "./Suicidality"; -import {schema} from "../schemata/SchemaData"; +import {Condition, ConditionJTD} from "./Condition.js"; +import {GuidedEmpathy, GuidedEmpathyJTD} from "./GuidedEmpathy.js"; +import {Suicidality, SuicidalityJTD} from "./Suicidality.js"; +import {schema} from "../schemata/SchemaData.js"; +import {SleepRecord, SleepRecordListJTD} from "./SleepRecord.js"; export interface Entry { readonly startedAt: Date readonly finishedAt: Date - readonly condition: Condition + readonly condition?: Condition readonly summary?: string readonly journalEntry?: string readonly guidedEmpathy?: readonly GuidedEmpathy[] + readonly sleepRecords?: readonly SleepRecord[] // readonly needs?: Needs // readonly music?: readonly string[] // readonly rpg?: RPGStats @@ -24,17 +26,18 @@ export const EntryJTD = schema({ properties: { startedAt: { type: "timestamp" }, finishedAt: { type: "timestamp" }, - condition: ConditionJTD.reference, }, optionalProperties: { + condition: ConditionJTD.reference, summary: { type: "string" }, journalEntry: { type: "string" }, guidedEmpathy: { elements: GuidedEmpathyJTD.reference }, suicidality: SuicidalityJTD.reference, + sleepRecords: SleepRecordListJTD.reference, } }, typeHint: null as Entry|null, key: "entry", - references: [ConditionJTD, GuidedEmpathyJTD, SuicidalityJTD] + references: [ConditionJTD, GuidedEmpathyJTD, SuicidalityJTD, SleepRecordListJTD, ...SleepRecordListJTD.requiredReferences, ...GuidedEmpathyJTD.requiredReferences] }) diff --git a/src/datatypes/GuidedEmpathy.ts b/src/datatypes/GuidedEmpathy.ts index e957d34..a8cc105 100644 --- a/src/datatypes/GuidedEmpathy.ts +++ b/src/datatypes/GuidedEmpathy.ts @@ -1,4 +1,4 @@ -import {isPopulatedArray} from "../utils/Arrays"; +import {isPopulatedArray} from "../utils/Arrays.js"; import { Persona, personaName, @@ -6,9 +6,9 @@ import { personaPronounObject, personaPronounPossessive, personaVerb -} from "./Persona"; +} from "./Persona.js"; import chalk from "chalk"; -import {schema} from "../schemata/SchemaData"; +import {schema} from "../schemata/SchemaData.js"; import capitalize from "capitalize"; export interface GuidedEmpathy { diff --git a/src/datatypes/Journal.ts b/src/datatypes/Journal.ts index 9ea4609..bb23a74 100644 --- a/src/datatypes/Journal.ts +++ b/src/datatypes/Journal.ts @@ -1,5 +1,5 @@ -import {Entry, EntryJTD} from "./Entry"; -import {schema} from "../schemata/SchemaData"; +import {Entry, EntryJTD} from "./Entry.js"; +import {schema} from "../schemata/SchemaData.js"; /* export interface PersonaState { readonly persona: Persona diff --git a/src/datatypes/Persona.ts b/src/datatypes/Persona.ts index 7dda8be..72eb91e 100644 --- a/src/datatypes/Persona.ts +++ b/src/datatypes/Persona.ts @@ -1,4 +1,4 @@ -import {schema} from "../schemata/SchemaData"; +import {schema} from "../schemata/SchemaData.js"; export enum Persona { HEART = "Heart", diff --git a/src/datatypes/SleepRecord.ts b/src/datatypes/SleepRecord.ts new file mode 100644 index 0000000..00a2127 --- /dev/null +++ b/src/datatypes/SleepRecord.ts @@ -0,0 +1,96 @@ +import {schema} from "../schemata/SchemaData.js"; + +export enum SleepQuality { + ACIDIC = "Acidic", + RESTLESS = "Restless", + NIGHTMARISH = "Nightmarish", + TIMESKIP = "Timeskip", + DREAMLESS = "Dreamless", + DREAMY = "Dreamy", + ECSTASY = "Ecstasy", +} +export const SLEEP_QUALITIES: SleepQuality[] = [SleepQuality.ACIDIC, SleepQuality.RESTLESS, SleepQuality.NIGHTMARISH, SleepQuality.TIMESKIP, SleepQuality.DREAMLESS, SleepQuality.DREAMY, SleepQuality.ECSTASY] + +export type SleepQualityJTD = typeof SleepQualityJTD +export const SleepQualityJTD = schema({ + schema: { + enum: SLEEP_QUALITIES + }, + key: "sleepQuality", + references: [], +}) + +export enum WakeQuality { + AGONIZED = "Agonized", + EXHAUSTED = "Exhausted", + DROWSY = "Drowsy", + RESTED = "Rested", + ENERGIZED = "Energized", +} +export const WAKE_QUALITIES: WakeQuality[] = [WakeQuality.AGONIZED, WakeQuality.EXHAUSTED, WakeQuality.DROWSY, WakeQuality.RESTED, WakeQuality.ENERGIZED] + +export type WakeQualityJTD = typeof WakeQualityJTD +export const WakeQualityJTD = schema({ + schema: { + enum: WAKE_QUALITIES + }, + key: "wakeQuality", + references: [], +}) + +export interface SleepRecord { + readonly sleepAt?: Date + readonly sleepQuality?: SleepQuality + readonly interruptions?: number + readonly wakeAt?: Date + readonly wakeQuality?: WakeQuality + readonly dreams?: string +} +export type SleepRecordJTD = typeof SleepRecordJTD +export const SleepRecordJTD = schema({ + schema: { + optionalProperties: { + sleepAt: { type: "timestamp" }, + sleepQuality: SleepQualityJTD.reference, + interruptions: { type: "uint32" }, + wakeAt: { type: "timestamp" }, + wakeQuality: WakeQualityJTD.reference, + dreams: { type: "string" }, + } + }, + typeHint: null as SleepRecord|null, + key: "sleepRecord", + references: [SleepQualityJTD, WakeQualityJTD], +}) + +export type SleepRecordListJTD = typeof SleepRecordListJTD +export const SleepRecordListJTD = schema({ + schema: { + elements: SleepRecordJTD.reference + }, + typeHint: null as (readonly SleepRecord[])|null, + key: "sleepRecords", + references: [SleepRecordJTD, ...SleepRecordJTD.requiredReferences], +}) + +const TimeFormat = Intl.DateTimeFormat([], { + dateStyle: undefined, + timeStyle: undefined, + year: undefined, + month: undefined, + day: undefined, + weekday: undefined, + hour: "numeric", + minute: "2-digit", + second: undefined, + fractionalSecondDigits: undefined, + timeZone: undefined, + hour12: true, + hourCycle: "h12", +}) + +export function sleepRecordToString(record: SleepRecord) { + const sleepAt = record.sleepAt === undefined ? null : TimeFormat.format(record.sleepAt) + const wakeAt = record.wakeAt === undefined ? null : TimeFormat.format(record.wakeAt) + return `${sleepAt ?? "?:??"} (${record.sleepQuality ?? "???"}) -${record.interruptions ?? "?"}-> ${wakeAt ?? "?:??"} (${record.wakeQuality ?? "???"})${typeof record.dreams === "string" ? " with dream journal" : ""}` +} diff --git a/src/datatypes/Suicidality.ts b/src/datatypes/Suicidality.ts index 43c7057..cae7505 100644 --- a/src/datatypes/Suicidality.ts +++ b/src/datatypes/Suicidality.ts @@ -1,4 +1,4 @@ -import {schema} from "../schemata/SchemaData"; +import {schema} from "../schemata/SchemaData.js"; export enum Suicidality { NONE = "None", diff --git a/src/index.ts b/src/index.ts index b2b62e7..1c30388 100644 --- a/src/index.ts +++ b/src/index.ts @@ -1,13 +1,15 @@ -import {addEntryCommand} from "./commands/AddEntry"; -import {updateEmpathyGuideCommand} from "./commands/UpdateEmpathyGuide"; -import yargs from "yargs" +import {addEntryCommand} from "./commands/AddEntry.js"; +import {updateEmpathyGuideCommand} from "./commands/UpdateEmpathyGuide.js"; +import {Argv, default as yargs} from "yargs" -yargs +const Yargs = yargs as unknown as {(): Argv} + +Yargs() .scriptName("mari-status-bar") .command(addEntryCommand()) .command(updateEmpathyGuideCommand()) .demandCommand() .parseAsync() - .catch((err) => { + .catch((err: unknown) => { console.error(err) }) \ No newline at end of file diff --git a/src/prompts/Inquire.ts b/src/prompts/Inquire.ts index 9a17d09..1869947 100644 --- a/src/prompts/Inquire.ts +++ b/src/prompts/Inquire.ts @@ -1,5 +1,9 @@ -import {prompt, QuestionMap} from "inquirer"; +import {QuestionMap} from "inquirer"; +import inquirer from "inquirer"; +export const prompt = inquirer.prompt; +export const registerPrompt = inquirer.registerPrompt; +export const Separator = inquirer.Separator; export type InquireFunction = (question: QuestionT) => Promise export type ShowFunction = (text: string) => Promise diff --git a/src/prompts/implementations/ConditionPrompt.ts b/src/prompts/implementations/ConditionPrompt.ts index 096cb79..c4b4992 100644 --- a/src/prompts/implementations/ConditionPrompt.ts +++ b/src/prompts/implementations/ConditionPrompt.ts @@ -1,10 +1,10 @@ -import {ListQuestion, Separator} from "inquirer"; -import {personaPossessive, PersonaPrompt} from "../../datatypes/Persona"; +import {ListQuestion} from "inquirer"; +import {personaPossessive, PersonaPrompt} from "../../datatypes/Persona.js"; import chalk from "chalk"; -import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt"; -import {asDefault, identity} from "../../utils/Objects"; -import {InquireFunction} from "../Inquire"; -import {Condition} from "../../datatypes/Condition"; +import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt.js"; +import {asDefault, identity} from "../../utils/Objects.js"; +import {InquireFunction, Separator} from "../Inquire.js"; +import {Condition} from "../../datatypes/Condition.js"; export interface ConditionPromptOptions extends Partial>, PersonaPrompt { } @@ -19,7 +19,7 @@ export function conditionPrompt(deps: ConditionPromptDependencies): { } { return makeEntryMainMenuChoice({ property: "condition", - name: (input) => `Change condition ${chalk.dim(`(currently ${chalk.greenBright(input)})`)}`, + name: (input) => typeof input === "string" ? `Change condition ${chalk.dim(`(currently ${chalk.greenBright(input)})`)}` : `Add condition`, key: "c", injected: (options) => promptForCondition(options, deps), toOptions: asDefault, diff --git a/src/prompts/implementations/EmpathyGroupListPrompt.ts b/src/prompts/implementations/EmpathyGroupListPrompt.ts index fa3f41d..0653dbd 100644 --- a/src/prompts/implementations/EmpathyGroupListPrompt.ts +++ b/src/prompts/implementations/EmpathyGroupListPrompt.ts @@ -1,9 +1,9 @@ -import {EmpathyGroup} from "../../datatypes/EmpathyGroup"; -import {isPopulatedArray} from "../../utils/Arrays"; +import {EmpathyGroup} from "../../datatypes/EmpathyGroup.js"; +import {isPopulatedArray} from "../../utils/Arrays.js"; import chalk from "chalk"; import pluralize from "pluralize"; -import {InquireFunction} from "../Inquire"; -import {EmpathyGroupPromptOptions} from "./EmpathyGroupPrompt"; +import {InquireFunction} from "../Inquire.js"; +import {EmpathyGroupPromptOptions} from "./EmpathyGroupPrompt.js"; import {ListQuestion} from "inquirer"; export interface EmpathyGroupListPromptOptions { diff --git a/src/prompts/implementations/EmpathyGroupPrompt.ts b/src/prompts/implementations/EmpathyGroupPrompt.ts index d8587f5..1067b5f 100644 --- a/src/prompts/implementations/EmpathyGroupPrompt.ts +++ b/src/prompts/implementations/EmpathyGroupPrompt.ts @@ -1,8 +1,8 @@ import capitalize from "capitalize"; -import {YamlPromptFunction} from "../../schemata/YAMLPrompt"; +import {YamlPromptFunction} from "../../schemata/YAMLPrompt.js"; import chalk from "chalk"; -import {InquireFunction} from "../Inquire"; -import {EmpathyGroup, EmpathyGroupJTD} from "../../datatypes/EmpathyGroup"; +import {InquireFunction} from "../Inquire.js"; +import {EmpathyGroup, EmpathyGroupJTD} from "../../datatypes/EmpathyGroup.js"; import {EditorQuestion, ExpandQuestion, InputQuestion, MultiTextInputQuestion} from "inquirer"; export interface EmpathyGroupPromptOptions { diff --git a/src/prompts/implementations/EmpathyGuidePrompt.ts b/src/prompts/implementations/EmpathyGuidePrompt.ts index 7383540..8245566 100644 --- a/src/prompts/implementations/EmpathyGuidePrompt.ts +++ b/src/prompts/implementations/EmpathyGuidePrompt.ts @@ -1,13 +1,13 @@ -import {isPopulatedArray} from "../../utils/Arrays"; +import {isPopulatedArray} from "../../utils/Arrays.js"; import chalk from "chalk"; import pluralize from "pluralize"; -import {totalItems} from "../../datatypes/EmpathyGroupList"; -import {ExpandQuestion, Separator} from "inquirer"; -import {YamlPromptFunction} from "../../schemata/YAMLPrompt"; -import {InquireFunction} from "../Inquire"; -import {EmpathyGroupListPromptOptions} from "./EmpathyGroupListPrompt"; -import {EmpathyGroup} from "../../datatypes/EmpathyGroup"; -import {EmpathyGuide, EmpathyGuideJTD} from "../../datatypes/EmpathyGuide"; +import {totalItems} from "../../datatypes/EmpathyGroupList.js"; +import {ExpandQuestion} from "inquirer"; +import {YamlPromptFunction} from "../../schemata/YAMLPrompt.js"; +import {InquireFunction, Separator} from "../Inquire.js"; +import {EmpathyGroupListPromptOptions} from "./EmpathyGroupListPrompt.js"; +import {EmpathyGroup} from "../../datatypes/EmpathyGroup.js"; +import {EmpathyGuide, EmpathyGuideJTD} from "../../datatypes/EmpathyGuide.js"; export interface EmpathyGuidePromptOptions { readonly default?: EmpathyGuide diff --git a/src/prompts/implementations/EntryMainMenuPrompt.ts b/src/prompts/implementations/EntryMainMenuPrompt.ts index 9d1dc27..b123d60 100644 --- a/src/prompts/implementations/EntryMainMenuPrompt.ts +++ b/src/prompts/implementations/EntryMainMenuPrompt.ts @@ -1,8 +1,11 @@ -import {InquireFunction} from "../Inquire"; -import {ExpandChoiceOptions, ExpandQuestion, Separator, SeparatorOptions} from "inquirer"; -import {merge} from "../../utils/Merge"; -import {Entry, EntryJTD} from "../../datatypes/Entry"; -import {YamlPromptFunction} from "../../schemata/YAMLPrompt"; +import {InquireFunction} from "../Inquire.js"; +import {ExpandChoiceOptions, ExpandQuestion, SeparatorOptions} from "inquirer"; +import inquirer from "inquirer"; +import {merge} from "../../utils/Merge.js"; +import {Entry, EntryJTD} from "../../datatypes/Entry.js"; +import {YamlPromptFunction} from "../../schemata/YAMLPrompt.js"; + +const Separator = inquirer.Separator const VIEW = ".View" const DONE = ".Done" diff --git a/src/prompts/implementations/EntryPrompt.ts b/src/prompts/implementations/EntryPrompt.ts index 5c515a3..2537cc4 100644 --- a/src/prompts/implementations/EntryPrompt.ts +++ b/src/prompts/implementations/EntryPrompt.ts @@ -1,8 +1,8 @@ -import {ConditionPromptOptions} from "./ConditionPrompt"; -import {Condition} from "../../datatypes/Condition"; -import {SummaryPromptOptions} from "./SummaryPrompt"; -import {EntryMainMenuOptions} from "./EntryMainMenuPrompt"; -import {Entry} from "../../datatypes/Entry"; +import {ConditionPromptOptions} from "./ConditionPrompt.js"; +import {Condition} from "../../datatypes/Condition.js"; +import {SummaryPromptOptions} from "./SummaryPrompt.js"; +import {EntryMainMenuOptions} from "./EntryMainMenuPrompt.js"; +import {Entry} from "../../datatypes/Entry.js"; interface EntryPromptOptions { } diff --git a/src/prompts/implementations/GuidedEmpathyListPrompt.ts b/src/prompts/implementations/GuidedEmpathyListPrompt.ts index d64f500..c21b8e6 100644 --- a/src/prompts/implementations/GuidedEmpathyListPrompt.ts +++ b/src/prompts/implementations/GuidedEmpathyListPrompt.ts @@ -1,13 +1,13 @@ -import {PersonaPrompt} from "../../datatypes/Persona"; -import {guidedEmpathyToStringShort, GuidedEmpathy} from "../../datatypes/GuidedEmpathy"; -import {InquireFunction} from "../Inquire"; -import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt"; +import {PersonaPrompt} from "../../datatypes/Persona.js"; +import {guidedEmpathyToStringShort, GuidedEmpathy} from "../../datatypes/GuidedEmpathy.js"; +import {InquireFunction} from "../Inquire.js"; +import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt.js"; import chalk from "chalk"; import pluralize from "pluralize"; -import {isPopulatedArray} from "../../utils/Arrays"; +import {isPopulatedArray} from "../../utils/Arrays.js"; import {ListChoiceOptions, ListQuestion} from "inquirer"; -import {asDefault} from "../../utils/Objects"; -import {GuidedEmpathyPromptOptions} from "./GuidedEmpathyPrompt"; +import {asDefault} from "../../utils/Objects.js"; +import {GuidedEmpathyPromptOptions} from "./GuidedEmpathyPrompt.js"; export interface GuidedEmpathyListPromptOptions extends PersonaPrompt { readonly default?: readonly GuidedEmpathy[] diff --git a/src/prompts/implementations/GuidedEmpathyPrompt.ts b/src/prompts/implementations/GuidedEmpathyPrompt.ts index 26311e1..9f0b625 100644 --- a/src/prompts/implementations/GuidedEmpathyPrompt.ts +++ b/src/prompts/implementations/GuidedEmpathyPrompt.ts @@ -4,13 +4,13 @@ import { personaPronounObject, personaPronounPossessive, personaVerb -} from "../../datatypes/Persona"; -import {InquireFunction, ShowFunction} from "../Inquire"; -import {EmpathyGuide} from "../../datatypes/EmpathyGuide"; -import {isPopulatedArray} from "../../utils/Arrays"; -import Separator from "inquirer/lib/objects/separator"; -import {EmpathyGroup} from "../../datatypes/EmpathyGroup"; -import {GuidedEmpathy, guidedEmpathyToString, isPopulatedGuidedEmpathy} from "../../datatypes/GuidedEmpathy"; +} from "../../datatypes/Persona.js"; +import {InquireFunction, ShowFunction} from "../Inquire.js"; +import {EmpathyGuide} from "../../datatypes/EmpathyGuide.js"; +import {isPopulatedArray} from "../../utils/Arrays.js"; +import {Separator} from "../Inquire.js"; +import {EmpathyGroup} from "../../datatypes/EmpathyGroup.js"; +import {GuidedEmpathy, guidedEmpathyToString, isPopulatedGuidedEmpathy} from "../../datatypes/GuidedEmpathy.js"; import {HierarchicalCheckboxChildChoice, HierarchicalCheckboxParentChoice, HierarchicalCheckboxQuestion, MultiTextInputQuestion } from "inquirer"; export interface GuidedEmpathyPromptOptions extends PersonaPrompt { diff --git a/src/prompts/implementations/JournalEntryPrompt.ts b/src/prompts/implementations/JournalEntryPrompt.ts index 1074350..63b4b19 100644 --- a/src/prompts/implementations/JournalEntryPrompt.ts +++ b/src/prompts/implementations/JournalEntryPrompt.ts @@ -1,11 +1,11 @@ import {EditorQuestion} from "inquirer"; -import {InquireFunction} from "../Inquire"; -import {personaPossessive, PersonaPrompt} from "../../datatypes/Persona"; -import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt"; +import {InquireFunction} from "../Inquire.js"; +import {personaPossessive, PersonaPrompt} from "../../datatypes/Persona.js"; +import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt.js"; import chalk from "chalk"; import pluralize from "pluralize"; import wordcount from "wordcount"; -import {asDefault} from "../../utils/Objects"; +import {asDefault} from "../../utils/Objects.js"; export interface JournalEntryPromptOptions extends Partial>, PersonaPrompt {} diff --git a/src/prompts/implementations/SleepRecordPrompt.ts b/src/prompts/implementations/SleepRecordPrompt.ts new file mode 100644 index 0000000..7e6b21e --- /dev/null +++ b/src/prompts/implementations/SleepRecordPrompt.ts @@ -0,0 +1,196 @@ +import { + DateQuestion, + EditorQuestion, + ListQuestion, + NumberQuestion, +} from "inquirer"; +import {Separator} from "../Inquire.js"; +import {InquireFunction} from "../Inquire.js"; +import {SleepQuality, SleepRecord, sleepRecordToString, WakeQuality} from "../../datatypes/SleepRecord.js"; +import {DateTime} from "luxon"; +import chalk from "chalk"; +import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt.js"; + +export interface SleepRecordPromptOptions extends Partial & Omit & Omit & Omit>{ + default?: SleepRecord, +} + +export interface SleepRecordPromptDependencies { + readonly inquire: InquireFunction & InquireFunction & InquireFunction & InquireFunction & InquireFunction +} + +export function sleepRecordPrompt(deps: SleepRecordPromptDependencies): { + (options: SleepRecordPromptOptions): Promise, + mainMenu: EntryMainMenuChoice<"sleepRecords">, +} { + return makeEntryMainMenuChoice({ + property: "sleepRecords", + name: (input) => typeof input !== "object" || input.length === 0 ? `Add sleep record` : `Change sleep record ${chalk.dim(`(currently ${chalk.greenBright(sleepRecordToString(input[0]))})`)}`, + key: "z", + injected: (options) => promptForSleepRecord(options, deps), + toOptions: (value) => typeof value !== "object" || value.length === 0 ? {} : {default: value[0]}, + toProperty: (value) => value === null ? undefined : [value], + }) +} + +export async function promptForSleepRecord(options: SleepRecordPromptOptions, {inquire}: SleepRecordPromptDependencies): Promise { + const oldBedTime = options.default?.sleepAt + const newBedTime = await inquire({ + ...options, + type: "date", + message: "About when did you get to sleep?", + clearable: true, + startCleared: false, + default: oldBedTime ?? DateTime.local().set({hour: 23, minute: 0, second: 0, millisecond: 0}).minus({days: 1}).toJSDate(), + format: { + year: undefined, + weekday: "short", + month: "short", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: undefined, + fractionalSecondDigits: undefined, + timeZoneName: "short", + }, + startingDatePart: "hour", + deltas: { + weekday: 1, + hour: [1, 5, 10], + minute: [15, 5, 1], + default: 0 + } + }) + const oldSleepQuality = options.default?.sleepQuality + const newSleepQuality = await inquire({ + ...options, + type: "list", + message: `How'd you sleep?`, + choices: [ + { + value: SleepQuality.ACIDIC, + name: `Acidic ${chalk.dim("(extremely poor/extremely restless/heavy acid reflux)")}` + }, + { + value: SleepQuality.RESTLESS, + name: `Restless ${chalk.dim("(very poor/very restless/fever dreamy)")}` + }, + { + value: SleepQuality.NIGHTMARISH, + name: `Nightmarish ${chalk.dim("(poor/restless/plagued with nightmares)")}` + }, + { + value: SleepQuality.TIMESKIP, + name: `Timeskip ${chalk.dim("(neutral/passage of time not recognized)")}` + }, + { + value: SleepQuality.DREAMLESS, + name: `Dreamless ${chalk.dim("(good/peaceful/no dreams had or remembered)")}` + }, + { + value: SleepQuality.DREAMY, + name: `Dreamy ${chalk.dim("(very good/peaceful/neutral to somewhat pleasant dreams)")}` + }, + { + value: SleepQuality.ECSTASY, + name: `Ecstasy ${chalk.dim("(extremely good/very peaceful/very pleasant dreams)")}` + }, + new Separator(), + { + value: undefined, + name: `Uncertain` + }, + ], + default: oldSleepQuality ?? SleepQuality.TIMESKIP, + pageSize: 999, + }) + const oldInterruptions = options.default?.interruptions + const newInterruptionsRaw = await inquire({ + ...options, + type: "number", + message: "How many times did you end up waking up during the sleep?", + default: oldInterruptions ?? -1, + }) + const newInterruptions = newInterruptionsRaw < 0 ? undefined : Math.round(newInterruptionsRaw) + const oldWakeTime = options.default?.wakeAt + const newWakeTime = await inquire({ + ...options, + type: "date", + message: "Around when did you get up?", + clearable: true, + startCleared: false, + default: oldWakeTime ?? DateTime.local().set({hour: 7, minute: 0, second: 0, millisecond: 0}).toJSDate(), + format: { + year: undefined, + weekday: "short", + month: "short", + day: "numeric", + hour: "numeric", + minute: "numeric", + second: undefined, + fractionalSecondDigits: undefined, + timeZoneName: "short", + }, + startingDatePart: "hour", + deltas: { + hour: [1, 5, 10], + minute: [15, 5, 1], + default: 0 + } + }) + const oldWakeQuality = options.default?.wakeQuality + const newWakeQuality = await inquire({ + ...options, + type: "list", + message: `How'd you feel when you got up?`, + choices: [ + { + value: WakeQuality.AGONIZED, + name: `Agonized ${chalk.dim("(in physical pain/barely able or unable to get out of bed)")}` + }, + { + value: WakeQuality.EXHAUSTED, + name: `Exhausted ${chalk.dim("(very tired/not wanting to get out of bed)")}` + }, + { + value: WakeQuality.DROWSY, + name: `Drowsy ${chalk.dim("(a bit sleepy but willing to get out of bed)")}` + }, + { + value: WakeQuality.RESTED, + name: `Rested ${chalk.dim("(well rested and ready to get going)")}` + }, + { + value: WakeQuality.ENERGIZED, + name: `Energized ${chalk.dim("(thoroughly recharged and eager to get up and running)")}` + }, + new Separator(), + { + value: undefined, + name: `Uncertain` + }, + ], + default: oldWakeQuality ?? WakeQuality.DROWSY, + pageSize: 999, + }) + const oldDreamJournal = options.default?.dreams + const newDreamJournalRaw = (await inquire({ + ...options, + type: "editor", + message: typeof oldDreamJournal === "string" ? `Edit dream journal for this sleep session:` : `Type up dream journal for this sleep session:`, + default: oldDreamJournal, + })).trimEnd() + const newDreamJournal = newDreamJournalRaw === "" ? undefined : newDreamJournalRaw + const result: SleepRecord = { + dreams: newDreamJournal, + interruptions: newInterruptions, + sleepAt: newBedTime ?? undefined, + sleepQuality: newSleepQuality, + wakeAt: newWakeTime ?? undefined, + wakeQuality: newWakeQuality, + } + return ( + Object.keys(result).map((key: keyof SleepRecord) => result[key]).some(value => (value !== undefined)) + ? result + : null) +} \ No newline at end of file diff --git a/src/prompts/implementations/SuicidalityPrompt.ts b/src/prompts/implementations/SuicidalityPrompt.ts index 9188c4c..4744c1a 100644 --- a/src/prompts/implementations/SuicidalityPrompt.ts +++ b/src/prompts/implementations/SuicidalityPrompt.ts @@ -1,9 +1,9 @@ import {ListQuestion} from "inquirer"; -import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt"; +import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt.js"; import chalk from "chalk"; -import {asDefault, identity} from "../../utils/Objects"; -import {InquireFunction} from "../Inquire"; -import {Suicidality} from "../../datatypes/Suicidality"; +import {asDefault, identity} from "../../utils/Objects.js"; +import {InquireFunction} from "../Inquire.js"; +import {Suicidality} from "../../datatypes/Suicidality.js"; export interface SuicidalityPromptOptions extends Partial> { } diff --git a/src/prompts/implementations/SummaryPrompt.ts b/src/prompts/implementations/SummaryPrompt.ts index f27e6ca..b8ad459 100644 --- a/src/prompts/implementations/SummaryPrompt.ts +++ b/src/prompts/implementations/SummaryPrompt.ts @@ -1,11 +1,11 @@ import {InputQuestion} from "inquirer"; -import {InquireFunction} from "../Inquire"; -import {personaName, personaPossessive, PersonaPrompt, personaVerb} from "../../datatypes/Persona"; -import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt"; +import {InquireFunction} from "../Inquire.js"; +import {personaName, personaPossessive, PersonaPrompt, personaVerb} from "../../datatypes/Persona.js"; +import {EntryMainMenuChoice, makeEntryMainMenuChoice} from "./EntryMainMenuPrompt.js"; import chalk from "chalk"; import pluralize from "pluralize"; import wordcount from "wordcount"; -import {asDefault} from "../../utils/Objects"; +import {asDefault} from "../../utils/Objects.js"; export interface SummaryPromptOptions extends Partial>, PersonaPrompt {} diff --git a/src/prompts/types/DateInput.ts b/src/prompts/types/DateInput.ts new file mode 100644 index 0000000..2935edd --- /dev/null +++ b/src/prompts/types/DateInput.ts @@ -0,0 +1,386 @@ +/* + * Adapted from https://github.com/haversnail/inquirer-date-prompt: + * MIT License + * + * Copyright (c) 2021 Alex Havermale + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in all + * copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + */ + +import chalk from "chalk"; +import {DateTime, DurationObjectUnits} from "luxon"; +import inquirer, {Answers, DateQuestion, Question} from "inquirer"; +import {Interface as ReadLineInterface, Key} from "readline"; +import Prompt from "inquirer/lib/prompts/base.js"; +import observe from "inquirer/lib/utils/events.js"; +import {map, takeUntil} from "rxjs/operators/index.js"; +import cliCursor from "cli-cursor" +import SuccessfulPromptStateData = inquirer.prompts.SuccessfulPromptStateData; +import FailedPromptStateData = inquirer.prompts.FailedPromptStateData; + +declare module "inquirer" { + + export interface DateQuestionOptions { + /** + * Transforms the value to display to the user. + * + * @param date + * The currently selected date in string format. + * + * @param answers + * The answers provided by the users. + * + * @param flags + * Additional information about the value. + * + * @returns + * The value to display to the user. + */ + transformer?( + date: string, + answers: AnswerT, + flags: { isDirty?: boolean; isCleared?: boolean; isFinal?: boolean }, + ): string | Promise; + + /** + * A Boolean value indicating whether the prompt is clearable. + * If `true`, pressing `backspace` or `delete` will replace the current value with `null`. + */ + clearable?: boolean; + + /** + * A Boolean value indicating whether the prompt should start cleared even though a default is provided. + * If `true`, the value will start off null, but clearing it will change to the default date. + */ + startCleared?: boolean; + + /** + * A specific locale to use when formatting the date. + * If no locale is provided, it will default to the user's current locale. + * @see the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat|Intl.DateTimeFormat} docs for more info. + */ + locale?: string; + + /** + * A set of options for customizing the date format. + * @see the {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/DateTimeFormat|Intl.DateTimeFormat} docs for more info. + */ + format?: Intl.DateTimeFormatOptions; + /** The date part that should be highlighted when the prompt is shown. */ + startingDatePart?: Intl.DateTimeFormatPartTypes + /** The amount by which each value should change. If null, the value will not be selectable. */ + deltas?: { + [key in Intl.DateTimeFormatPartTypes|"default"]?: number|[number]|[number,number]|[number,number,number]|[number,number,number,number]|0 + } + } + + export interface DateQuestion extends Question, DateQuestionOptions { + /** @inheritDoc */ + type: "date" + /** If the default is not provided or null, the value will be the present date at the time that the prompt is shown. */ + default?: Date|null + } + + export interface QuestionMap { + ["date"]: DateQuestion + } +} + +/** + * A lookup object that maps each date part type to the corresponding field of a duration. + */ +const offsetLookup: Partial> = { + year: "years", + month: "months", + day: "days", + hour: "hours", + minute: "minutes", + second: "seconds", + weekday: "days", +}; + +/** + * Returns the index of the _last_ element in the array where predicate is true, and -1 otherwise. + */ +function findLastIndex(array: T[], predicate: (value: T, index: number, obj: T[]) => boolean) { + let l = array.length; + while (l--) { + if (predicate(array[l], l, array)) return l; + } + return -1; +} + +/** + * Represents a date prompt. + */ +export class DateInput = DateQuestion> extends Prompt { + date: DateTime + readonly transformer: DateQuestion["transformer"] + readonly clearable: boolean + readonly format: Intl.DateTimeFormatOptions + readonly deltas: NonNullable + done: ((state: unknown) => void)|null = null + isDirty: boolean + isCleared: boolean + cursorIndex: number + firstEditableIndex: number + lastEditableIndex: number + + constructor(questions: QuestionT, rl: ReadLineInterface, answers: AnswerT) { + super(questions, rl, answers); + // Set the format object based on the user's specified options: + const { transformer, clearable, startCleared, locale, format = {}, default: date, deltas, startingDatePart } = this.opt; + this.transformer = transformer + this.deltas = deltas ?? {} + this.clearable = clearable ?? false + this.format = { + year: "numeric", + month: "numeric", + day: "numeric", + hour: "numeric", + minute: "numeric", + ...format, + }; + // Set the date object with either the default value or the current date: + this.date = DateTime.fromJSDate(date ?? new Date()); + if (typeof locale === "string") { + this.date = this.date.setLocale(locale) + } + // Clear the default value option (so it won't be printed by the Prompt class): + this.opt.default = null; + this.isDirty = false; + this.isCleared = startCleared ?? false; + // Set the first and last indices of the editable date parts: + this.firstEditableIndex = this.dateParts.findIndex((part) => this.isDatePartEditable(part.type)); + this.lastEditableIndex = findLastIndex(this.dateParts, (part) => this.isDatePartEditable(part.type)); + // Set the cursor index to the first editable part: + this.cursorIndex = !!startingDatePart && this.isDatePartEditable(startingDatePart) ? this.dateParts.findIndex((part) => part.type === startingDatePart) : this.firstEditableIndex; + } + + // Called by parent class: + _run(cb: DateInput["done"]) { + this.done = cb; + + // Observe events: + const events = observe(this.rl); + const submit = events.line.pipe(map(() => (this.isCleared ? null : this.date.toJSDate()))); + const validation = this.handleSubmitEvents(submit); + validation.success.forEach(this.onEnd.bind(this)); + validation.error.forEach(this.onError.bind(this)); + events.keypress.pipe(takeUntil(validation.success)).forEach(this.onKeypress.bind(this)); + + // Init the prompt: + cliCursor.hide(); + this.render(); + + return this; + } + + /** + * Renders the prompt. + * @param {string} [error] + */ + render(error?: string) { + let message = this.getQuestion(); // The question portion of the output, including any prefix and suffix + + const { isDirty, isCleared } = this; + const isFinal = this.status === "answered"; + + if (!isCleared) { + const dateString = this.dateParts + .map(({ value }, index) => + isFinal + ? chalk.cyan(value) + : index === this.cursorIndex + ? chalk.inverse(value) + : !isDirty + ? chalk.dim(value) + : value, + ) + .join(""); + + // Apply the transformer function if one was provided: + message += this.opt.transformer + ? this.opt.transformer(dateString, this.answers as AnswerT, { isDirty, isCleared, isFinal }) + : dateString; + + // Display info on how to clear if the prompt is clearable: + if (this.opt.clearable && !isFinal) { + message += chalk.dim(" ( to clear) "); + } + } + + const bottomContent = error ? chalk.red(">> ") + error : ""; + + // Render the final message: + this.screen.render(message, bottomContent); + } + + /** + * The end event handler. + */ + onEnd({ value }: SuccessfulPromptStateData) { + this.status = "answered"; + + // Re-render prompt + this.render(); + + this.screen.done(); + cliCursor.show(); + if (this.done !== null) { + this.done(value); + } + } + + /** + * The error event handler. + */ + onError({ isValid }: FailedPromptStateData) { + this.render(isValid || undefined); + } + + /** + * The array of date part objects according to the user's specified format. + */ + get dateParts() { + return this.date.toLocaleParts(this.format); + } + + /** + * The currently selected date part. + */ + get currentDatePart() { + return this.dateParts[this.cursorIndex]; + } + + isDatePartEditable(part: Intl.DateTimeFormatPartTypes): boolean { + return offsetLookup.hasOwnProperty(part) && ((this.deltas[part] ?? this.deltas["default"] ?? 1) !== 0) + } + + /** + * A Boolean value indicating whether the currently selected date part is editable. + */ + get isCurrentDatePartEditable() { + return this.isDatePartEditable(this.currentDatePart.type); + } + + /** + * Moves the cursor index to the right. + */ + incrementCursorIndex() { + if (this.cursorIndex < this.lastEditableIndex) { + this.cursorIndex++; + } + } + + /** + * Moves the cursor index to the left. + */ + decrementCursorIndex() { + if (this.cursorIndex > this.firstEditableIndex) { + this.cursorIndex--; + } + } + + /** + * Shifts the currently selected date part to the specified offset value. + * The default value is `0`. + * @param {number} offset + */ + shiftDatePartValue(offset = 0) { + const { type } = this.currentDatePart; + const duration: DurationObjectUnits = {} + const offsetProperty = offsetLookup[type] + if (offset !== 0 && typeof offsetProperty === "string") { + duration[offsetProperty] = offset + // Set the input as "dirty" now that the initial date is being changed: + this.isDirty = true; + this.date = this.date.plus(duration) + } + } + + /** + * Increments the currently selected date part by one. + */ + incrementDatePartValueBy(value = 1) { + this.shiftDatePartValue(value); + } + + /** + * Decrements the currently selected date part by one. + */ + decrementDatePartValueBy(value = 1) { + this.shiftDatePartValue(-1 * value); + } + + /** + * The keypress event handler. + */ + onKeypress({ key }: {key: Key}) { + // Reset cleared state if any other key is pressed: + if (this.isCleared) { + this.isCleared = false; + this.isDirty = true; + return + } + // Calculate the amount to increment/decrement by based on modifiers: + const deltas = this.deltas[this.currentDatePart.type] ?? this.deltas["default"] ?? [1, 10, 100] + const amount = ((): number => { + if (typeof deltas === "number") { + return deltas + } else { + switch (deltas.length) { + case 1: + return deltas[0] + case 2: + return (key.shift || key.meta) ? deltas[1] : deltas[0] + case 3: + return (key.shift || key.meta) ? (key.shift && key.meta) ? deltas[2] : deltas[1] : deltas[0] + case 4: + return key.shift ? key.meta ? deltas[3] : deltas[1] : key.meta ? deltas[2] : deltas[0] + } + } + })() + + switch (key.name) { + case "right": + do { + this.incrementCursorIndex(); + } while (!this.isCurrentDatePartEditable); // increments the cursor index until it hits an editable value + break; + case "left": + do { + this.decrementCursorIndex(); + } while (!this.isCurrentDatePartEditable); // decrements the cursor index until it hits an editable value + break; + case "up": + this.incrementDatePartValueBy(amount); + break; + case "down": + this.decrementDatePartValueBy(amount); + break; + case "delete": + case "backspace": + if (this.clearable) this.isCleared = true; + break; + } + + this.render(); + } +} \ No newline at end of file diff --git a/src/prompts/types/HierarchicalCheckboxInput.ts b/src/prompts/types/HierarchicalCheckboxInput.ts index 73ac803..92286f0 100644 --- a/src/prompts/types/HierarchicalCheckboxInput.ts +++ b/src/prompts/types/HierarchicalCheckboxInput.ts @@ -1,23 +1,26 @@ -import Prompt from "inquirer/lib/prompts/base"; -import observe from "inquirer/lib/utils/events"; +import Prompt from "inquirer/lib/prompts/base.js"; +import observe from "inquirer/lib/utils/events.js"; import { Answers, ChoiceOptions, HierarchicalCheckboxChoice, HierarchicalCheckboxQuestion, Question, - Separator, SeparatorOptions, } from "inquirer"; +import {Separator} from "../Inquire.js"; import {Interface as ReadLineInterface} from "readline"; -import {filter} from "rxjs/operators" +import {filter} from "rxjs/operators/index.js" import chalk from "chalk"; import {Subject} from "rxjs"; import figures from "figures"; -import Paginator from "inquirer/lib/utils/paginator"; -import {isPopulatedArray} from "../../utils/Arrays"; -import {filter as fuzzyFilter, FilterOptions} from "fuzzy"; -import ScreenManager from "inquirer/lib/utils/screen-manager"; +import Paginator from "inquirer/lib/utils/paginator.js"; +import {isPopulatedArray} from "../../utils/Arrays.js"; +import {FilterOptions} from "fuzzy"; +import fuzzy from "fuzzy"; +import ScreenManager from "inquirer/lib/utils/screen-manager.js"; + +const fuzzyFilter = fuzzy.filter; interface ExtendedReadLine extends ReadLineInterface { line: string diff --git a/src/prompts/types/MultiTextInput.ts b/src/prompts/types/MultiTextInput.ts index db0967e..f84fd49 100644 --- a/src/prompts/types/MultiTextInput.ts +++ b/src/prompts/types/MultiTextInput.ts @@ -1,12 +1,12 @@ -import Prompt from "inquirer/lib/prompts/base"; -import observe from "inquirer/lib/utils/events"; +import Prompt from "inquirer/lib/prompts/base.js"; +import observe from "inquirer/lib/utils/events.js"; import {Answers, MultiTextInputQuestion, Question} from "inquirer"; import {Interface as ReadLineInterface} from "readline"; -import {filter} from "rxjs/operators" +import {filter} from "rxjs/operators/index.js" import chalk from "chalk"; import {Subject} from "rxjs"; import figures from "figures"; -import Paginator from "inquirer/lib/utils/paginator"; +import Paginator from "inquirer/lib/utils/paginator.js"; interface ExtendedReadLine extends ReadLineInterface { line: string diff --git a/src/prompts/types/index.ts b/src/prompts/types/index.ts index 6b76f60..077d3cf 100644 --- a/src/prompts/types/index.ts +++ b/src/prompts/types/index.ts @@ -1,8 +1,10 @@ -import {registerPrompt} from "inquirer"; -import {MultiTextInput} from "./MultiTextInput"; -import {HierarchicalCheckboxInput} from "./HierarchicalCheckboxInput"; +import {registerPrompt} from "../Inquire.js"; +import {MultiTextInput} from "./MultiTextInput.js"; +import {HierarchicalCheckboxInput} from "./HierarchicalCheckboxInput.js"; +import {DateInput} from "./DateInput.js"; export function registerPrompts() { registerPrompt("multitext", MultiTextInput) registerPrompt("hierarchical-checkbox", HierarchicalCheckboxInput) + registerPrompt("date", DateInput) } \ No newline at end of file diff --git a/src/repository/LocalRepository.ts b/src/repository/LocalRepository.ts index fc444d7..7121ee2 100644 --- a/src/repository/LocalRepository.ts +++ b/src/repository/LocalRepository.ts @@ -1,18 +1,18 @@ -import {EmpathyGuide, EmpathyGuideJTD} from "../datatypes/EmpathyGuide"; -import {Entry} from "../datatypes/Entry"; +import {EmpathyGuide, EmpathyGuideJTD} from "../datatypes/EmpathyGuide.js"; +import {Entry} from "../datatypes/Entry.js"; import { ReferencedSchema, ReferencedTypes, schema, SchemaData, AnyReferenceList, Value -} from "../schemata/SchemaData"; +} from "../schemata/SchemaData.js"; import {rm, open, FileHandle} from "fs/promises"; import {join, dirname} from "path"; import {dump, load} from "js-yaml"; import envPaths from "env-paths"; import makeDir from "make-dir"; -import {Journal, JournalJTD} from "../datatypes/Journal"; +import {Journal, JournalJTD} from "../datatypes/Journal.js"; export type AutosaveFile = Record export type AutosaveFileJTD = typeof AutosaveFileJTD diff --git a/src/schemata/SchemaData.ts b/src/schemata/SchemaData.ts index 785b4ba..19f9462 100644 --- a/src/schemata/SchemaData.ts +++ b/src/schemata/SchemaData.ts @@ -1,5 +1,5 @@ -import AJV, {ValidateFunction, JTDSchemaType} from "ajv/dist/jtd"; +import AJV, {ValidateFunction, JTDSchemaType} from "ajv/dist/jtd.js"; const ajv = new AJV(); diff --git a/src/schemata/YAMLPrompt.ts b/src/schemata/YAMLPrompt.ts index e0dcf5e..ec93739 100644 --- a/src/schemata/YAMLPrompt.ts +++ b/src/schemata/YAMLPrompt.ts @@ -1,6 +1,6 @@ -import {AnySchemaDataFor} from "./SchemaData"; +import {AnySchemaDataFor} from "./SchemaData.js"; import {dump, load} from "js-yaml"; -import {InquireFunction, ShowFunction} from "../prompts/Inquire"; +import {InquireFunction, ShowFunction} from "../prompts/Inquire.js"; import {EditorQuestion, ExpandQuestion} from "inquirer"; const RETRY = "Retry" diff --git a/tsconfig.json b/tsconfig.json index c2c072e..2b6ae43 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -1,6 +1,6 @@ { "compilerOptions": { - "module": "commonjs", + "module": "es6", "esModuleInterop": true, "allowSyntheticDefaultImports": true, "target": "es6",