From 0507722ecfdff176b6628e3c14821b28d43652e5 Mon Sep 17 00:00:00 2001 From: David Rousselie Date: Fri, 26 Jan 2024 08:48:27 +0100 Subject: [PATCH] feat: Add notification actions --- .eslintrc.json | 8 +- .prettierrc | 5 +- justfile | 4 + package-lock.json | 1300 ++++++++++++++++- package.json | 9 +- src/NotificationActions.tsx | 73 - src/action/CreateTaskFromNotification.tsx | 152 ++ src/action/LinkNotificationToTask.tsx | 109 ++ src/action/NotificationActions.tsx | 200 +++ src/{ => action}/NotificationTaskActions.tsx | 16 +- src/api.ts | 20 + src/index.tsx | 41 +- .../github/{misc.tsx => accessories.ts} | 2 +- .../GithubDiscussionNotificationListItem.tsx | 15 +- .../GithubNotificationListItem.tsx | 10 +- .../GithubPullRequestNotificationListItem.tsx | 15 +- .../preview/GithubDiscussionPreview.tsx | 3 +- .../preview/GithubPullRequestPreview.tsx | 3 +- .../GoogleMailNotificationListItem.tsx | 12 +- .../linear/LinearNotificationListItem.tsx | 12 +- .../todoist/TodoistNotificationListItem.tsx | 7 +- src/notification.ts | 45 +- src/task.ts | 41 + src/types.ts | 37 - 24 files changed, 1967 insertions(+), 172 deletions(-) delete mode 100644 src/NotificationActions.tsx create mode 100644 src/action/CreateTaskFromNotification.tsx create mode 100644 src/action/LinkNotificationToTask.tsx create mode 100644 src/action/NotificationActions.tsx rename src/{ => action}/NotificationTaskActions.tsx (82%) create mode 100644 src/api.ts rename src/integrations/github/{misc.tsx => accessories.ts} (100%) rename src/integrations/github/{ => listitem}/GithubNotificationListItem.tsx (65%) create mode 100644 src/task.ts diff --git a/.eslintrc.json b/.eslintrc.json index e6258e1..0e0979a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -1,4 +1,10 @@ { "root": true, - "extends": ["@raycast"] + "extends": ["@raycast", "plugin:import/recommended", "plugin:import/typescript"], + "settings": { + "import/resolver": { + "typescript": true, + "node": true + } + } } diff --git a/.prettierrc b/.prettierrc index b7d51e0..5345ef9 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,4 +1,5 @@ { "printWidth": 120, - "singleQuote": false -} \ No newline at end of file + "singleQuote": false, + "plugins": ["./node_modules/prettier-plugin-sort-imports/dist/index.js"] +} diff --git a/justfile b/justfile index 8da12d9..69050d5 100644 --- a/justfile +++ b/justfile @@ -5,6 +5,10 @@ default: build: npm run build +# Format code +format: + npm run format + # Lint extension code lint: npm run lint diff --git a/package-lock.json b/package-lock.json index 9bfd254..78219b0 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,14 +9,20 @@ "dependencies": { "@raycast/api": "^1.65.1", "@raycast/utils": "^1.10.1", - "node-fetch": "^3.3.2" + "dayjs": "^1.11.10", + "node-fetch": "^3.3.2", + "ts-pattern": "^5.0.6" }, "devDependencies": { "@raycast/eslint-config": "^1.0.6", "@types/node": "20.8.10", "@types/react": "18.2.27", + "@typescript-eslint/parser": "^6.19.1", "eslint": "^8.56.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", "prettier": "^3.0.3", + "prettier-plugin-sort-imports": "^1.8.3", "typescript": "^5.3.3" } }, @@ -286,6 +292,12 @@ "integrity": "sha512-5+fP8P8MFNC+AyZCDxrB2pkZFPGzqQWUzpSeuuVLvm8VMcorNYavBqoFcxK8bQz4Qsbn4oUEEem4wDLfcysGHA==", "dev": true }, + "node_modules/@types/json5": { + "version": "0.0.29", + "resolved": "https://registry.npmjs.org/@types/json5/-/json5-0.0.29.tgz", + "integrity": "sha512-dRLjCWHYg4oaA77cxO64oO+7JwCwnIzkZPdrrC71jQmQtlhM556pwKo5bUzqvZndkVbeFLIIi+9TC40JNF5hNQ==", + "dev": true + }, "node_modules/@types/node": { "version": "20.8.10", "resolved": "https://registry.npmjs.org/@types/node/-/node-20.8.10.tgz", @@ -708,6 +720,38 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "node_modules/array-buffer-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/array-buffer-byte-length/-/array-buffer-byte-length-1.0.0.tgz", + "integrity": "sha512-LPuwb2P+NrQw3XhxGc36+XSvuBPopovXYTR9Ew++Du9Yb/bx5AzBfrIsBoj0EZUifjQU+sHL21sseZ3jerWO/A==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "is-array-buffer": "^3.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array-includes": { + "version": "3.1.7", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.1.7.tgz", + "integrity": "sha512-dlcsNBIiWhPkHdOEEKnehA+RNUWDc4UqFtnIXU4uuYDPtA4LDkr7qip2p0VvFAEXNDr0yWZ9PJyIRiGjRLQzwQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-string": "^1.0.7" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/array-union": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz", @@ -717,6 +761,94 @@ "node": ">=8" } }, + "node_modules/array.prototype.findlastindex": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/array.prototype.findlastindex/-/array.prototype.findlastindex-1.2.3.tgz", + "integrity": "sha512-LzLoiOMAxvy+Gd3BAq3B7VeIgPdo+Q8hthvKtXybMvRV0jrXfJM/t8mw7nNlpEcVlVUnCnM2KSX4XU5HmpodOA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0", + "get-intrinsic": "^1.2.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flat": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flat/-/array.prototype.flat-1.3.2.tgz", + "integrity": "sha512-djYB+Zx2vLewY8RWlNCUdHjDXs2XOgm602S9E7P/UpHgfeHL00cRiIF+IN/G/aUJ7kGPb6yO/ErDI5V2s8iycA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/array.prototype.flatmap": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/array.prototype.flatmap/-/array.prototype.flatmap-1.3.2.tgz", + "integrity": "sha512-Ewyx0c9PmpcsByhSW4r+9zDU7sGjFc86qf/kKtuSCRdhfbk0SNLLkaT5qvcHnRGgc5NP/ly/y+qkXkqONX54CQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "es-shim-unscopables": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/arraybuffer.prototype.slice": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/arraybuffer.prototype.slice/-/arraybuffer.prototype.slice-1.0.2.tgz", + "integrity": "sha512-yMBKppFur/fbHu9/6USUe03bZ4knMYiwFBcyiaXB8Go0qNehwX6inYPzK9U0NeQvGxKthcmHcaR8P5MStSRBAw==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1", + "is-array-buffer": "^3.0.2", + "is-shared-array-buffer": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/available-typed-arrays": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/available-typed-arrays/-/available-typed-arrays-1.0.5.tgz", + "integrity": "sha512-DMD0KiN46eipeziST1LPP/STfDU0sufISXmjSgvVsoU2tqxctQeASejWcfNtxYKqETM1UxQ8sp2OrSBWpHY6sw==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/balanced-match": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", @@ -744,6 +876,20 @@ "node": ">=8" } }, + "node_modules/call-bind": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.5.tgz", + "integrity": "sha512-C3nQxfFZxFRVoJoGKKI8y3MOEo129NQ+FgQ08iye+Mk4zNZZGdjfs06bVTr+DBSlA66Q2VEcMki/cUCP4SercQ==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.1", + "set-function-length": "^1.1.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/callsites": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", @@ -855,6 +1001,11 @@ "node": ">= 12" } }, + "node_modules/dayjs": { + "version": "1.11.10", + "resolved": "https://registry.npmjs.org/dayjs/-/dayjs-1.11.10.tgz", + "integrity": "sha512-vjAczensTgRcqDERK0SR2XMwsF/tSvnvlv6VcF2GIhg6Sx4yOIt/irsr1RDJsKiIyBzJDpCoXiWWq28MqH2cnQ==" + }, "node_modules/debug": { "version": "4.3.4", "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", @@ -878,6 +1029,37 @@ "integrity": "sha512-oIPzksmTg4/MriiaYGO+okXDT7ztn/w3Eptv/+gSIdMdKsJo0u4CfYNFJPy+4SKMuCqGw2wxnA+URMg3t8a/bQ==", "dev": true }, + "node_modules/define-data-property": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.1.tgz", + "integrity": "sha512-E7uGkTzkk1d0ByLeSc6ZsFS79Axg+m1P/VsgYsxHgiuc3tFSj+MjMIwe90FC4lOAZzNBdY7kkO2P2wKdsQ1vgQ==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.1", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/define-properties": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.2.1.tgz", + "integrity": "sha512-8QmQKqEASLd5nx0U1B1okLElbUuuttJ/AnYmRXbbbGDWh6uS208EjD4Xqq/I9wK7u0v6O08XhTWnt5XtEbR6Dg==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/dequal": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/dequal/-/dequal-2.0.3.tgz", @@ -910,6 +1092,112 @@ "node": ">=6.0.0" } }, + "node_modules/enhanced-resolve": { + "version": "5.15.0", + "resolved": "https://registry.npmjs.org/enhanced-resolve/-/enhanced-resolve-5.15.0.tgz", + "integrity": "sha512-LXYT42KJ7lpIKECr2mAXIaMldcNCh/7E0KBKOu4KSfkHmP+mZmSs+8V5gBAqisWBy0OO4W5Oyys0GO1Y8KtdKg==", + "dev": true, + "dependencies": { + "graceful-fs": "^4.2.4", + "tapable": "^2.2.0" + }, + "engines": { + "node": ">=10.13.0" + } + }, + "node_modules/es-abstract": { + "version": "1.22.3", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.22.3.tgz", + "integrity": "sha512-eiiY8HQeYfYH2Con2berK+To6GrK2RxbPawDkGq4UiCQQfZHb6wX9qQqkbpPqaxQFcl8d9QzZqo0tGE0VcrdwA==", + "dev": true, + "dependencies": { + "array-buffer-byte-length": "^1.0.0", + "arraybuffer.prototype.slice": "^1.0.2", + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.5", + "es-set-tostringtag": "^2.0.1", + "es-to-primitive": "^1.2.1", + "function.prototype.name": "^1.1.6", + "get-intrinsic": "^1.2.2", + "get-symbol-description": "^1.0.0", + "globalthis": "^1.0.3", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.0", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0", + "internal-slot": "^1.0.5", + "is-array-buffer": "^3.0.2", + "is-callable": "^1.2.7", + "is-negative-zero": "^2.0.2", + "is-regex": "^1.1.4", + "is-shared-array-buffer": "^1.0.2", + "is-string": "^1.0.7", + "is-typed-array": "^1.1.12", + "is-weakref": "^1.0.2", + "object-inspect": "^1.13.1", + "object-keys": "^1.1.1", + "object.assign": "^4.1.4", + "regexp.prototype.flags": "^1.5.1", + "safe-array-concat": "^1.0.1", + "safe-regex-test": "^1.0.0", + "string.prototype.trim": "^1.2.8", + "string.prototype.trimend": "^1.0.7", + "string.prototype.trimstart": "^1.0.7", + "typed-array-buffer": "^1.0.0", + "typed-array-byte-length": "^1.0.0", + "typed-array-byte-offset": "^1.0.0", + "typed-array-length": "^1.0.4", + "unbox-primitive": "^1.0.2", + "which-typed-array": "^1.1.13" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/es-set-tostringtag": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/es-set-tostringtag/-/es-set-tostringtag-2.0.2.tgz", + "integrity": "sha512-BuDyupZt65P9D2D2vA/zqcI3G5xRsklm5N3xCwuiy+/vKy8i0ifdsQP1sLgO4tZDSCaQUSnmC48khknGMV3D2Q==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2", + "has-tostringtag": "^1.0.0", + "hasown": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/es-shim-unscopables": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/es-shim-unscopables/-/es-shim-unscopables-1.0.2.tgz", + "integrity": "sha512-J3yBRXCzDu4ULnQwxyToo/OjdMx6akgVC7K6few0a7F/0wLtmKKN7I73AH5T2836UuXRqN7Qg+IIUw/+YJksRw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + } + }, + "node_modules/es-to-primitive": { + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.1.tgz", + "integrity": "sha512-QCOllgZJtaUo9miYBcLChTUaHNjJF3PYs1VidD7AwiEj1kYxKeQTctLAezAOH5ZKRH0g2IgPn6KwB4IT8iRpvA==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -989,6 +1277,160 @@ "eslint": ">=7.0.0" } }, + "node_modules/eslint-import-resolver-node": { + "version": "0.3.9", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.9.tgz", + "integrity": "sha512-WFj2isz22JahUv+B788TlO3N6zL3nNJGU8CcZbPZvVEkBPaJdCV4vy5wyghty5ROFbCRnm132v8BScu5/1BQ8g==", + "dev": true, + "dependencies": { + "debug": "^3.2.7", + "is-core-module": "^2.13.0", + "resolve": "^1.22.4" + } + }, + "node_modules/eslint-import-resolver-node/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-import-resolver-typescript": { + "version": "3.6.1", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-typescript/-/eslint-import-resolver-typescript-3.6.1.tgz", + "integrity": "sha512-xgdptdoi5W3niYeuQxKmzVDTATvLYqhpwmykwsh7f6HIOStGWEIL9iqZgQDF9u9OEzrRwR8no5q2VT+bjAujTg==", + "dev": true, + "dependencies": { + "debug": "^4.3.4", + "enhanced-resolve": "^5.12.0", + "eslint-module-utils": "^2.7.4", + "fast-glob": "^3.3.1", + "get-tsconfig": "^4.5.0", + "is-core-module": "^2.11.0", + "is-glob": "^4.0.3" + }, + "engines": { + "node": "^14.18.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/unts/projects/eslint-import-resolver-ts" + }, + "peerDependencies": { + "eslint": "*", + "eslint-plugin-import": "*" + } + }, + "node_modules/eslint-module-utils": { + "version": "2.8.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.8.0.tgz", + "integrity": "sha512-aWajIYfsqCKRDgUfjEXNN/JlrzauMuSEy5sbd7WXbtW3EH6A6MpwEh42c7qD+MqQo9QMJ6fWLAeIJynx0g6OAw==", + "dev": true, + "dependencies": { + "debug": "^3.2.7" + }, + "engines": { + "node": ">=4" + }, + "peerDependenciesMeta": { + "eslint": { + "optional": true + } + } + }, + "node_modules/eslint-module-utils/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import": { + "version": "2.29.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.29.1.tgz", + "integrity": "sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==", + "dev": true, + "dependencies": { + "array-includes": "^3.1.7", + "array.prototype.findlastindex": "^1.2.3", + "array.prototype.flat": "^1.3.2", + "array.prototype.flatmap": "^1.3.2", + "debug": "^3.2.7", + "doctrine": "^2.1.0", + "eslint-import-resolver-node": "^0.3.9", + "eslint-module-utils": "^2.8.0", + "hasown": "^2.0.0", + "is-core-module": "^2.13.1", + "is-glob": "^4.0.3", + "minimatch": "^3.1.2", + "object.fromentries": "^2.0.7", + "object.groupby": "^1.0.1", + "object.values": "^1.1.7", + "semver": "^6.3.1", + "tsconfig-paths": "^3.15.0" + }, + "engines": { + "node": ">=4" + }, + "peerDependencies": { + "eslint": "^2 || ^3 || ^4 || ^5 || ^6 || ^7.2.0 || ^8" + } + }, + "node_modules/eslint-plugin-import/node_modules/brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "dependencies": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/debug": { + "version": "3.2.7", + "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", + "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", + "dev": true, + "dependencies": { + "ms": "^2.1.1" + } + }, + "node_modules/eslint-plugin-import/node_modules/doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "dependencies": { + "esutils": "^2.0.2" + }, + "engines": { + "node": ">=0.10.0" + } + }, + "node_modules/eslint-plugin-import/node_modules/minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "dependencies": { + "brace-expansion": "^1.1.7" + }, + "engines": { + "node": "*" + } + }, + "node_modules/eslint-plugin-import/node_modules/semver": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.1.tgz", + "integrity": "sha512-BR7VvDCVHO+q2xBEWskxS6DJE1qRnb7DxzUrogb71CWoSficBxYsiAGd+Kl0mmq/MprG9yArRkyrQxTO6XjMzA==", + "dev": true, + "bin": { + "semver": "bin/semver.js" + } + }, "node_modules/eslint-scope": { "version": "5.1.1", "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-5.1.1.tgz", @@ -1275,6 +1717,15 @@ "integrity": "sha512-36yxDn5H7OFZQla0/jFJmbIKTdZAQHngCedGxiMmpNfEZM0sdEeT+WczLQrjK6D7o2aiyLYDnkw0R3JK0Qv1RQ==", "dev": true }, + "node_modules/for-each": { + "version": "0.3.3", + "resolved": "https://registry.npmjs.org/for-each/-/for-each-0.3.3.tgz", + "integrity": "sha512-jqYfLp7mo9vIyQf8ykW2v7A+2N4QjeCeI5+Dz9XraiO1ign81wjiH7Fb9vSOWvQfNtmSa4H2RoQTrrXivdUZmw==", + "dev": true, + "dependencies": { + "is-callable": "^1.1.3" + } + }, "node_modules/formdata-polyfill": { "version": "4.0.10", "resolved": "https://registry.npmjs.org/formdata-polyfill/-/formdata-polyfill-4.0.10.tgz", @@ -1292,6 +1743,85 @@ "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", "dev": true }, + "node_modules/function-bind": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", + "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/function.prototype.name": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/function.prototype.name/-/function.prototype.name-1.1.6.tgz", + "integrity": "sha512-Z5kx79swU5P27WEayXM1tBi5Ze/lbIyiNgU3qyXUOf9b2rgXYyF9Dy9Cx+IQv/Lc8WCG6L82zwUPpSS9hGehIg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "functions-have-names": "^1.2.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/functions-have-names": { + "version": "1.2.3", + "resolved": "https://registry.npmjs.org/functions-have-names/-/functions-have-names-1.2.3.tgz", + "integrity": "sha512-xckBUXyTIqT97tq2x2AMb+g163b5JFysYk0x4qxNFwbfQkmNZoiRHb6sPzI9/QV33WeuvVYBUIiD4NzNIyqaRQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-intrinsic": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.2.tgz", + "integrity": "sha512-0gSo4ml/0j98Y3lngkFEot/zhiCeWsbYIlZ+uZOVgzLyLaUw7wxUL+nCTP0XJvJg1AXulJRI3UJi8GsbDuxdGA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2", + "has-proto": "^1.0.1", + "has-symbols": "^1.0.3", + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-symbol-description": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", + "integrity": "sha512-2EmdH1YvIQiZpltCNgkuiUnyukzxM/R6NDJX31Ke3BG1Nq5b0S2PhX59UKi9vZpPDQVdqn+1IcaAwnzTT5vCjw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/get-tsconfig": { + "version": "4.7.2", + "resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.7.2.tgz", + "integrity": "sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==", + "dev": true, + "dependencies": { + "resolve-pkg-maps": "^1.0.0" + }, + "funding": { + "url": "https://github.com/privatenumber/get-tsconfig?sponsor=1" + } + }, "node_modules/glob": { "version": "7.2.3", "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", @@ -1361,6 +1891,21 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/globalthis": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/globalthis/-/globalthis-1.0.3.tgz", + "integrity": "sha512-sFdI5LyBiNTHjRd7cGPWapiHWMOXKyuBNX/cWJ3NfzrZQVa8GI/8cofCl74AOVqq9W5kNmguTIzJ/1s2gyI9wA==", + "dev": true, + "dependencies": { + "define-properties": "^1.1.3" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/globby": { "version": "11.1.0", "resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz", @@ -1381,12 +1926,39 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/gopd": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", + "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.1.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/graceful-fs": { + "version": "4.2.11", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.11.tgz", + "integrity": "sha512-RbJ5/jmFcNNCcDV5o9eTnBLJ/HszWV0P73bc+Ff4nS/rJj+YaS6IGyiOL0VoBYX+l1Wrl3k63h/KrH+nhJ0XvQ==", + "dev": true + }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", "integrity": "sha512-EtKwoO6kxCL9WO5xipiHTZlSzBm7WLT627TqC/uVRd0HKmq8NXyebnNYxDoBi7wt8eTWrUrKXCOVaFq9x1kgag==", "dev": true }, + "node_modules/has-bigints": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/has-bigints/-/has-bigints-1.0.2.tgz", + "integrity": "sha512-tSvCKtBr9lkF0Ex0aQiP9N+OpV4zi2r/Nee5VkRDbaqv35RLYMzbwQfFSZZH0kR+Rd6302UJZ2p/bJCEoR3VoQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/has-flag": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", @@ -1396,6 +1968,69 @@ "node": ">=8" } }, + "node_modules/has-property-descriptors": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.1.tgz", + "integrity": "sha512-VsX8eaIewvas0xnvinAe9bw4WfIeODpGYikiWYLH+dma0Jw6KHYqWiWfhQlgOVK8D6PvjubK5Uc4P0iIhIcNVg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-proto": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.1.tgz", + "integrity": "sha512-7qE+iP+O+bgF9clE5+UoBFzE65mlBiVj3tKCrlNQ0Ogwm0BjpT/gK4SlLYDMybDh5I3TCTKnPPa0oMG7JDYrhg==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-symbols": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", + "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/has-tostringtag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-tostringtag/-/has-tostringtag-1.0.0.tgz", + "integrity": "sha512-kFjcSNhnlGV1kyoGk7OXKSawH5JOb/LzUc5w9B02hOTO0dfFRjbHQKvg1d6cf3HbeUmtU9VbbV3qzZ2Teh97WQ==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/hasown": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.0.tgz", + "integrity": "sha512-vUptKVTpIJhcczKBbgnS+RtcuYMB8+oNzPK2/Hp3hanz8JmpATdmmgLgSaadVREkDm+e2giHwY3ZRkyjSIDDFA==", + "dev": true, + "dependencies": { + "function-bind": "^1.1.2" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/ignore": { "version": "5.3.0", "resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.0.tgz", @@ -1446,6 +2081,101 @@ "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", "dev": true }, + "node_modules/internal-slot": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/internal-slot/-/internal-slot-1.0.6.tgz", + "integrity": "sha512-Xj6dv+PsbtwyPpEflsejS+oIZxmMlV44zAhG479uYu89MsjcYOhCFnNyKrkJrihbsiasQyY0afoCl/9BLR65bg==", + "dev": true, + "dependencies": { + "get-intrinsic": "^1.2.2", + "hasown": "^2.0.0", + "side-channel": "^1.0.4" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/is-array-buffer": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/is-array-buffer/-/is-array-buffer-3.0.2.tgz", + "integrity": "sha512-y+FyyR/w8vfIRq4eQcM1EYgSTnmHXPqaF+IgzgraytCFq5Xh8lllDVmAZolPJiZttZLeFSINPYMaEJ7/vWUa1w==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.0", + "is-typed-array": "^1.1.10" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-bigint": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-bigint/-/is-bigint-1.0.4.tgz", + "integrity": "sha512-zB9CruMamjym81i2JZ3UMn54PKGsQzsJeo6xvN3HJJ4CAsQNB6iRutp2To77OfCNuoxspsIhzaPoO1zyCEhFOg==", + "dev": true, + "dependencies": { + "has-bigints": "^1.0.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-boolean-object": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/is-boolean-object/-/is-boolean-object-1.1.2.tgz", + "integrity": "sha512-gDYaKHJmnj4aWxyj6YHyXVpdQawtVLHU5cb+eztPGczf6cjuTdwve5ZIEfgXqH4e57An1D1AKf8CZ3kYrQRqYA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-callable": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.2.7.tgz", + "integrity": "sha512-1BC0BVFhS/p0qtw6enp8e+8OD0UrK0oFLztSjNzhcKA3WDuJxxAPXzPuPtKkjEY9UUoEWlX/8fgKeu2S8i9JTA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-core-module": { + "version": "2.13.1", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.13.1.tgz", + "integrity": "sha512-hHrIjvZsftOsvKSn2TRYl63zvxsgE0K+0mYMoH6gD4omR5IWB2KynivBQczo3+wF1cCkjzvptnI9Q0sPU66ilw==", + "dev": true, + "dependencies": { + "hasown": "^2.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-date-object": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.5.tgz", + "integrity": "sha512-9YQaSxsAiSwcvS33MBk3wTCVnWK+HhF8VZR2jRxehM16QcVOdHqPn4VPHmRK4lSr38n9JriurInLcP90xsYNfQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-extglob": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", @@ -1467,6 +2197,18 @@ "node": ">=0.10.0" } }, + "node_modules/is-negative-zero": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/is-negative-zero/-/is-negative-zero-2.0.2.tgz", + "integrity": "sha512-dqJvarLawXsFbNDeJW7zAz8ItJ9cd28YufuuFzh0G8pNHjJMnY08Dv7sYX2uF5UpQOwieAeOExEYAWWfu7ZZUA==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-number": { "version": "7.0.0", "resolved": "https://registry.npmjs.org/is-number/-/is-number-7.0.0.tgz", @@ -1476,6 +2218,21 @@ "node": ">=0.12.0" } }, + "node_modules/is-number-object": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-number-object/-/is-number-object-1.0.7.tgz", + "integrity": "sha512-k1U0IRzLMo7ZlYIfzRu23Oh6MiIFasgpb9X76eqfFZAqwH44UI4KTBvBYIZ1dSL9ZzChTB9ShHfLkR4pdW5krQ==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/is-path-inside": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz", @@ -1485,6 +2242,97 @@ "node": ">=8" } }, + "node_modules/is-regex": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.1.4.tgz", + "integrity": "sha512-kvRdxDsxZjhzUX07ZnLydzS1TU/TJlTUHHY4YLL87e37oUA49DfkLqgy+VjFocowy29cKvcSiu+kIv728jTTVg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-shared-array-buffer": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-shared-array-buffer/-/is-shared-array-buffer-1.0.2.tgz", + "integrity": "sha512-sqN2UDu1/0y6uvXyStCOzyhAjCSlHceFoMKJW8W9EU9cvic/QdsZ0kEU93HEy3IUEFZIiH/3w+AH/UQbPHNdhA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-string": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/is-string/-/is-string-1.0.7.tgz", + "integrity": "sha512-tE2UXzivje6ofPW7l23cjDOMa09gb7xlAqG6jG5ej6uPV32TlWP3NKPigtaGeHNu9fohccRYvIiZMfOOnOYUtg==", + "dev": true, + "dependencies": { + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-symbol": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.4.tgz", + "integrity": "sha512-C/CPBqKWnvdcxqIARxyOh4v1UUEOCHpgDa0WYgpKDFMszcrPcffg5uhwSgPCLD2WWxmq6isisz87tzT01tuGhg==", + "dev": true, + "dependencies": { + "has-symbols": "^1.0.2" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-typed-array": { + "version": "1.1.12", + "resolved": "https://registry.npmjs.org/is-typed-array/-/is-typed-array-1.1.12.tgz", + "integrity": "sha512-Z14TF2JNG8Lss5/HMqt0//T9JeHXttXy5pH/DBU4vi98ozO2btxzq9MwYDZYnKwU8nRsz/+GVFVRDq3DkVuSPg==", + "dev": true, + "dependencies": { + "which-typed-array": "^1.1.11" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/is-weakref": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-weakref/-/is-weakref-1.0.2.tgz", + "integrity": "sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/isarray": { + "version": "2.0.5", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-2.0.5.tgz", + "integrity": "sha512-xHjhDr3cNBK0BzdUJSPXZntQUx/mwMS5Rw4A7lPJ90XGAO6ISP/ePDNuo0vhqOZU+UD5JoodwCAAoZQd3FeAKw==", + "dev": true + }, "node_modules/isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -1526,6 +2374,18 @@ "integrity": "sha512-Bdboy+l7tA3OGW6FjyFHWkP5LuByj1Tk33Ljyq0axyzdk9//JSi2u3fP1QSmd1KNwq6VOKYGlAu87CisVir6Pw==", "dev": true }, + "node_modules/json5": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/json5/-/json5-1.0.2.tgz", + "integrity": "sha512-g1MWMLBiz8FKi1e4w0UyVL3w+iJceWAFBAaBnnGKOpNa5f8TLktkbre1+s6oICydWAm+HRUGTmI+//xv2hvXYA==", + "dev": true, + "dependencies": { + "minimist": "^1.2.0" + }, + "bin": { + "json5": "lib/cli.js" + } + }, "node_modules/keyv": { "version": "4.5.4", "resolved": "https://registry.npmjs.org/keyv/-/keyv-4.5.4.tgz", @@ -1637,6 +2497,15 @@ "url": "https://github.com/sponsors/isaacs" } }, + "node_modules/minimist": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", + "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -1692,6 +2561,88 @@ "node": ">= 6" } }, + "node_modules/object-inspect": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.1.tgz", + "integrity": "sha512-5qoj1RUiKOMsCCNLV1CBiPYE10sziTsnmNxkAI/rZhiD63CF7IqdFGC/XzjWjpSgLf0LxXX3bDFIh0E18f6UhQ==", + "dev": true, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/object.assign": { + "version": "4.1.5", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.5.tgz", + "integrity": "sha512-byy+U7gp+FVwmyzKPYhW2h5l3crpmGsxl7X2s8y43IgxvG4g3QZ6CffDtsNQy1WsmZpQbO+ybo0AlW7TY6DcBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "define-properties": "^1.2.1", + "has-symbols": "^1.0.3", + "object-keys": "^1.1.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.fromentries": { + "version": "2.0.7", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.7.tgz", + "integrity": "sha512-UPbPHML6sL8PI/mOqPwsH4G6iyXcCGzLin8KvEPenOZN5lpCNBZZQ+V62vdjB1mQHrmqGQt5/OJzemUA+KJmEA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/object.groupby": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object.groupby/-/object.groupby-1.0.1.tgz", + "integrity": "sha512-HqaQtqLnp/8Bn4GL16cj+CUYbnpe1bh0TtEaWvybszDG4tgxCJuRpV8VGuvNaI1fAnI4lUJzDG55MXcOH4JZcQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1", + "get-intrinsic": "^1.2.1" + } + }, + "node_modules/object.values": { + "version": "1.1.7", + "resolved": "https://registry.npmjs.org/object.values/-/object.values-1.1.7.tgz", + "integrity": "sha512-aU6xnDFYT3x17e/f0IiiwlGPTy2jzMySGfUB4fq6z7CV8l85CWHDk5ErhyhpfDHhrOMwGFhSQkhMGHaIotA6Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/once": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", @@ -1787,6 +2738,12 @@ "node": ">=8" } }, + "node_modules/path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, "node_modules/path-type": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz", @@ -1832,6 +2789,18 @@ "url": "https://github.com/prettier/prettier?sponsor=1" } }, + "node_modules/prettier-plugin-sort-imports": { + "version": "1.8.3", + "resolved": "https://registry.npmjs.org/prettier-plugin-sort-imports/-/prettier-plugin-sort-imports-1.8.3.tgz", + "integrity": "sha512-0PiQ8Y7PH7EfWi8U0wnrOOd5N2SWjWRwGyivxvz78IDHFSARSkuqtDkNwOLRJNNTtffSVpLBXsHKCgzRQQjrBQ==", + "dev": true, + "dependencies": { + "prettier": "^3.1.1" + }, + "peerDependencies": { + "typescript": ">4.0.0" + } + }, "node_modules/punycode": { "version": "2.3.1", "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.3.1.tgz", @@ -1872,6 +2841,40 @@ "node": ">=0.10.0" } }, + "node_modules/regexp.prototype.flags": { + "version": "1.5.1", + "resolved": "https://registry.npmjs.org/regexp.prototype.flags/-/regexp.prototype.flags-1.5.1.tgz", + "integrity": "sha512-sy6TXMN+hnP/wMy+ISxg3krXx7BAtWVO4UouuCN/ziM9UEne0euamVNafDfvC83bRNr95y0V5iijeDQFUNpvrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "set-function-name": "^2.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/resolve": { + "version": "1.22.8", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.8.tgz", + "integrity": "sha512-oKWePCxqpd6FlLvGV1VU0x7bkPmmCNolxzjMf4NczoDnQcIWrAF+cPtZn5i6n+RfD2d9i0tzpKnG6Yk168yIyw==", + "dev": true, + "dependencies": { + "is-core-module": "^2.13.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + }, + "bin": { + "resolve": "bin/resolve" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/resolve-from": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", @@ -1881,6 +2884,15 @@ "node": ">=4" } }, + "node_modules/resolve-pkg-maps": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/resolve-pkg-maps/-/resolve-pkg-maps-1.0.0.tgz", + "integrity": "sha512-seS2Tj26TBVOC2NIc2rOe2y2ZO7efxITtLZcGSOnHHNOQ7CkiUBfw0Iw2ck6xkIhPwLhKNLS8BO+hEpngQlqzw==", + "dev": true, + "funding": { + "url": "https://github.com/privatenumber/resolve-pkg-maps?sponsor=1" + } + }, "node_modules/reusify": { "version": "1.0.4", "resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz", @@ -1929,6 +2941,41 @@ "queue-microtask": "^1.2.2" } }, + "node_modules/safe-array-concat": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-array-concat/-/safe-array-concat-1.1.0.tgz", + "integrity": "sha512-ZdQ0Jeb9Ofti4hbt5lX3T2JcAamT9hfzYU1MNB+z/jaEbB6wfFfPIR/zEORmZqobkCCJhSjodobH6WHNmJ97dg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "has-symbols": "^1.0.3", + "isarray": "^2.0.5" + }, + "engines": { + "node": ">=0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/safe-regex-test": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/safe-regex-test/-/safe-regex-test-1.0.2.tgz", + "integrity": "sha512-83S9w6eFq12BBIJYvjMux6/dkirb8+4zJRA9cxNBVb7Wq5fJBW+Xze48WqR8pxua7bDuAaaAxtVVd4Idjp1dBQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.5", + "get-intrinsic": "^1.2.2", + "is-regex": "^1.1.4" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/semver": { "version": "7.5.4", "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", @@ -1944,6 +2991,36 @@ "node": ">=10" } }, + "node_modules/set-function-length": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.0.tgz", + "integrity": "sha512-4DBHDoyHlM1IRPGYcoxexgh67y4ueR53FKV1yyxwFMY7aCqcN/38M1+SwZ/qJQ8iLv7+ck385ot4CcisOAPT9w==", + "dev": true, + "dependencies": { + "define-data-property": "^1.1.1", + "function-bind": "^1.1.2", + "get-intrinsic": "^1.2.2", + "gopd": "^1.0.1", + "has-property-descriptors": "^1.0.1" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/set-function-name": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/set-function-name/-/set-function-name-2.0.1.tgz", + "integrity": "sha512-tMNCiqYVkXIZgc2Hnoy2IvC/f8ezc5koaRFkCjrpWzGpCd3qbZXPzVy9MAZzK1ch/X0jvSkojys3oqJN0qCmdA==", + "dev": true, + "dependencies": { + "define-data-property": "^1.0.1", + "functions-have-names": "^1.2.3", + "has-property-descriptors": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + } + }, "node_modules/shebang-command": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", @@ -1965,6 +3042,20 @@ "node": ">=8" } }, + "node_modules/side-channel": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.4.tgz", + "integrity": "sha512-q5XPytqFEIKHkGdiMIrY10mvLRvnQh42/+GoBlFW3b2LXLE2xxJpZFdm94we0BaoV3RwJyGqg5wS7epxTv0Zvw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.0", + "get-intrinsic": "^1.0.2", + "object-inspect": "^1.9.0" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/signal-exit": { "version": "4.1.0", "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", @@ -1985,6 +3076,51 @@ "node": ">=8" } }, + "node_modules/string.prototype.trim": { + "version": "1.2.8", + "resolved": "https://registry.npmjs.org/string.prototype.trim/-/string.prototype.trim-1.2.8.tgz", + "integrity": "sha512-lfjY4HcixfQXOfaqCvcBuOIapyaroTXhbkfJN3gcB1OtyupngWK4sEET9Knd0cXd28kTUqu/kHoV4HKSJdnjiQ==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimend": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimend/-/string.prototype.trimend-1.0.7.tgz", + "integrity": "sha512-Ni79DqeB72ZFq1uH/L6zJ+DKZTkOtPIHovb3YZHQViE+HDouuU4mBrLOLDn5Dde3RF8qw5qVETEjhu9locMLvA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/string.prototype.trimstart": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/string.prototype.trimstart/-/string.prototype.trimstart-1.0.7.tgz", + "integrity": "sha512-NGhtDFu3jCEm7B4Fy0DpLewdJQOZcQ0rGbwQ/+stjnrp2i+rlKeCvos9hOIeCmqwratM47OBxY7uFZzjxHXmrg==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "define-properties": "^1.2.0", + "es-abstract": "^1.22.1" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/strip-ansi": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", @@ -1997,6 +3133,15 @@ "node": ">=8" } }, + "node_modules/strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==", + "dev": true, + "engines": { + "node": ">=4" + } + }, "node_modules/strip-json-comments": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz", @@ -2021,6 +3166,27 @@ "node": ">=8" } }, + "node_modules/supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/tapable": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/tapable/-/tapable-2.2.1.tgz", + "integrity": "sha512-GNzQvQTOIP6RyTfE2Qxb8ZVlNmw0n88vp1szwWRimP02mnTsx3Wtn5qRdqY9w2XduFNUgvOwhNnQsjwCp+kqaQ==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/text-table": { "version": "0.2.0", "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", @@ -2065,6 +3231,23 @@ "typescript": ">=4.2.0" } }, + "node_modules/ts-pattern": { + "version": "5.0.6", + "resolved": "https://registry.npmjs.org/ts-pattern/-/ts-pattern-5.0.6.tgz", + "integrity": "sha512-Y+jOjihlFriWzcBjncPCf2/am+Hgz7LtsWs77pWg5vQQKLQj07oNrJryo/wK2G0ndNaoVn2ownFMeoeAuReu3Q==" + }, + "node_modules/tsconfig-paths": { + "version": "3.15.0", + "resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-3.15.0.tgz", + "integrity": "sha512-2Ac2RgzDe/cn48GvOe3M+o82pEFewD3UPbyoUHHdKasHwJKjds4fLXWf/Ux5kATBKN20oaFGu+jbElp1pos0mg==", + "dev": true, + "dependencies": { + "@types/json5": "^0.0.29", + "json5": "^1.0.2", + "minimist": "^1.2.6", + "strip-bom": "^3.0.0" + } + }, "node_modules/tslib": { "version": "2.6.2", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.6.2.tgz", @@ -2116,6 +3299,71 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/typed-array-buffer": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-buffer/-/typed-array-buffer-1.0.0.tgz", + "integrity": "sha512-Y8KTSIglk9OZEr8zywiIHG/kmQ7KWyjseXs1CbSo8vC42w7hg2HgYTxSWwP0+is7bWDc1H+Fo026CpHFwm8tkw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "get-intrinsic": "^1.2.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + } + }, + "node_modules/typed-array-byte-length": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-length/-/typed-array-byte-length-1.0.0.tgz", + "integrity": "sha512-Or/+kvLxNpeQ9DtSydonMxCx+9ZXOswtwJn17SNLvhptaXYDJvkFFP5zbfU/uLmvnBJlI4yrnXRxpdWH/M5tNA==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-byte-offset": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/typed-array-byte-offset/-/typed-array-byte-offset-1.0.0.tgz", + "integrity": "sha512-RD97prjEt9EL8YgAgpOkf3O4IF9lhJFr9g0htQkm0rchFp/Vx7LW5Q8fSXXub7BXAODyUQohRMyOc3faCPd0hg==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "has-proto": "^1.0.1", + "is-typed-array": "^1.1.10" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/typed-array-length": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/typed-array-length/-/typed-array-length-1.0.4.tgz", + "integrity": "sha512-KjZypGq+I/H7HI5HlOoGHkWUUGq+Q0TPhQurLbyrVrvnKTBgzLhIJ7j6J/XTQOi0d1RjyZ0wdas8bKs2p0x3Ng==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "for-each": "^0.3.3", + "is-typed-array": "^1.1.9" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/typescript": { "version": "5.3.3", "resolved": "https://registry.npmjs.org/typescript/-/typescript-5.3.3.tgz", @@ -2129,6 +3377,21 @@ "node": ">=14.17" } }, + "node_modules/unbox-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/unbox-primitive/-/unbox-primitive-1.0.2.tgz", + "integrity": "sha512-61pPlCD9h51VoreyJ0BReideM3MDKMKnh6+V9L08331ipq6Q8OFXZYiqP6n/tbHx4s5I9uRhcye6BrbkizkBDw==", + "dev": true, + "dependencies": { + "call-bind": "^1.0.2", + "has-bigints": "^1.0.2", + "has-symbols": "^1.0.3", + "which-boxed-primitive": "^1.0.2" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/undici-types": { "version": "5.26.5", "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", @@ -2180,6 +3443,41 @@ "node": ">= 8" } }, + "node_modules/which-boxed-primitive": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/which-boxed-primitive/-/which-boxed-primitive-1.0.2.tgz", + "integrity": "sha512-bwZdv0AKLpplFY2KZRX6TvyuN7ojjr7lwkg6ml0roIy9YeuSr7JS372qlNW18UQYzgYK9ziGcerWqZOmEn9VNg==", + "dev": true, + "dependencies": { + "is-bigint": "^1.0.1", + "is-boolean-object": "^1.1.0", + "is-number-object": "^1.0.4", + "is-string": "^1.0.5", + "is-symbol": "^1.0.3" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, + "node_modules/which-typed-array": { + "version": "1.1.13", + "resolved": "https://registry.npmjs.org/which-typed-array/-/which-typed-array-1.1.13.tgz", + "integrity": "sha512-P5Nra0qjSncduVPEAr7xhoF5guty49ArDTwzJ/yNuPIbZppyRxFQsRCWrocxIY+CnMVG+qfbU2FmDKyvSGClow==", + "dev": true, + "dependencies": { + "available-typed-arrays": "^1.0.5", + "call-bind": "^1.0.4", + "for-each": "^0.3.3", + "gopd": "^1.0.1", + "has-tostringtag": "^1.0.0" + }, + "engines": { + "node": ">= 0.4" + }, + "funding": { + "url": "https://github.com/sponsors/ljharb" + } + }, "node_modules/wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", diff --git a/package.json b/package.json index 4253b0d..b0c4b8d 100644 --- a/package.json +++ b/package.json @@ -40,18 +40,25 @@ "dependencies": { "@raycast/api": "^1.65.1", "@raycast/utils": "^1.10.1", - "node-fetch": "^3.3.2" + "dayjs": "^1.11.10", + "node-fetch": "^3.3.2", + "ts-pattern": "^5.0.6" }, "devDependencies": { "@raycast/eslint-config": "^1.0.6", "@types/node": "20.8.10", "@types/react": "18.2.27", + "@typescript-eslint/parser": "^6.19.1", "eslint": "^8.56.0", + "eslint-import-resolver-typescript": "^3.6.1", + "eslint-plugin-import": "^2.29.1", "prettier": "^3.0.3", + "prettier-plugin-sort-imports": "^1.8.3", "typescript": "^5.3.3" }, "scripts": { "build": "ray build -e dist", + "format": "prettier --write --list-different --ignore-unknown src", "dev": "ray develop", "fix-lint": "ray lint --fix", "lint": "ray lint", diff --git a/src/NotificationActions.tsx b/src/NotificationActions.tsx deleted file mode 100644 index f2c005a..0000000 --- a/src/NotificationActions.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import { Action, ActionPanel, Icon } from "@raycast/api"; -import { useMemo, ReactElement } from "react"; -import { getNotificationHtmlUrl } from "./notification"; -import { Notification } from "./types"; - -function deleteNotification(notification: Notification) { - console.log(`Deleting notification ${notification.id}`); -} - -function unsubscribeFromNotification(notification: Notification) { - console.log(`Unsubcribing from notification ${notification.id}`); -} - -function snoozeNotification(notification: Notification) { - console.log(`Snoozing notification ${notification.id}`); -} - -function createTaskFromNotification(notification: Notification) { - console.log(`Creating task notification ${notification.id}`); -} - -function linkNotificationToTask(notification: Notification) { - console.log(`Linking notification ${notification.id}`); -} - -export function NotificationActions({ - notification, - detailsTarget, -}: { - notification: Notification; - detailsTarget: ReactElement; -}) { - const notification_html_url = useMemo(() => { - return getNotificationHtmlUrl(notification); - }, [notification]); - - return ( - - - - deleteNotification(notification)} - /> - unsubscribeFromNotification(notification)} - /> - snoozeNotification(notification)} - /> - createTaskFromNotification(notification)} - /> - linkNotificationToTask(notification)} - /> - - ); -} diff --git a/src/action/CreateTaskFromNotification.tsx b/src/action/CreateTaskFromNotification.tsx new file mode 100644 index 0000000..cc9892d --- /dev/null +++ b/src/action/CreateTaskFromNotification.tsx @@ -0,0 +1,152 @@ +import { Action, useNavigation, ActionPanel, Form, Icon, getPreferenceValues, showToast, Toast } from "@raycast/api"; +import { MutatePromise, useForm, FormValidation, useFetch } from "@raycast/utils"; +import { Page, UniversalInboxPreferences } from "../types"; +import { Notification } from "../notification"; +import { TaskPriority } from "../task"; +import { handleErrors } from "../api"; +import utc from "dayjs/plugin/utc"; +import { useState } from "react"; +import fetch from "node-fetch"; +import dayjs from "dayjs"; + +dayjs.extend(utc); + +interface CreateTaskFromNotificationProps { + notification: Notification; + mutate: MutatePromise | undefined>; +} + +interface TaskCreationFormValues { + title: string; + project: string; + dueAt: Date | null; + priority: string; +} + +interface ProjectSummary { + name: string; + source_id: string; +} + +interface TaskCreation { + title: string; + project: ProjectSummary; + due_at?: { type: "DateTimeWithTz"; content: string }; + priority: TaskPriority; +} + +export function CreateTaskFromNotification({ notification, mutate }: CreateTaskFromNotificationProps) { + const preferences = getPreferenceValues(); + const { pop } = useNavigation(); + const [searchText, setSearchText] = useState(""); + + const { isLoading, data: projects } = useFetch>( + `${preferences.universalInboxBaseUrl}/api/tasks/projects/search?matches=${searchText}`, + { + keepPreviousData: true, + headers: { + Authorization: `Bearer ${preferences.apiKey}`, + }, + }, + ); + + const { handleSubmit, itemProps } = useForm({ + initialValues: { + title: notification.title, + dueAt: new Date(), + priority: `${TaskPriority.P4 as number}`, + }, + async onSubmit(values) { + const project = projects?.find((p) => p.source_id === values.project); + if (!project) { + throw new Error("Project not found"); + } + const taskCreation: TaskCreation = { + title: values.title, + project: project, + due_at: values.dueAt ? { type: "DateTimeWithTz", content: dayjs(values.dueAt).utc().format() } : undefined, + priority: parseInt(values.priority) as TaskPriority, + }; + await createTaskFromNotification(taskCreation, notification, mutate); + pop(); + }, + validation: { + title: FormValidation.Required, + project: FormValidation.Required, + priority: FormValidation.Required, + }, + }); + + return ( +
+ + + } + > + + + + {projects?.map((project) => { + return ; + })} + + + + + + + + + + ); +} + +async function createTaskFromNotification( + taskCreation: TaskCreation, + notification: Notification, + mutate: MutatePromise | undefined>, +) { + const preferences = getPreferenceValues(); + const toast = await showToast({ style: Toast.Style.Animated, title: "Creating task from notification" }); + try { + await mutate( + handleErrors( + fetch(`${preferences.universalInboxBaseUrl}/api/notifications/${notification.id}/task`, { + method: "POST", + body: JSON.stringify(taskCreation), + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${preferences.apiKey}`, + }, + }), + ), + { + optimisticUpdate(page) { + if (page) { + page.content = page.content.filter((n) => n.id !== notification.id); + } + return page; + }, + }, + ); + + toast.style = Toast.Style.Success; + toast.title = "Task successfully created"; + } catch (error) { + toast.style = Toast.Style.Failure; + toast.title = "Failed to create task from notification"; + toast.message = (error as Error).message; + throw error; + } +} diff --git a/src/action/LinkNotificationToTask.tsx b/src/action/LinkNotificationToTask.tsx new file mode 100644 index 0000000..68f1917 --- /dev/null +++ b/src/action/LinkNotificationToTask.tsx @@ -0,0 +1,109 @@ +import { Action, ActionPanel, useNavigation, Form, Icon, getPreferenceValues, showToast, Toast } from "@raycast/api"; +import { MutatePromise, useForm, FormValidation, useFetch } from "@raycast/utils"; +import { Page, UniversalInboxPreferences } from "../types"; +import { Notification } from "../notification"; +import { Task, TaskStatus } from "../task"; +import { handleErrors } from "../api"; +import { useState } from "react"; +import fetch from "node-fetch"; + +interface LinkNotificationToTaskProps { + notification: Notification; + mutate: MutatePromise | undefined>; +} + +interface TaskLinkFormValues { + taskId: string; +} + +export function LinkNotificationToTask({ notification, mutate }: LinkNotificationToTaskProps) { + const preferences = getPreferenceValues(); + const { pop } = useNavigation(); + const [searchText, setSearchText] = useState(""); + + const { isLoading, data: tasks } = useFetch>( + `${preferences.universalInboxBaseUrl}/api/tasks/search?matches=${searchText}`, + { + keepPreviousData: true, + headers: { + Authorization: `Bearer ${preferences.apiKey}`, + }, + }, + ); + + const { handleSubmit, itemProps } = useForm({ + async onSubmit(values) { + await linkNotificationToTask(notification, values.taskId, mutate); + pop(); + }, + validation: { + taskId: FormValidation.Required, + }, + }); + + return ( +
+ + + } + > + + + {tasks?.map((task) => { + return ; + })} + + + ); +} + +async function linkNotificationToTask( + notification: Notification, + taskId: string, + mutate: MutatePromise | undefined>, +) { + const preferences = getPreferenceValues(); + const toast = await showToast({ style: Toast.Style.Animated, title: "Linking notification to task" }); + try { + await mutate( + handleErrors( + fetch(`${preferences.universalInboxBaseUrl}/api/notifications/${notification.id}`, { + method: "PATCH", + body: JSON.stringify({ status: TaskStatus.Deleted, task_id: taskId }), + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${preferences.apiKey}`, + }, + }), + ), + { + optimisticUpdate(page) { + if (page) { + page.content = page.content.filter((n) => n.id !== notification.id); + } + console.log(`page(link): ${notification.id}`, page); + return page; + }, + }, + ); + + toast.style = Toast.Style.Success; + toast.title = "Notification successfully linked to task"; + } catch (error) { + toast.style = Toast.Style.Failure; + toast.title = "Failed to link notification to task"; + toast.message = (error as Error).message; + throw error; + } +} diff --git a/src/action/NotificationActions.tsx b/src/action/NotificationActions.tsx new file mode 100644 index 0000000..ab97c97 --- /dev/null +++ b/src/action/NotificationActions.tsx @@ -0,0 +1,200 @@ +import { Notification, NotificationStatus, getNotificationHtmlUrl, isNotificationBuiltFromTask } from "../notification"; +import { Action, ActionPanel, Icon, getPreferenceValues, showToast, Toast } from "@raycast/api"; +import { CreateTaskFromNotification } from "./CreateTaskFromNotification"; +import { LinkNotificationToTask } from "./LinkNotificationToTask"; +import { Page, UniversalInboxPreferences } from "../types"; +import { MutatePromise } from "@raycast/utils"; +import { useMemo, ReactElement } from "react"; +import { handleErrors } from "../api"; +import { TaskStatus } from "../task"; +import utc from "dayjs/plugin/utc"; +import fetch from "node-fetch"; +import dayjs from "dayjs"; + +dayjs.extend(utc); + +interface NotificationActionsProps { + notification: Notification; + detailsTarget: ReactElement; + mutate: MutatePromise | undefined>; +} + +export function NotificationActions({ notification, detailsTarget, mutate }: NotificationActionsProps) { + const notification_html_url = useMemo(() => { + return getNotificationHtmlUrl(notification); + }, [notification]); + + return ( + + + + deleteNotification(notification, mutate)} + /> + unsubscribeFromNotification(notification, mutate)} + /> + snoozeNotification(notification, mutate)} + /> + } + /> + } + /> + + ); +} + +async function deleteNotification(notification: Notification, mutate: MutatePromise | undefined>) { + const preferences = getPreferenceValues(); + const toast = await showToast({ style: Toast.Style.Animated, title: "Deleting notification" }); + try { + if (isNotificationBuiltFromTask(notification) && notification.task) { + await mutate( + fetch(`${preferences.universalInboxBaseUrl}/api/tasks/${notification.task.id}`, { + method: "PATCH", + body: JSON.stringify({ status: TaskStatus.Deleted }), + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${preferences.apiKey}`, + }, + }), + { + optimisticUpdate(page) { + if (page) { + page.content = page.content.filter((n) => n.id !== notification.id); + } + return page; + }, + }, + ); + } else { + await mutate( + handleErrors( + fetch(`${preferences.universalInboxBaseUrl}/api/notifications/${notification.id}`, { + method: "PATCH", + body: JSON.stringify({ status: NotificationStatus.Deleted }), + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${preferences.apiKey}`, + }, + }), + ), + { + optimisticUpdate(page) { + if (page) { + page.content = page.content.filter((n) => n.id !== notification.id); + } + return page; + }, + }, + ); + } + + toast.style = Toast.Style.Success; + toast.title = "Notification successfully deleted"; + } catch (error) { + toast.style = Toast.Style.Failure; + toast.title = "Failed to delete notification"; + toast.message = (error as Error).message; + throw error; + } +} + +async function unsubscribeFromNotification( + notification: Notification, + mutate: MutatePromise | undefined>, +) { + const preferences = getPreferenceValues(); + const toast = await showToast({ style: Toast.Style.Animated, title: "Unsubscribing from notification" }); + try { + await mutate( + handleErrors( + fetch(`${preferences.universalInboxBaseUrl}/api/notifications/${notification.id}`, { + method: "PATCH", + body: JSON.stringify({ status: NotificationStatus.Unsubscribed }), + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${preferences.apiKey}`, + }, + }), + ), + { + optimisticUpdate(page) { + if (page) { + page.content = page.content.filter((n) => n.id !== notification.id); + } + return page; + }, + }, + ); + + toast.style = Toast.Style.Success; + toast.title = "Notification successfully unsubscribed"; + } catch (error) { + toast.style = Toast.Style.Failure; + toast.title = "Failed to unsubscribe from notification"; + toast.message = (error as Error).message; + throw error; + } +} + +async function snoozeNotification(notification: Notification, mutate: MutatePromise | undefined>) { + const preferences = getPreferenceValues(); + const toast = await showToast({ style: Toast.Style.Animated, title: "Snoozing notification" }); + try { + const snoozeTime = computeSnoozedUntil(new Date(), 1, 6); + await mutate( + handleErrors( + fetch(`${preferences.universalInboxBaseUrl}/api/notifications/${notification.id}`, { + method: "PATCH", + body: JSON.stringify({ snoozed_until: snoozeTime }), + headers: { + "Content-Type": "application/json", + Authorization: `Bearer ${preferences.apiKey}`, + }, + }), + ), + { + optimisticUpdate(page) { + if (page) { + page.content = page.content.filter((n) => n.id !== notification.id); + } + return page; + }, + }, + ); + + toast.style = Toast.Style.Success; + toast.title = "Notification successfully snoozed"; + } catch (error) { + toast.style = Toast.Style.Failure; + toast.title = "Failed to snooze notification"; + toast.message = (error as Error).message; + throw error; + } +} + +function computeSnoozedUntil(fromDate: Date, daysOffset: number, resetHour: number): Date { + const result = dayjs(fromDate) + .utc() + .add(fromDate.getHours() < resetHour ? daysOffset - 1 : daysOffset, "day"); + return result.hour(resetHour).minute(0).second(0).millisecond(0).toDate(); +} diff --git a/src/NotificationTaskActions.tsx b/src/action/NotificationTaskActions.tsx similarity index 82% rename from src/NotificationTaskActions.tsx rename to src/action/NotificationTaskActions.tsx index e54ac79..a512a9d 100644 --- a/src/NotificationTaskActions.tsx +++ b/src/action/NotificationTaskActions.tsx @@ -1,7 +1,8 @@ +import { Notification, getNotificationHtmlUrl } from "../notification"; import { Action, ActionPanel, Icon } from "@raycast/api"; +import { MutatePromise } from "@raycast/utils"; import { useMemo, ReactElement } from "react"; -import { getNotificationHtmlUrl } from "./notification"; -import { Notification } from "./types"; +import { Page } from "../types"; function deleteNotification(notification: Notification) { console.log(`Deleting notification ${notification.id}`); @@ -19,21 +20,20 @@ function completeTask(notification: Notification) { console.log(`Completing task ${notification.id}`); } -export function NotificationTaskActions({ - notification, - detailsTarget, -}: { +interface NotificationTaskActionsProps { notification: Notification; detailsTarget: ReactElement; -}) { + mutate: MutatePromise | undefined>; +} +export function NotificationTaskActions({ notification, detailsTarget }: NotificationTaskActionsProps) { const notification_html_url = useMemo(() => { return getNotificationHtmlUrl(notification); }, [notification]); return ( - + ) { + return match(await response) + .with({ status: 400 }, async (r) => { + throw new Error(((await r.json()) as ResponseError).message); + }) + .with({ status: 401 }, async (r) => { + throw new Error(((await r.json()) as ResponseError).message); + }) + .with({ status: 500 }, async (r) => { + throw new Error(((await r.json()) as ResponseError).message); + }) + .otherwise((resp) => resp); +} diff --git a/src/index.tsx b/src/index.tsx index 8ae28a7..c9a14a4 100644 --- a/src/index.tsx +++ b/src/index.tsx @@ -1,20 +1,21 @@ import { Action, ActionPanel, Detail, List, getPreferenceValues, openExtensionPreferences } from "@raycast/api"; -import { useFetch } from "@raycast/utils"; -import { NotificationActions } from "./NotificationActions"; -import { GithubNotificationListItem } from "./integrations/github/GithubNotificationListItem"; import { GoogleMailNotificationListItem } from "./integrations/google-mail/GoogleMailNotificationListItem"; -import { LinearNotificationListItem } from "./integrations/linear/LinearNotificationListItem"; +import { GithubNotificationListItem } from "./integrations/github/listitem/GithubNotificationListItem"; import { TodoistNotificationListItem } from "./integrations/todoist/TodoistNotificationListItem"; -import { Notification, NotificationListItemProps, Page, UniversalInboxPreferences } from "./types"; +import { LinearNotificationListItem } from "./integrations/linear/LinearNotificationListItem"; +import { Notification, NotificationListItemProps } from "./notification"; +import { NotificationActions } from "./action/NotificationActions"; +import { Page, UniversalInboxPreferences } from "./types"; +import { useFetch } from "@raycast/utils"; export default function Command() { const preferences = getPreferenceValues(); if ( preferences.apiKey === undefined || - preferences.apiKey === "" - /* preferences.universalInboxBaseUrl === undefined || - * preferences.universalInboxBaseUrl === "" */ + preferences.apiKey === "" || + preferences.universalInboxBaseUrl === undefined || + preferences.universalInboxBaseUrl === "" ) { return ( >( + const { isLoading, data, mutate } = useFetch>( `${preferences.universalInboxBaseUrl}/api/notifications?status=Unread,Read&with_tasks=true`, { headers: { @@ -40,35 +41,39 @@ export default function Command() { return ( {data?.content.map((notification: Notification) => { - return ; + return ; })} ); } -function NotificationListItem({ notification }: NotificationListItemProps) { +function NotificationListItem({ notification, mutate }: NotificationListItemProps) { switch (notification.metadata.type) { case "Github": - return ; + return ; case "Linear": - return ; + return ; case "GoogleMail": - return ; + return ; case "Todoist": - return ; + return ; default: - return ; + return ; } } -function DefaultNotificationListItem({ notification }: NotificationListItemProps) { +function DefaultNotificationListItem({ notification, mutate }: NotificationListItemProps) { return ( } /> + } + mutate={mutate} + /> } /> ); diff --git a/src/integrations/github/misc.tsx b/src/integrations/github/accessories.ts similarity index 100% rename from src/integrations/github/misc.tsx rename to src/integrations/github/accessories.ts index 82aeb26..d600a7a 100644 --- a/src/integrations/github/misc.tsx +++ b/src/integrations/github/accessories.ts @@ -1,5 +1,5 @@ -import { Icon, Image, List } from "@raycast/api"; import { GithubActor, getGithubActorName } from "./types"; +import { Icon, Image, List } from "@raycast/api"; export function getGithubActorAccessory(actor?: GithubActor): List.Item.Accessory { if (actor) { diff --git a/src/integrations/github/listitem/GithubDiscussionNotificationListItem.tsx b/src/integrations/github/listitem/GithubDiscussionNotificationListItem.tsx index 6152e65..0ab6ed6 100644 --- a/src/integrations/github/listitem/GithubDiscussionNotificationListItem.tsx +++ b/src/integrations/github/listitem/GithubDiscussionNotificationListItem.tsx @@ -1,20 +1,24 @@ -import { Color, Icon, List } from "@raycast/api"; -import { NotificationActions } from "../../../NotificationActions"; -import { Notification } from "../../../types"; -import { getGithubActorAccessory } from "../misc"; -import { GithubDiscussion, GithubDiscussionStateReason } from "../types"; import { GithubDiscussionPreview } from "../preview/GithubDiscussionPreview"; +import { NotificationActions } from "../../../action/NotificationActions"; +import { GithubDiscussion, GithubDiscussionStateReason } from "../types"; +import { getGithubActorAccessory } from "../accessories"; +import { Notification } from "../../../notification"; +import { Color, Icon, List } from "@raycast/api"; +import { MutatePromise } from "@raycast/utils"; +import { Page } from "../../../types"; interface GithubDiscussionNotificationListItemProps { icon: string; notification: Notification; githubDiscussion: GithubDiscussion; + mutate: MutatePromise | undefined>; } export function GithubDiscussionNotificationListItem({ icon, notification, githubDiscussion, + mutate, }: GithubDiscussionNotificationListItemProps) { const subtitle = `${githubDiscussion.repository.name_with_owner}`; @@ -48,6 +52,7 @@ export function GithubDiscussionNotificationListItem({ } + mutate={mutate} /> } /> diff --git a/src/integrations/github/GithubNotificationListItem.tsx b/src/integrations/github/listitem/GithubNotificationListItem.tsx similarity index 65% rename from src/integrations/github/GithubNotificationListItem.tsx rename to src/integrations/github/listitem/GithubNotificationListItem.tsx index ea6f4f5..66ef558 100644 --- a/src/integrations/github/GithubNotificationListItem.tsx +++ b/src/integrations/github/listitem/GithubNotificationListItem.tsx @@ -1,10 +1,10 @@ +import { GithubPullRequestNotificationListItem } from "./GithubPullRequestNotificationListItem"; +import { GithubDiscussionNotificationListItem } from "./GithubDiscussionNotificationListItem"; +import { NotificationListItemProps } from "../../../notification"; import { environment } from "@raycast/api"; import { useMemo } from "react"; -import { NotificationListItemProps } from "../../types"; -import { GithubDiscussionNotificationListItem } from "./listitem/GithubDiscussionNotificationListItem"; -import { GithubPullRequestNotificationListItem } from "./listitem/GithubPullRequestNotificationListItem"; -export function GithubNotificationListItem({ notification }: NotificationListItemProps) { +export function GithubNotificationListItem({ notification, mutate }: NotificationListItemProps) { const icon = useMemo(() => { if (environment.appearance === "dark") { return "github-logo-light.svg"; @@ -19,6 +19,7 @@ export function GithubNotificationListItem({ notification }: NotificationListIte icon={icon} notification={notification} githubPullRequest={notification.details.content} + mutate={mutate} /> ); case "GithubDiscussion": @@ -27,6 +28,7 @@ export function GithubNotificationListItem({ notification }: NotificationListIte icon={icon} notification={notification} githubDiscussion={notification.details.content} + mutate={mutate} /> ); default: diff --git a/src/integrations/github/listitem/GithubPullRequestNotificationListItem.tsx b/src/integrations/github/listitem/GithubPullRequestNotificationListItem.tsx index adc35a9..47c0f1c 100644 --- a/src/integrations/github/listitem/GithubPullRequestNotificationListItem.tsx +++ b/src/integrations/github/listitem/GithubPullRequestNotificationListItem.tsx @@ -1,7 +1,3 @@ -import { Color, Icon, List } from "@raycast/api"; -import { NotificationActions } from "../../../NotificationActions"; -import { Notification } from "../../../types"; -import { GithubPullRequestPreview } from "../preview/GithubPullRequestPreview"; import { GithubPullRequestState, GithubPullRequestReviewDecision, @@ -11,18 +7,26 @@ import { GithubCheckStatusState, GithubCheckSuite, } from "../types"; -import { getGithubActorAccessory } from "../misc"; +import { GithubPullRequestPreview } from "../preview/GithubPullRequestPreview"; +import { NotificationActions } from "../../../action/NotificationActions"; +import { getGithubActorAccessory } from "../accessories"; +import { Notification } from "../../../notification"; +import { Color, Icon, List } from "@raycast/api"; +import { MutatePromise } from "@raycast/utils"; +import { Page } from "../../../types"; interface GithubPullRequestNotificationListItemProps { icon: string; notification: Notification; githubPullRequest: GithubPullRequest; + mutate: MutatePromise | undefined>; } export function GithubPullRequestNotificationListItem({ icon, notification, githubPullRequest, + mutate, }: GithubPullRequestNotificationListItemProps) { const subtitle = `${githubPullRequest.head_repository?.name_with_owner} #${githubPullRequest.number}`; @@ -67,6 +71,7 @@ export function GithubPullRequestNotificationListItem({ } + mutate={mutate} /> } /> diff --git a/src/integrations/github/preview/GithubDiscussionPreview.tsx b/src/integrations/github/preview/GithubDiscussionPreview.tsx index 6943052..cf4b7c6 100644 --- a/src/integrations/github/preview/GithubDiscussionPreview.tsx +++ b/src/integrations/github/preview/GithubDiscussionPreview.tsx @@ -1,8 +1,7 @@ +import { Notification, getNotificationHtmlUrl } from "../../../notification"; import { Detail, ActionPanel, Action } from "@raycast/api"; -import { Notification } from "../../../types"; import { GithubDiscussion } from "../types"; import { useMemo } from "react"; -import { getNotificationHtmlUrl } from "../../../notification"; interface GithubDiscussionPreviewProps { notification: Notification; diff --git a/src/integrations/github/preview/GithubPullRequestPreview.tsx b/src/integrations/github/preview/GithubPullRequestPreview.tsx index faa5406..8c332ae 100644 --- a/src/integrations/github/preview/GithubPullRequestPreview.tsx +++ b/src/integrations/github/preview/GithubPullRequestPreview.tsx @@ -1,8 +1,7 @@ +import { Notification, getNotificationHtmlUrl } from "../../../notification"; import { Detail, ActionPanel, Action } from "@raycast/api"; -import { Notification } from "../../../types"; import { GithubPullRequest } from "../types"; import { useMemo } from "react"; -import { getNotificationHtmlUrl } from "../../../notification"; interface GithubPullRequestPreviewProps { notification: Notification; diff --git a/src/integrations/google-mail/GoogleMailNotificationListItem.tsx b/src/integrations/google-mail/GoogleMailNotificationListItem.tsx index 3cc25e0..d039c1b 100644 --- a/src/integrations/google-mail/GoogleMailNotificationListItem.tsx +++ b/src/integrations/google-mail/GoogleMailNotificationListItem.tsx @@ -1,9 +1,9 @@ +import { NotificationActions } from "../../action/NotificationActions"; +import { NotificationListItemProps } from "../../notification"; import { Detail, List, environment } from "@raycast/api"; import { useMemo } from "react"; -import { NotificationActions } from "../../NotificationActions"; -import { NotificationListItemProps } from "../../types"; -export function GoogleMailNotificationListItem({ notification }: NotificationListItemProps) { +export function GoogleMailNotificationListItem({ notification, mutate }: NotificationListItemProps) { const icon = useMemo(() => { if (environment.appearance === "dark") { return "google-mail-logo-light.svg"; @@ -18,7 +18,11 @@ export function GoogleMailNotificationListItem({ notification }: NotificationLis icon={icon} subtitle={`#${notification.source_id}`} actions={ - } /> + } + mutate={mutate} + /> } /> ); diff --git a/src/integrations/linear/LinearNotificationListItem.tsx b/src/integrations/linear/LinearNotificationListItem.tsx index 0a8840f..1ce4cd0 100644 --- a/src/integrations/linear/LinearNotificationListItem.tsx +++ b/src/integrations/linear/LinearNotificationListItem.tsx @@ -1,9 +1,9 @@ +import { NotificationActions } from "../../action/NotificationActions"; +import { NotificationListItemProps } from "../../notification"; import { Detail, List, environment } from "@raycast/api"; import { useMemo } from "react"; -import { NotificationActions } from "../../NotificationActions"; -import { NotificationListItemProps } from "../../types"; -export function LinearNotificationListItem({ notification }: NotificationListItemProps) { +export function LinearNotificationListItem({ notification, mutate }: NotificationListItemProps) { const icon = useMemo(() => { if (environment.appearance === "dark") { return "linear-logo-light.svg"; @@ -18,7 +18,11 @@ export function LinearNotificationListItem({ notification }: NotificationListIte icon={icon} subtitle={`#${notification.source_id}`} actions={ - } /> + } + mutate={mutate} + /> } /> ); diff --git a/src/integrations/todoist/TodoistNotificationListItem.tsx b/src/integrations/todoist/TodoistNotificationListItem.tsx index 29925d8..c8a2840 100644 --- a/src/integrations/todoist/TodoistNotificationListItem.tsx +++ b/src/integrations/todoist/TodoistNotificationListItem.tsx @@ -1,9 +1,9 @@ +import { NotificationTaskActions } from "../../action/NotificationTaskActions"; +import { NotificationListItemProps } from "../../notification"; import { Detail, List, environment } from "@raycast/api"; import { useMemo } from "react"; -import { NotificationTaskActions } from "../../NotificationTaskActions"; -import { NotificationListItemProps } from "../../types"; -export function TodoistNotificationListItem({ notification }: NotificationListItemProps) { +export function TodoistNotificationListItem({ notification, mutate }: NotificationListItemProps) { const icon = useMemo(() => { if (environment.appearance === "dark") { return "todoist-icon-light.svg"; @@ -21,6 +21,7 @@ export function TodoistNotificationListItem({ notification }: NotificationListIt } + mutate={mutate} /> } /> diff --git a/src/notification.ts b/src/notification.ts index 77aa284..281bc61 100644 --- a/src/notification.ts +++ b/src/notification.ts @@ -1,4 +1,43 @@ -import { Notification } from "./types"; +import { GithubDiscussion, GithubPullRequest } from "./integrations/github/types"; +import { MutatePromise } from "@raycast/utils"; +import { Page } from "./types"; +import { Task } from "./task"; + +export interface Notification { + id: string; + title: string; + source_id: string; + status: NotificationStatus; + metadata: NotificationMetadata; + updated_at: Date; + last_read_at?: Date; + snoozed_until?: Date; + user_id: string; + task?: Task; + details?: NotificationDetails; +} + +export type NotificationMetadata = { + type: "Github" | "Linear" | "GoogleMail" | "Todoist"; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + content: any; +}; + +export type NotificationDetails = + | { type: "GithubPullRequest"; content: GithubPullRequest } + | { type: "GithubDiscussion"; content: GithubDiscussion }; + +export enum NotificationStatus { + Unread = "Unread", + Read = "Read", + Deleted = "Deleted", + Unsubscribed = "Unsubscribed", +} + +export type NotificationListItemProps = { + notification: Notification; + mutate: MutatePromise | undefined>; +}; export function getNotificationHtmlUrl(notification: Notification) { switch (notification.details?.type) { @@ -12,3 +51,7 @@ export function getNotificationHtmlUrl(notification: Notification) { } } } + +export function isNotificationBuiltFromTask(notification: Notification) { + return notification.metadata.type === "Todoist"; +} diff --git a/src/task.ts b/src/task.ts new file mode 100644 index 0000000..62a88f6 --- /dev/null +++ b/src/task.ts @@ -0,0 +1,41 @@ +export interface Task { + id: string; + source_id: string; + title: string; + body: string; + status: TaskStatus; + completed_at?: Date; + priority: TaskPriority; + due_at?: DueDate; + tags: Array; + parent_id?: string; + project: string; + is_recurring: boolean; + created_at: Date; + metadata: TaskMetadata; + user_id: string; +} + +export type TaskMetadata = { + type: "Todoist"; + // eslint-disable-next-line @typescript-eslint/no-explicit-any + content: any; +}; + +export enum TaskStatus { + Active = "Active", + Done = "Done", + Deleted = "Deleted", +} + +export enum TaskPriority { + P1 = 1, + P2 = 2, + P3 = 3, + P4 = 4, +} + +export type DueDate = + | { type: "Date"; content: Date } + | { type: "DateTime"; content: Date } + | { type: "DateTimeWithTz"; content: Date }; diff --git a/src/types.ts b/src/types.ts index b155fe1..e16d288 100644 --- a/src/types.ts +++ b/src/types.ts @@ -1,5 +1,3 @@ -import { GithubDiscussion, GithubPullRequest } from "./integrations/github/types"; - export interface UniversalInboxPreferences { apiKey: string; universalInboxBaseUrl: string; @@ -11,38 +9,3 @@ export interface Page { total: number; content: Array; } - -export interface Notification { - id: string; - title: string; - source_id: string; - status: NotificationStatus; - metadata: NotificationMetadata; - updated_at: Date; - last_read_at?: Date; - snoozed_until?: Date; - user_id: string; - task_id?: string; - details?: NotificationDetails; -} - -export type NotificationMetadata = { - type: "Github" | "Linear" | "GoogleMail" | "Todoist"; - // eslint-disable-next-line @typescript-eslint/no-explicit-any - content: any; -}; - -export type NotificationDetails = - | { type: "GithubPullRequest"; content: GithubPullRequest } - | { type: "GithubDiscussion"; content: GithubDiscussion }; - -export enum NotificationStatus { - Unread = "Unread", - Read = "Read", - Deleted = "Deleted", - Unsubscribed = "Unsubscribed", -} - -export type NotificationListItemProps = { - notification: Notification; -};