diff --git a/.pnp.cjs b/.pnp.cjs index d66258a1b..faa7910ef 100755 --- a/.pnp.cjs +++ b/.pnp.cjs @@ -59,6 +59,10 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { {\ "name": "@standardnotes/syncing-server",\ "reference": "workspace:packages/syncing-server"\ + },\ + {\ + "name": "@standardnotes/time",\ + "reference": "workspace:packages/time"\ }\ ],\ "enableTopLevelFallback": true,\ @@ -74,7 +78,8 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/scheduler-server", ["workspace:packages/scheduler"]],\ ["@standardnotes/security", ["workspace:packages/security"]],\ ["@standardnotes/server-monorepo", ["workspace:."]],\ - ["@standardnotes/syncing-server", ["workspace:packages/syncing-server"]]\ + ["@standardnotes/syncing-server", ["workspace:packages/syncing-server"]],\ + ["@standardnotes/time", ["workspace:packages/time"]]\ ],\ "fallbackPool": [\ ],\ @@ -2682,7 +2687,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@standardnotes/security", "workspace:packages/security"],\ - ["@standardnotes/time", "npm:1.7.1"],\ + ["@standardnotes/time", "workspace:packages/time"],\ ["@types/cors", "npm:2.8.12"],\ ["@types/express", "npm:4.17.13"],\ ["@types/ioredis", "npm:4.28.10"],\ @@ -2745,7 +2750,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/settings", "npm:1.15.0"],\ ["@standardnotes/sncrypto-common", "npm:1.9.0"],\ ["@standardnotes/sncrypto-node", "npm:1.8.3"],\ - ["@standardnotes/time", "npm:1.7.1"],\ + ["@standardnotes/time", "workspace:packages/time"],\ ["@types/bcryptjs", "npm:2.4.2"],\ ["@types/cors", "npm:2.8.12"],\ ["@types/express", "npm:4.17.13"],\ @@ -2893,7 +2898,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/security", "workspace:packages/security"],\ ["@standardnotes/sncrypto-common", "npm:1.9.0"],\ ["@standardnotes/sncrypto-node", "npm:1.8.3"],\ - ["@standardnotes/time", "npm:1.7.1"],\ + ["@standardnotes/time", "workspace:packages/time"],\ ["@types/connect-busboy", "npm:1.0.0"],\ ["@types/cors", "npm:2.8.12"],\ ["@types/express", "npm:4.17.13"],\ @@ -2998,7 +3003,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/domain-events", "workspace:packages/domain-events"],\ ["@standardnotes/domain-events-infra", "workspace:packages/domain-events-infra"],\ ["@standardnotes/predicates", "workspace:packages/predicates"],\ - ["@standardnotes/time", "npm:1.7.1"],\ + ["@standardnotes/time", "workspace:packages/time"],\ ["@types/ioredis", "npm:4.28.10"],\ ["@types/jest", "npm:28.1.4"],\ ["@types/newrelic", "npm:7.0.3"],\ @@ -3125,7 +3130,7 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { ["@standardnotes/responses", "npm:1.6.39"],\ ["@standardnotes/security", "workspace:packages/security"],\ ["@standardnotes/settings", "npm:1.15.0"],\ - ["@standardnotes/time", "npm:1.7.1"],\ + ["@standardnotes/time", "workspace:packages/time"],\ ["@types/cors", "npm:2.8.12"],\ ["@types/dotenv", "npm:8.2.0"],\ ["@types/express", "npm:4.17.13"],\ @@ -3167,15 +3172,21 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { }]\ ]],\ ["@standardnotes/time", [\ - ["npm:1.7.1", {\ - "packageLocation": "./.yarn/cache/@standardnotes-time-npm-1.7.1-e6859705d5-ccb9c4af73.zip/node_modules/@standardnotes/time/",\ + ["workspace:packages/time", {\ + "packageLocation": "./packages/time/",\ "packageDependencies": [\ - ["@standardnotes/time", "npm:1.7.1"],\ + ["@standardnotes/time", "workspace:packages/time"],\ + ["@types/jest", "npm:27.5.2"],\ + ["@types/microtime", "npm:2.1.0"],\ + ["@typescript-eslint/eslint-plugin", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:5.30.5"],\ ["dayjs", "npm:1.11.3"],\ + ["eslint-plugin-prettier", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:4.2.1"],\ + ["jest", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:27.5.1"],\ ["microtime", "npm:3.1.0"],\ - ["reflect-metadata", "npm:0.1.13"]\ + ["reflect-metadata", "npm:0.1.13"],\ + ["ts-jest", "virtual:c66bf20e88479ada0172094776519a9f51acc4731d22079b60a295bcec7ea42d5545cbce58a77a50d932bf953298799135e99707486e343da6d99ba1d167bdbd#npm:27.1.5"]\ ],\ - "linkType": "HARD"\ + "linkType": "SOFT"\ }]\ ]],\ ["@standardnotes/utils", [\ @@ -3510,6 +3521,15 @@ function $$SETUP_STATE(hydrateRuntimeState, basePath) { "linkType": "HARD"\ }]\ ]],\ + ["@types/microtime", [\ + ["npm:2.1.0", {\ + "packageLocation": "./.yarn/cache/@types-microtime-npm-2.1.0-111ed89518-6c23131fe4.zip/node_modules/@types/microtime/",\ + "packageDependencies": [\ + ["@types/microtime", "npm:2.1.0"]\ + ],\ + "linkType": "HARD"\ + }]\ + ]],\ ["@types/mime", [\ ["npm:1.3.2", {\ "packageLocation": "./.yarn/cache/@types-mime-npm-1.3.2-ea71878ab3-0493368244.zip/node_modules/@types/mime/",\ diff --git a/.yarn/cache/@standardnotes-time-npm-1.7.1-e6859705d5-ccb9c4af73.zip b/.yarn/cache/@standardnotes-time-npm-1.7.1-e6859705d5-ccb9c4af73.zip deleted file mode 100644 index 675bbb6c0..000000000 Binary files a/.yarn/cache/@standardnotes-time-npm-1.7.1-e6859705d5-ccb9c4af73.zip and /dev/null differ diff --git a/.yarn/cache/@types-microtime-npm-2.1.0-111ed89518-6c23131fe4.zip b/.yarn/cache/@types-microtime-npm-2.1.0-111ed89518-6c23131fe4.zip new file mode 100644 index 000000000..f41b910e0 Binary files /dev/null and b/.yarn/cache/@types-microtime-npm-2.1.0-111ed89518-6c23131fe4.zip differ diff --git a/packages/api-gateway/package.json b/packages/api-gateway/package.json index 23d7c85b1..a153207ce 100644 --- a/packages/api-gateway/package.json +++ b/packages/api-gateway/package.json @@ -28,7 +28,7 @@ "@standardnotes/domain-events": "workspace:*", "@standardnotes/domain-events-infra": "workspace:*", "@standardnotes/security": "workspace:*", - "@standardnotes/time": "^1.7.1", + "@standardnotes/time": "workspace:*", "aws-sdk": "^2.1160.0", "axios": "0.24.0", "cors": "2.8.5", diff --git a/packages/auth/package.json b/packages/auth/package.json index 318d51b76..ab837bbb3 100644 --- a/packages/auth/package.json +++ b/packages/auth/package.json @@ -45,7 +45,7 @@ "@standardnotes/settings": "^1.15.0", "@standardnotes/sncrypto-common": "^1.9.0", "@standardnotes/sncrypto-node": "^1.8.3", - "@standardnotes/time": "^1.7.1", + "@standardnotes/time": "workspace:*", "aws-sdk": "^2.1159.0", "axios": "0.24.0", "bcryptjs": "2.4.3", diff --git a/packages/files/package.json b/packages/files/package.json index 2451ea837..10089cd51 100644 --- a/packages/files/package.json +++ b/packages/files/package.json @@ -33,7 +33,7 @@ "@standardnotes/security": "workspace:*", "@standardnotes/sncrypto-common": "^1.9.0", "@standardnotes/sncrypto-node": "^1.8.3", - "@standardnotes/time": "^1.7.1", + "@standardnotes/time": "workspace:*", "aws-sdk": "^2.1158.0", "connect-busboy": "^1.0.0", "cors": "^2.8.5", diff --git a/packages/scheduler/package.json b/packages/scheduler/package.json index 202b41aa3..8623d761d 100644 --- a/packages/scheduler/package.json +++ b/packages/scheduler/package.json @@ -30,7 +30,7 @@ "@standardnotes/domain-events": "workspace:*", "@standardnotes/domain-events-infra": "workspace:*", "@standardnotes/predicates": "workspace:*", - "@standardnotes/time": "^1.7.1", + "@standardnotes/time": "workspace:*", "aws-sdk": "^2.1158.0", "dayjs": "^1.11.3", "dotenv": "8.2.0", diff --git a/packages/syncing-server/package.json b/packages/syncing-server/package.json index a7ac6eb6e..cf5d1cdf4 100644 --- a/packages/syncing-server/package.json +++ b/packages/syncing-server/package.json @@ -34,7 +34,7 @@ "@standardnotes/responses": "^1.6.39", "@standardnotes/security": "workspace:*", "@standardnotes/settings": "1.15.0", - "@standardnotes/time": "^1.7.1", + "@standardnotes/time": "workspace:*", "aws-sdk": "^2.1159.0", "axios": "0.24.0", "cors": "2.8.5", diff --git a/packages/time/.eslintignore b/packages/time/.eslintignore new file mode 100644 index 000000000..1521c8b76 --- /dev/null +++ b/packages/time/.eslintignore @@ -0,0 +1 @@ +dist diff --git a/packages/time/.eslintrc b/packages/time/.eslintrc new file mode 100644 index 000000000..cb7136174 --- /dev/null +++ b/packages/time/.eslintrc @@ -0,0 +1,6 @@ +{ + "extends": "../../.eslintrc", + "parserOptions": { + "project": "./linter.tsconfig.json" + } +} diff --git a/packages/time/CHANGELOG.md b/packages/time/CHANGELOG.md new file mode 100644 index 000000000..a950df824 --- /dev/null +++ b/packages/time/CHANGELOG.md @@ -0,0 +1,182 @@ +# Change Log + +All notable changes to this project will be documented in this file. +See [Conventional Commits](https://conventionalcommits.org) for commit guidelines. + +## [1.7.2](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.7.1...@standardnotes/time@1.7.2) (2022-07-04) + +**Note:** Version bump only for package @standardnotes/time + +## [1.7.1](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.7.0...@standardnotes/time@1.7.1) (2022-06-23) + +### Bug Fixes + +* upgrade microtime package version ([65ec0e6](https://github.com/standardnotes/snjs/commit/65ec0e6f3a72718aa490f30a168fbdd13b5a4c76)) + +# [1.7.0](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.10...@standardnotes/time@1.7.0) (2022-05-30) + +### Features + +* getting timestamp in seconds ([24c3215](https://github.com/standardnotes/snjs/commit/24c3215fd0797b60eec10a88583c0ed8c7020387)) + +## [1.6.10](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.9...@standardnotes/time@1.6.10) (2022-05-30) + +### Bug Fixes + +* add converting string dates to seconds ([f1ccbc9](https://github.com/standardnotes/snjs/commit/f1ccbc929fbd9a452ca87cbaf88bf4ce30855c91)) + +## [1.6.9](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.7...@standardnotes/time@1.6.9) (2022-05-04) + +**Note:** Version bump only for package @standardnotes/time + +## [1.6.8](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.7...@standardnotes/time@1.6.8) (2022-05-04) + +**Note:** Version bump only for package @standardnotes/time + +## [1.6.7](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.6...@standardnotes/time@1.6.7) (2022-04-22) + +**Note:** Version bump only for package @standardnotes/time + +## [1.6.6](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.5...@standardnotes/time@1.6.6) (2022-04-15) + +**Note:** Version bump only for package @standardnotes/time + +## [1.6.5](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.4...@standardnotes/time@1.6.5) (2022-04-11) + +**Note:** Version bump only for package @standardnotes/time + +## [1.6.4](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.3...@standardnotes/time@1.6.4) (2022-03-31) + +**Note:** Version bump only for package @standardnotes/time + +## [1.6.3](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.1...@standardnotes/time@1.6.3) (2022-02-28) + +### Bug Fixes + +* add pseudo change to get lerna to trigger ([41e6817](https://github.com/standardnotes/snjs/commit/41e6817bbf726b0932cdf16f58622328b9e42803)) + +## [1.6.2](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.1...@standardnotes/time@1.6.2) (2022-02-28) + +### Bug Fixes + +* add pseudo change to get lerna to trigger ([41e6817](https://github.com/standardnotes/snjs/commit/41e6817bbf726b0932cdf16f58622328b9e42803)) + +## [1.6.1](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.6.0...@standardnotes/time@1.6.1) (2022-02-10) + +### Bug Fixes + +* timer tests with utc dates ([c0b15a2](https://github.com/standardnotes/snjs/commit/c0b15a2ae45632615fa5e4064d5210bdd97ff237)) + +# [1.6.0](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.5.0...@standardnotes/time@1.6.0) (2022-02-09) + +### Features + +* add date formatting ([4c65cb8](https://github.com/standardnotes/snjs/commit/4c65cb82b1acd842f7e35fb79389de95bef0ddcf)) + +# [1.5.0](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.4.5...@standardnotes/time@1.5.0) (2022-02-09) + +### Features + +* add calculating time difference in days ([1348065](https://github.com/standardnotes/snjs/commit/1348065eb2bd7a559046a0f125751b32ad224d93)) + +## [1.4.5](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.4.4...@standardnotes/time@1.4.5) (2021-12-29) + +**Note:** Version bump only for package @standardnotes/time + +## [1.4.4](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.4.3...@standardnotes/time@1.4.4) (2021-12-29) + +**Note:** Version bump only for package @standardnotes/time + +## [1.4.3](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.4.2...@standardnotes/time@1.4.3) (2021-12-29) + +**Note:** Version bump only for package @standardnotes/time + +## [1.4.2](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.4.1...@standardnotes/time@1.4.2) (2021-12-29) + +### Bug Fixes + +* remove code coverage reports from repository ([61f5dfd](https://github.com/standardnotes/snjs/commit/61f5dfd8e9698e36142df131ad210749865f70f4)) + +## [1.4.1](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.4.0...@standardnotes/time@1.4.1) (2021-12-29) + +### Bug Fixes + +* correct gitignore paths ([cefc0cf](https://github.com/standardnotes/snjs/commit/cefc0cfcf98e3e5378e055b8c46931b53b23195e)) +* include dist in static components ([d17ce0f](https://github.com/standardnotes/snjs/commit/d17ce0f67045c6e4c97bf4577709aa58794e72e6)) + +# 1.4.0 (2021-12-23) + +### Features + +* rename email backup setting to email backup frequency ([25e7b46](https://github.com/standardnotes/snjs/commit/25e7b4620834711ac7f513ae893898c5eab1af53)) + +## 1.3.3 (2021-12-23) + +### Bug Fixes + +* lock package versions ([8aa2ce6](https://github.com/standardnotes/snjs/commit/8aa2ce676b57598ab72840adf851869d8e769022)) + +## 1.3.2 (2021-12-23) + +### Bug Fixes + +* add publishing from package version by lerna ([80433d0](https://github.com/standardnotes/snjs/commit/80433d044f258095753482b8322d73aba3d9a9e4)) + +## 1.3.1 (2021-12-23) + +### Bug Fixes + +* remove the ammend commit from lerna versioning ([f0400d9](https://github.com/standardnotes/snjs/commit/f0400d9a2f5a04eaece2e4c16da71166a2ddb251)) + +# 1.3.0 (2021-12-23) + +### Features + +* add one drive backup frequency setting ([#522](https://github.com/standardnotes/snjs/issues/522)) ([c27827f](https://github.com/standardnotes/snjs/commit/c27827f8c7969dd32511c9c75122ece372132c83)) + +## 1.2.4 (2021-12-23) + +### Bug Fixes + +* remove running tests upon deployment - ensured on PR status checks ([#523](https://github.com/standardnotes/snjs/issues/523)) ([5c795d1](https://github.com/standardnotes/snjs/commit/5c795d17b583d02955773576384e622c3ef7f418)) + +## 1.2.3 (2021-12-23) + +### Bug Fixes + +* pr template ([#518](https://github.com/standardnotes/snjs/issues/518)) ([b445bb6](https://github.com/standardnotes/snjs/commit/b445bb64841217ae27c2514887629235be95d2a3)) + +## 1.2.2 (2021-12-23) + +### Bug Fixes + +* checkout with personal access token ([773c1ef](https://github.com/standardnotes/snjs/commit/773c1ef91c4452ad411e928342060dcb59428e3c)) + +## 1.2.1 (2021-12-22) + +### Bug Fixes + +* gpg signing with CI StandardNotes user ([d72f61c](https://github.com/standardnotes/snjs/commit/d72f61c23cd15b31d37340cc756d16526634b9ee)) + +# [1.2.0](https://github.com/standardnotes/snjs/compare/@standardnotes/time@1.1.0...@standardnotes/time@1.2.0) (2021-12-22) + +### Features + +* add converting date to microseconds ([#516](https://github.com/standardnotes/snjs/issues/516)) ([a3dfd9e](https://github.com/standardnotes/snjs/commit/a3dfd9eccb275734ecd381cfb9fbb3fa132aa0ac)) + +# 1.1.0 (2021-12-22) + +### Bug Fixes + +* add n days ahead method for timer ([#443](https://github.com/standardnotes/snjs/issues/443)) ([63926da](https://github.com/standardnotes/snjs/commit/63926da495c8b0fbaf1cddb595f7e2a90185b207)) +* timer specs ([e782a14](https://github.com/standardnotes/snjs/commit/e782a14b023954b1b9d112111d4bc15ed746a8ae)) +* versioning and package dependencies ([#509](https://github.com/standardnotes/snjs/issues/509)) ([fe1df94](https://github.com/standardnotes/snjs/commit/fe1df94eff3e90bcf9ba0cf45bdc44ac49204c71)) + +### Features + +* add converting date to milliseconds ([#513](https://github.com/standardnotes/snjs/issues/513)) ([088bfcf](https://github.com/standardnotes/snjs/commit/088bfcf37ed98a5385735cd7c5ce8155bf276b16)) +* add method for getting n days ago date ([#434](https://github.com/standardnotes/snjs/issues/434)) ([4aa91c1](https://github.com/standardnotes/snjs/commit/4aa91c10a3612bff7f1c10a8660e1da4d5cbc492)) +* add n-hours ahead and ago methods for timer ([7ced52d](https://github.com/standardnotes/snjs/commit/7ced52db6dabccb8f1c203b73d6237be75ed4fb7)) +* add time package ([#311](https://github.com/standardnotes/snjs/issues/311)) ([f50d8aa](https://github.com/standardnotes/snjs/commit/f50d8aa11dd8c72f6ae03c281fc00a048937f623)) +* features instead of permissions ([#385](https://github.com/standardnotes/snjs/issues/385)) ([b53e967](https://github.com/standardnotes/snjs/commit/b53e967297bc472ed11aed79af79d0ae5b36d101)) +* upgrade node engine versions to latest active LTS ([#462](https://github.com/standardnotes/snjs/issues/462)) ([686fc15](https://github.com/standardnotes/snjs/commit/686fc15030d302b474ebb7ef1cd4dcc48ec42359)) diff --git a/packages/time/jest.config.js b/packages/time/jest.config.js new file mode 100644 index 000000000..e62343845 --- /dev/null +++ b/packages/time/jest.config.js @@ -0,0 +1,11 @@ +// eslint-disable-next-line @typescript-eslint/no-var-requires +const base = require('../../jest.config'); + +module.exports = { + ...base, + globals: { + 'ts-jest': { + tsconfig: 'tsconfig.json', + }, + } +}; diff --git a/packages/time/linter.tsconfig.json b/packages/time/linter.tsconfig.json new file mode 100644 index 000000000..c1a7d22c5 --- /dev/null +++ b/packages/time/linter.tsconfig.json @@ -0,0 +1,4 @@ +{ + "extends": "./tsconfig.json", + "exclude": ["dist"] +} diff --git a/packages/time/package.json b/packages/time/package.json new file mode 100644 index 000000000..96db108a3 --- /dev/null +++ b/packages/time/package.json @@ -0,0 +1,39 @@ +{ + "name": "@standardnotes/time", + "version": "1.8.0", + "engines": { + "node": ">=16.0.0 <17.0.0" + }, + "description": "Utilities for time processing and calculation", + "main": "dist/src/index.js", + "types": "dist/src/index.d.ts", + "files": [ + "dist/src/**/*.js", + "dist/src/**/*.d.ts" + ], + "publishConfig": { + "access": "public" + }, + "author": "Standard Notes", + "license": "AGPL-3.0-or-later", + "scripts": { + "clean": "rm -fr dist", + "prebuild": "yarn clean", + "build": "tsc -p tsconfig.json", + "lint": "eslint . --ext .ts", + "test:unit": "jest spec --coverage" + }, + "dependencies": { + "dayjs": "^1.10.8", + "microtime": "^3.1.0", + "reflect-metadata": "^0.1.13" + }, + "devDependencies": { + "@types/jest": "^27.4.1", + "@types/microtime": "^2.1.0", + "@typescript-eslint/eslint-plugin": "^5.30.0", + "eslint-plugin-prettier": "^4.2.1", + "jest": "^27.5.1", + "ts-jest": "^27.1.3" + } +} diff --git a/packages/time/src/Domain/Time/Time.ts b/packages/time/src/Domain/Time/Time.ts new file mode 100644 index 000000000..3a55c1016 --- /dev/null +++ b/packages/time/src/Domain/Time/Time.ts @@ -0,0 +1,4 @@ +export enum Time { + MicrosecondsInASecond = 1_000_000, + MicrosecondsInAMillisecond = 1_000, +} diff --git a/packages/time/src/Domain/Time/Timer.spec.ts b/packages/time/src/Domain/Time/Timer.spec.ts new file mode 100644 index 000000000..813d66c1c --- /dev/null +++ b/packages/time/src/Domain/Time/Timer.spec.ts @@ -0,0 +1,111 @@ +import 'reflect-metadata' + +import { Timer } from './Timer' + +describe('Timer', () => { + const createTimer = () => new Timer() + + it('should return a timestamp in microseconds', () => { + const timestamp = createTimer().getTimestampInMicroseconds() + expect(`${timestamp}`.length).toEqual(16) + }) + + it('should return a timestamp in seconds', () => { + const timestamp = createTimer().getTimestampInSeconds() + expect(`${timestamp}`.length).toEqual(10) + }) + + it('should return a utc date', () => { + const date = createTimer().getUTCDate() + expect(date).toBeInstanceOf(Date) + }) + + it('should return a utc date n days ago', () => { + const date = createTimer().getUTCDate() + const dateNDaysAgo = createTimer().getUTCDateNDaysAgo(4) + + expect(+date - +dateNDaysAgo >= 4 * 24 * 3600).toBeTruthy() + }) + + it('should return a utc date n days ahead', () => { + const date = createTimer().getUTCDate() + const dateNDaysAhead = createTimer().getUTCDateNDaysAhead(4) + + expect(+dateNDaysAhead - +date >= 4 * 24 * 3600).toBeTruthy() + }) + + it('should calculate days difference between now and a given date', () => { + const dateNDaysAgo = createTimer().getUTCDateNDaysAgo(4) + + expect(createTimer().dateWasNDaysAgo(dateNDaysAgo)).toEqual(4) + }) + + it('should return a utc date n hours ago', () => { + const date = createTimer().getUTCDate() + const dateNHoursAgo = createTimer().getUTCDateNHoursAgo(4) + + expect(+date - +dateNHoursAgo >= 4 * 3600).toBeTruthy() + }) + + it('should return a utc date n hours ahead', () => { + const date = createTimer().getUTCDate() + const dateNHoursAhead = createTimer().getUTCDateNHoursAhead(4) + + expect(+dateNHoursAhead - +date >= 4 * 3600).toBeTruthy() + }) + + it('should convert a date to milliseconds', () => { + const timestamp = createTimer().convertDateToMilliseconds(new Date(Date.UTC(2021, 2, 29, 12, 13, 45))) + expect(timestamp).toEqual(1617020025000) + }) + + it('should convert a date to microseconds', () => { + const timestamp = createTimer().convertDateToMicroseconds(new Date(Date.UTC(2021, 2, 29, 8, 0, 5, 233))) + expect(timestamp).toEqual(1617004805000000) + }) + + it('should convert a date to iso string', () => { + const isoString = createTimer().convertDateToISOString(new Date(Date.UTC(2021, 2, 29, 8, 0, 5))) + expect(isoString).toEqual('2021-03-29T08:00:05.000Z') + }) + + it('should convert a string date to microseconds', () => { + const timestamp = createTimer().convertStringDateToMicroseconds('2021-03-29 08:00:05.233Z') + expect(timestamp).toEqual(1617004805233000) + }) + + it('should convert a string date to seconds', () => { + const timestamp = createTimer().convertStringDateToSeconds('2021-03-29 08:00:05.233Z') + expect(timestamp).toEqual(1617004805) + }) + + it('should convert microseconds to string date', () => { + expect(createTimer().convertMicrosecondsToStringDate(1617004805233123)).toEqual('2021-03-29T08:00:05.233123Z') + }) + + it('should convert a string date to milliseconds', () => { + const timestamp = createTimer().convertStringDateToMilliseconds('Mon Mar 29 2021 12:13:45 GMT+0200') + expect(timestamp).toEqual(1617012825000) + }) + + it('should convert a string date to date', () => { + const date = createTimer().convertStringDateToDate('Mon Mar 29 2021 12:13:45 GMT+0200') + expect(date).toEqual(new Date(1617012825000)) + }) + + it('should convert microseconds to date', () => { + expect(createTimer().convertMicrosecondsToDate(1617004805233123)).toEqual(new Date('2021-03-29T08:00:05.233123Z')) + }) + + it('should convert microseconds to milliseconds', () => { + expect(createTimer().convertMicrosecondsToMilliseconds(1616164633241312)).toEqual(1616164633241) + }) + + it('should convert microseconds to seconds', () => { + expect(createTimer().convertMicrosecondsToSeconds(1616164633241312)).toEqual(1616164633) + }) + + it('should format date', () => { + expect(createTimer().formatDate(new Date('2021-03-29T08:00:05.233123Z'), 'YYYY-MM-DD')).toEqual('2021-03-29') + }) +}) diff --git a/packages/time/src/Domain/Time/Timer.ts b/packages/time/src/Domain/Time/Timer.ts new file mode 100644 index 000000000..078bda4a9 --- /dev/null +++ b/packages/time/src/Domain/Time/Timer.ts @@ -0,0 +1,95 @@ +import * as dayjs from 'dayjs' +import * as utc from 'dayjs/plugin/utc' +import * as microtime from 'microtime' +import { Time } from './Time' +import { TimerInterface } from './TimerInterface' + +export class Timer implements TimerInterface { + constructor() { + dayjs.extend(utc) + } + + formatDate(date: Date, format: string): string { + return dayjs.utc(date).format(format) + } + + convertDateToMilliseconds(date: Date): number { + return this.convertStringDateToMilliseconds(date.toString()) + } + + convertDateToMicroseconds(date: Date): number { + return this.convertStringDateToMicroseconds(date.toString()) + } + + convertMicrosecondsToSeconds(microseconds: number): number { + return Math.floor(microseconds / Time.MicrosecondsInASecond) + } + + getTimestampInMicroseconds(): number { + return microtime.now() + } + + getTimestampInSeconds(): number { + return this.convertMicrosecondsToSeconds(this.getTimestampInMicroseconds()) + } + + getUTCDate(): Date { + return dayjs.utc().toDate() + } + + getUTCDateNDaysAgo(n: number): Date { + return dayjs.utc().subtract(n, 'days').toDate() + } + + getUTCDateNDaysAhead(n: number): Date { + return dayjs.utc().add(n, 'days').toDate() + } + + getUTCDateNHoursAgo(n: number): Date { + return dayjs.utc().subtract(n, 'hours').toDate() + } + + getUTCDateNHoursAhead(n: number): Date { + return dayjs.utc().add(n, 'hours').toDate() + } + + convertStringDateToDate(date: string): Date { + return dayjs.utc(date).toDate() + } + + convertDateToISOString(date: Date): string { + return dayjs.utc(date).toISOString() + } + + dateWasNDaysAgo(date: Date): number { + return dayjs.utc().diff(date, 'days') + } + + convertStringDateToMicroseconds(date: string): number { + return this.convertStringDateToMilliseconds(date) * Time.MicrosecondsInAMillisecond + } + + convertStringDateToMilliseconds(date: string): number { + return dayjs.utc(date).valueOf() + } + + convertStringDateToSeconds(date: string): number { + return this.convertMicrosecondsToSeconds(this.convertStringDateToMicroseconds(date)) + } + + convertMicrosecondsToMilliseconds(microseconds: number): number { + return Math.floor(microseconds / Time.MicrosecondsInAMillisecond) + } + + convertMicrosecondsToStringDate(microseconds: number): string { + const milliseconds = this.convertMicrosecondsToMilliseconds(microseconds) + + const microsecondsString = microseconds.toString().substring(13) + + return dayjs.utc(milliseconds).format(`YYYY-MM-DDTHH:mm:ss.SSS${microsecondsString}[Z]`) + } + + convertMicrosecondsToDate(microseconds: number): Date { + return this.convertStringDateToDate(this.convertMicrosecondsToStringDate(microseconds)) + } +} diff --git a/packages/time/src/Domain/Time/TimerInterface.ts b/packages/time/src/Domain/Time/TimerInterface.ts new file mode 100644 index 000000000..d570bcfc5 --- /dev/null +++ b/packages/time/src/Domain/Time/TimerInterface.ts @@ -0,0 +1,22 @@ +export interface TimerInterface { + getTimestampInMicroseconds(): number + getTimestampInSeconds(): number + getUTCDate(): Date + getUTCDateNDaysAgo(n: number): Date + getUTCDateNDaysAhead(n: number): Date + getUTCDateNHoursAgo(n: number): Date + getUTCDateNHoursAhead(n: number): Date + convertDateToMilliseconds(date: Date): number + convertDateToMicroseconds(date: Date): number + convertDateToISOString(date: Date): string + convertStringDateToDate(date: string): Date + convertStringDateToMicroseconds(date: string): number + convertStringDateToMilliseconds(date: string): number + convertStringDateToSeconds(date: string): number + convertMicrosecondsToMilliseconds(microseconds: number): number + convertMicrosecondsToSeconds(microseconds: number): number + convertMicrosecondsToStringDate(microseconds: number): string + convertMicrosecondsToDate(microseconds: number): Date + formatDate(date: Date, format: string): string + dateWasNDaysAgo(date: Date): number +} diff --git a/packages/time/src/Domain/index.ts b/packages/time/src/Domain/index.ts new file mode 100644 index 000000000..acc1c966b --- /dev/null +++ b/packages/time/src/Domain/index.ts @@ -0,0 +1,3 @@ +export * from './Time/Time' +export * from './Time/Timer' +export * from './Time/TimerInterface' diff --git a/packages/time/src/index.ts b/packages/time/src/index.ts new file mode 100644 index 000000000..920deacdb --- /dev/null +++ b/packages/time/src/index.ts @@ -0,0 +1 @@ +export * from './Domain' diff --git a/packages/time/tsconfig.json b/packages/time/tsconfig.json new file mode 100644 index 000000000..8d2588d39 --- /dev/null +++ b/packages/time/tsconfig.json @@ -0,0 +1,11 @@ +{ + "extends": "../../tsconfig.json", + "compilerOptions": { + "composite": true, + "outDir": "./dist", + }, + "include": [ + "src/**/*" + ], + "references": [] +} diff --git a/tsconfig.json b/tsconfig.json index fe8f9e745..3f2452d83 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -51,6 +51,9 @@ }, { "path": "./packages/syncing-server" + }, + { + "path": "./packages/time" } ] } diff --git a/yarn.lock b/yarn.lock index 37909f5bb..bab691acf 100644 --- a/yarn.lock +++ b/yarn.lock @@ -1964,7 +1964,7 @@ __metadata: "@standardnotes/domain-events": "workspace:*" "@standardnotes/domain-events-infra": "workspace:*" "@standardnotes/security": "workspace:*" - "@standardnotes/time": ^1.7.1 + "@standardnotes/time": "workspace:*" "@types/cors": ^2.8.9 "@types/express": ^4.17.11 "@types/ioredis": ^4.28.10 @@ -2028,7 +2028,7 @@ __metadata: "@standardnotes/settings": ^1.15.0 "@standardnotes/sncrypto-common": ^1.9.0 "@standardnotes/sncrypto-node": ^1.8.3 - "@standardnotes/time": ^1.7.1 + "@standardnotes/time": "workspace:*" "@types/bcryptjs": ^2.4.2 "@types/cors": ^2.8.9 "@types/express": ^4.17.11 @@ -2175,7 +2175,7 @@ __metadata: "@standardnotes/security": "workspace:*" "@standardnotes/sncrypto-common": ^1.9.0 "@standardnotes/sncrypto-node": ^1.8.3 - "@standardnotes/time": ^1.7.1 + "@standardnotes/time": "workspace:*" "@types/connect-busboy": ^1.0.0 "@types/cors": ^2.8.9 "@types/express": ^4.17.11 @@ -2273,7 +2273,7 @@ __metadata: "@standardnotes/domain-events": "workspace:*" "@standardnotes/domain-events-infra": "workspace:*" "@standardnotes/predicates": "workspace:*" - "@standardnotes/time": ^1.7.1 + "@standardnotes/time": "workspace:*" "@types/ioredis": ^4.28.10 "@types/jest": ^28.1.2 "@types/newrelic": ^7.0.3 @@ -2388,7 +2388,7 @@ __metadata: "@standardnotes/responses": ^1.6.39 "@standardnotes/security": "workspace:*" "@standardnotes/settings": 1.15.0 - "@standardnotes/time": ^1.7.1 + "@standardnotes/time": "workspace:*" "@types/cors": ^2.8.9 "@types/dotenv": ^8.2.0 "@types/express": ^4.17.9 @@ -2428,16 +2428,21 @@ __metadata: languageName: unknown linkType: soft -"@standardnotes/time@npm:^1.7.1": - version: 1.7.1 - resolution: "@standardnotes/time@npm:1.7.1" +"@standardnotes/time@workspace:*, @standardnotes/time@workspace:packages/time": + version: 0.0.0-use.local + resolution: "@standardnotes/time@workspace:packages/time" dependencies: + "@types/jest": ^27.4.1 + "@types/microtime": ^2.1.0 + "@typescript-eslint/eslint-plugin": ^5.30.0 dayjs: ^1.10.8 + eslint-plugin-prettier: ^4.2.1 + jest: ^27.5.1 microtime: ^3.1.0 reflect-metadata: ^0.1.13 - checksum: ccb9c4af73d2c77d5b1cfea480930e3a30e87fb426eee3c60eb0ce0f259fa5c1f9b1b29fdc52c72d321821791e3bdc141e4af0bfc668662863012743332c5407 - languageName: node - linkType: hard + ts-jest: ^27.1.3 + languageName: unknown + linkType: soft "@standardnotes/utils@npm:^1.4.6, @standardnotes/utils@npm:^1.6.12": version: 1.6.12 @@ -2731,6 +2736,13 @@ __metadata: languageName: node linkType: hard +"@types/microtime@npm:^2.1.0": + version: 2.1.0 + resolution: "@types/microtime@npm:2.1.0" + checksum: 6c23131fe46fd1b059c8d7e474a5ab60e703cf0f4a6ab0e3dbe36f1d394359fb4712dca696ff891b15482855465e6febc16acc56eaaf500864283d758b0c8dca + languageName: node + linkType: hard + "@types/mime@npm:^1": version: 1.3.2 resolution: "@types/mime@npm:1.3.2"