From f0e3b4588a1952d33532b4892552585ed535b40a Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 23 Jan 2023 21:19:41 +0000 Subject: [PATCH 01/13] Bump knex from 0.21.12 to 2.4.2 Bumps [knex](https://github.com/knex/knex) from 0.21.12 to 2.4.2. - [Release notes](https://github.com/knex/knex/releases) - [Changelog](https://github.com/knex/knex/blob/master/CHANGELOG.md) - [Commits](https://github.com/knex/knex/commits) --- updated-dependencies: - dependency-name: knex dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- packages/api/package.json | 2 +- yarn.lock | 121 +++++++++++++------------------------- 2 files changed, 42 insertions(+), 81 deletions(-) diff --git a/packages/api/package.json b/packages/api/package.json index 76906a6f1..03012c71e 100644 --- a/packages/api/package.json +++ b/packages/api/package.json @@ -68,7 +68,7 @@ "intercom-client": "^3.1.4", "jsonwebtoken": "^8.5.1", "jwks-rsa": "^2.0.3", - "knex": "0.21.12", + "knex": "2.4.2", "knex-stringcase": "^1.4.2", "linkedom": "^0.14.9", "luxon": "^3.2.1", diff --git a/yarn.lock b/yarn.lock index 67aaf0621..8298ecfe6 100644 --- a/yarn.lock +++ b/yarn.lock @@ -11740,26 +11740,16 @@ color@3.0.x: color-convert "^1.9.1" color-string "^1.5.2" -colorette@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.2.1.tgz#4d0b921325c14faf92633086a536db6e89564b1b" - integrity sha512-puCDz0CzydiSYOrnXpz/PKd69zRrribezjtE9yd4zvytoRc8+RY/KJPvtPFKZS3E3wP6neGyMe0vOTlHO5L3Pw== +colorette@2.0.19, colorette@^2.0.10, colorette@^2.0.14, colorette@^2.0.16: + version "2.0.19" + resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.19.tgz#cdf044f47ad41a0f4b56b3a0d5b4e6e1a2d5a798" + integrity sha512-3tlv/dIP7FWvj3BsbHrGLJ6l/oKh1O3TcgBqMn+yyCagOxc23fyzDS6HypQbgxWbkpDnf52p1LuR4eWDQ/K9WQ== -colorette@^1.2.2: +colorette@^1.2.2, colorette@^1.3.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.4.0.tgz#5190fbb87276259a86ad700bff2c6d6faa3fca40" integrity sha512-Y2oEozpomLn7Q3HFP7dpww7AtMJplbM9lGZP6RDfHqmbeRjiwRg4n6VM6j4KLmRke85uWEI7JqF17f3pqdRA0g== -colorette@^1.3.0: - version "1.3.0" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-1.3.0.tgz#ff45d2f0edb244069d3b772adeb04fed38d0a0af" - integrity sha512-ecORCqbSFP7Wm8Y6lyqMJjexBQqXSF7SSeaTyGGphogUjBlFP9m9o08wy86HL2uB7fMTxtOUzLMk7ogKcxMg1w== - -colorette@^2.0.10, colorette@^2.0.14, colorette@^2.0.16: - version "2.0.16" - resolved "https://registry.yarnpkg.com/colorette/-/colorette-2.0.16.tgz#713b9af84fdb000139f04546bd4a93f62a5085da" - integrity sha512-hUewv7oMjCp+wkBv5Rm0v87eJhq4woh5rSR+42YSQJKecCqgIqNkZ6lAlQms/BwHPJA5NKMRlpxPRv0n8HQW6g== - colorspace@1.1.x: version "1.1.2" resolved "https://registry.yarnpkg.com/colorspace/-/colorspace-1.1.2.tgz#e0128950d082b86a2168580796a0aa5d6c68d8c5" @@ -11823,6 +11813,11 @@ commander@^8.3.0: resolved "https://registry.yarnpkg.com/commander/-/commander-8.3.0.tgz#4837ea1b2da67b9c616a67afbb0fafee567bca66" integrity sha512-OkTL9umf+He2DZkUq8f8J9of7yL6RJKI24dVITBmNfZBmri9zYZQrKkuXiKhyfPSu8tUhnVBB1iKXevvnlR4Ww== +commander@^9.1.0: + version "9.5.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-9.5.0.tgz#bc08d1eb5cedf7ccb797a96199d41c7bc3e60d30" + integrity sha512-KRs7WVDKg86PWiuAqhDrAQnTXZKraVcCc6vFdL14qrZ/DcWwuRo7VoiYXalXO7S5GKpqYiVEwCbgFDfxNHKJBQ== + common-path-prefix@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/common-path-prefix/-/common-path-prefix-3.0.0.tgz#7d007a7e07c58c4b4d5f433131a19141b29f11e0" @@ -12656,13 +12651,6 @@ debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, de dependencies: ms "2.1.2" -debug@4.1.1: - version "4.1.1" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.1.1.tgz#3b72260255109c6b589cee050f1d516139664791" - integrity sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw== - dependencies: - ms "^2.1.1" - debug@4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" @@ -14635,16 +14623,6 @@ findup-sync@^2.0.0: micromatch "^3.0.4" resolve-dir "^1.0.1" -findup-sync@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/findup-sync/-/findup-sync-3.0.0.tgz#17b108f9ee512dfb7a5c7f3c8b27ea9e1a9c08d1" - integrity sha512-YbffarhcicEhOrm4CtrwdKBdCuz576RLdhJDsIfvNtxUuhdRet1qZcsMjqbePtAseKdAnDyM/IyXbu7PRPRLYg== - dependencies: - detect-file "^1.0.0" - is-glob "^4.0.0" - micromatch "^3.0.4" - resolve-dir "^1.0.1" - fined@^1.0.1: version "1.2.0" resolved "https://registry.yarnpkg.com/fined/-/fined-1.2.0.tgz#d00beccf1aa2b475d16d423b0238b713a2c4a37b" @@ -15176,10 +15154,10 @@ get-value@^2.0.3, get-value@^2.0.6: resolved "https://registry.yarnpkg.com/get-value/-/get-value-2.0.6.tgz#dc15ca1c672387ca76bd37ac0a395ba2042a2c28" integrity sha1-3BXKHGcjh8p2vTesCjlbogQqLCg= -getopts@2.2.5: - version "2.2.5" - resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.2.5.tgz#67a0fe471cacb9c687d817cab6450b96dde8313b" - integrity sha512-9jb7AW5p3in+IiJWhQiZmmwkpLaR/ccTWdWQCtZM66HJcHHLegowh4q4tSD7gouUyeNvFWRavfK9GXosQHDpFA== +getopts@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/getopts/-/getopts-2.3.0.tgz#71e5593284807e03e2427449d4f6712a268666f4" + integrity sha512-5eDf9fuSXwxBL6q5HX+dhDj+dslFGWzU5thZ9kNKUkcPtaPdatmUFKwHFrLb/uf/WpA4BHET+AX3Scl56cAjpA== getos@^3.2.1: version "3.2.1" @@ -18358,23 +18336,25 @@ knex-stringcase@^1.4.2: dependencies: stringcase "^4.3.1" -knex@0.21.12: - version "0.21.12" - resolved "https://registry.yarnpkg.com/knex/-/knex-0.21.12.tgz#961bdb484311eb853030f6f49bd5bf9eca89dc51" - integrity sha512-AEyyiTM9p/x/Pb38TPZkvphKPmn8UWxP7MdIphzjAOielOfFFeU6pjP6y3M7UJ7rxrQsCrAYHwdonLQ3l1JCDw== +knex@2.4.2: + version "2.4.2" + resolved "https://registry.yarnpkg.com/knex/-/knex-2.4.2.tgz#a34a289d38406dc19a0447a78eeaf2d16ebedd61" + integrity sha512-tMI1M7a+xwHhPxjbl/H9K1kHX+VncEYcvCx5K00M16bWvpYPKAZd6QrCu68PtHAdIZNQPWZn0GVhqVBEthGWCg== dependencies: - colorette "1.2.1" - commander "^5.1.0" - debug "4.1.1" + colorette "2.0.19" + commander "^9.1.0" + debug "4.3.4" + escalade "^3.1.1" esm "^3.2.25" - getopts "2.2.5" + get-package-type "^0.1.0" + getopts "2.3.0" interpret "^2.2.0" - liftoff "3.1.0" - lodash "^4.17.20" - pg-connection-string "2.3.0" - tarn "^3.0.1" + lodash "^4.17.21" + pg-connection-string "2.5.0" + rechoir "^0.8.0" + resolve-from "^5.0.0" + tarn "^3.0.2" tildify "2.0.0" - v8flags "^3.2.0" kuler@^2.0.0: version "2.0.0" @@ -18499,20 +18479,6 @@ lie@3.1.1: dependencies: immediate "~3.0.5" -liftoff@3.1.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-3.1.0.tgz#c9ba6081f908670607ee79062d700df062c52ed3" - integrity sha512-DlIPlJUkCV0Ips2zf2pJP0unEoT1kwYhiiPUGF3s/jtxTCjziNLoiVVh+jqWOWeFi6mmwQ5fNxvAUyPad4Dfog== - dependencies: - extend "^3.0.0" - findup-sync "^3.0.0" - fined "^1.0.1" - flagged-respawn "^1.0.0" - is-plain-object "^2.0.4" - object.map "^1.0.0" - rechoir "^0.6.2" - resolve "^1.1.7" - liftoff@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/liftoff/-/liftoff-2.5.0.tgz#2009291bb31cea861bbf10a7c15a28caf75c31ec" @@ -21475,12 +21441,7 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -pg-connection-string@2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.3.0.tgz#c13fcb84c298d0bfa9ba12b40dd6c23d946f55d6" - integrity sha512-ukMTJXLI7/hZIwTW7hGMZJ0Lj0S2XQBCJ4Shv4y1zgQ/vqVea+FLhzywvPj0ujSuofu+yA4MYHGZPTsgjBgJ+w== - -pg-connection-string@^2.5.0: +pg-connection-string@2.5.0, pg-connection-string@^2.5.0: version "2.5.0" resolved "https://registry.yarnpkg.com/pg-connection-string/-/pg-connection-string-2.5.0.tgz#538cadd0f7e603fc09a12590f3b8a452c2c0cf34" integrity sha512-r5o/V/ORTA6TmUnyWZR9nCj1klXCO2CEKNRlVuJptZe85QuhFayC7WeMic7ndayT5IRIR0S0xFxFi2ousartlQ== @@ -23295,6 +23256,13 @@ rechoir@^0.7.0: dependencies: resolve "^1.9.0" +rechoir@^0.8.0: + version "0.8.0" + resolved "https://registry.yarnpkg.com/rechoir/-/rechoir-0.8.0.tgz#49f866e0d32146142da3ad8f0eff352b3215ff22" + integrity sha512-/vxpCXddiX8NGfGO/mTafwjq4aFa/71pvamip0++IQk3zG8cbCj0fifNPrjjF1XMXUne91jL9OoxmdykoEtifQ== + dependencies: + resolve "^1.20.0" + redent@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" @@ -25314,10 +25282,10 @@ tar@^6.0.2, tar@^6.1.0: mkdirp "^1.0.3" yallist "^4.0.0" -tarn@^3.0.1: - version "3.0.1" - resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.1.tgz#ebac2c6dbc6977d34d4526e0a7814200386a8aec" - integrity sha512-6usSlV9KyHsspvwu2duKH+FMUhqJnAh6J5J/4MITl8s94iSUQTLkJggdiewKv4RyARQccnigV48Z+khiuVZDJw== +tarn@^3.0.2: + version "3.0.2" + resolved "https://registry.yarnpkg.com/tarn/-/tarn-3.0.2.tgz#73b6140fbb881b71559c4f8bfde3d9a4b3d27693" + integrity sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ== teeny-request@^7.0.0: version "7.1.1" @@ -26573,13 +26541,6 @@ v8flags@^2.0.10: dependencies: user-home "^1.1.1" -v8flags@^3.2.0: - version "3.2.0" - resolved "https://registry.yarnpkg.com/v8flags/-/v8flags-3.2.0.tgz#b243e3b4dfd731fa774e7492128109a0fe66d656" - integrity sha512-mH8etigqMfiGWdeXpaaqGfs6BndypxusHHcv2qSHyZkGEznCd/qAXCWWRzeowtL54147cktFOC4P5y+kl8d8Jg== - dependencies: - homedir-polyfill "^1.0.1" - valid-url@^1.0.9: version "1.0.9" resolved "https://registry.yarnpkg.com/valid-url/-/valid-url-1.0.9.tgz#1c14479b40f1397a75782f115e4086447433a200" From 22c6962c59ddf8a8fbf714b7afc458dd5c4829a9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Kemp=C3=A9?= Date: Thu, 2 Feb 2023 18:03:40 +0100 Subject: [PATCH 02/13] Translate the English Getting Started to French --- .../fr/getting-started-guide.md | 173 ++++++++++++++++++ 1 file changed, 173 insertions(+) create mode 100644 docs/guides/getting-started/fr/getting-started-guide.md diff --git a/docs/guides/getting-started/fr/getting-started-guide.md b/docs/guides/getting-started/fr/getting-started-guide.md new file mode 100644 index 000000000..15723938b --- /dev/null +++ b/docs/guides/getting-started/fr/getting-started-guide.md @@ -0,0 +1,173 @@ +# Commencer avec Omnivore + +Omnivore est une **application de lecture ultérieure** qui vous permet de sauvegarder et d'organiser tout ce que vous lisez en ligne. + +Ce guide vous montrera comment utiliser les fonctions de base et les fonctionnalités avancées d'Omnivore, divisées en quatre activités principales: + + +* Sauvegarde +* Lecture +* Organisation +* Intégrations + +La **bibliothèque** est le centre de votre expérience Omnivore, où vous pouvez accéder rapidement à tous les liens que vous avez enregistrés. Les liens enregistrés restent dans votre bibliothèque à jamais, à moins que vous ne les supprimiez. + + +## Sauvegarde + + +Il existe cinq façons de sauvegarder des liens vers des pages ou des articles que vous souhaitez lire plus tard: + + + +* Sauvegarde depuis votre bibliothèque Omnivore +* Sauvegarde depuis un navigateur +* Sauvegarde depuis un téléphone ou une tablette (iOS ou Android) +* Abonnements à des newsletters via e-mail +* Sauvegarde de PDF à partir d'un Mac + + +### Saving from Your Omnivore Library +1. Dans le coin supérieur droit de votre bibliothèque, appuyez sur le bouton **Ajouter un lien**. +2. Entrez l'URL que vous souhaitez enregistrer et appuyez sur **Ajouter un lien**. +3. Le lien apparaîtra dans votre bibliothèque la prochaine fois que vous la rafraîchissez. + + +### Saving from a Browser + +1. Téléchargez et installez l'extension Omnivore pour votre navigateur : + +* [Chrome ](https://omnivore.app/install/chrome) +* [Edge](https://omnivore.app/install/edge) +* [Firefox](https://omnivore.app/install/firefox) +* [Safari](https://omnivore.app/install/safari) + +2. Accédez à la page que vous souhaitez enregistrer et appuyez sur le bouton Omnivore dans la barre d'outils de votre navigateur ou dans le menu Extensions. +3. Alternativement, vous pouvez cliquer avec le bouton droit (commande + clic sur Mac) sur n'importe quel lien hypertexte et sélectionner **Enregistrer dans Omnivore** dans le menu. +4. Le lien apparaîtra dans votre bibliothèque la prochaine fois que vous la rafraîchissez. + + + +### Enregistrement à partir d'un téléphone ou d'une tablette + +La meilleure façon d'enregistrer des liens à partir de votre appareil mobile est via l'application Omnivore. Vous pouvez télécharger l'application ici : + +* [iOS (iPhone ou iPad)](https://omnivore.app/install/ios) +* Android + +Une fois que l'application mobile est installée : + +1. Dans votre navigateur, accédez à la page que vous souhaitez enregistrer et appuyez sur le bouton **Partager**. +2. Appuyez sur l'icône **Omnivore** dans le menu Partager. +3. Le lien apparaîtra dans votre bibliothèque la prochaine fois que vous la rafraîchirez. + +### Abonnements à la newsletter via e-mail + +1. Sur le site web ou l'application Omnivore, appuyez sur votre photo, initiale ou avatar dans le coin supérieur droit pour accéder au menu de profil. Sélectionnez **Emails** dans le menu. +2. Appuyez sur **Créer une nouvelle adresse e-mail** pour ajouter une nouvelle adresse e-mail (par exemple : username-123_abc@inbox.omnivore.app) à la liste. +3. Cliquez sur l'icône Copier à côté de l'adresse e-mail. +4. Accédez à la page d'inscription pour la newsletter à laquelle vous souhaitez vous abonner. \ +5. Collez l'adresse e-mail Omnivore dans le formulaire d'inscription. +6. Les nouvelles newsletters seront automatiquement livrées à votre boîte de réception Omnivore. + + +### Enregistrement de PDF à partir d'un Mac + +1. Installez [l'application Mac](https://omnivore.app/install/mac). +2. Sur votre Mac, localisez le PDF que vous souhaitez enregistrer et faites un clic droit ou ctrl + clic sur le nom de fichier. +3. Sélectionnez **Partager** dans le menu et choisissez **Omnivore**. +4. Le lien apparaîtra dans votre bibliothèque la prochaine fois que vous la rafraîchirez. + + +## Lecture + +Cliquez sur n'importe quel lien enregistré dans votre bibliothèque pour accéder à la vue du lecteur. + +Omnivore formatte les pages pour une lecture facile et une surbrillance, en enlevant les publicités et les encombrements pour une lecture exempte de distractions. La vue axée sur le texte rend également les articles plus petits et plus rapides à charger. + +Pendant la lecture, vous pouvez : + +* Modifier la mise en forme +* Surligner le texte +* Ajouter des notes +* Voir toutes les surlignages et notes enregistrés +* Suivre la progression de la lecture + +### Modification de la mise en forme + +1. **_Thème:_** Appuyez sur votre photo, initiale ou avatar dans le coin supérieur droit pour accéder au menu de profil. Sélectionnez la miniature blanche ou noire pour choisir le thème clair ou sombre. +2. **_Mise en forme du texte:_** Appuyez sur l'icône Aa pour ajuster la taille du texte, la police, les marges et les espacements entre les lignes. + +### Mettre en surbrillance du texte + +1. Sélectionnez le texte que vous souhaitez mettre en surbrillance. +2. Appuyez sur le bouton **Mettre en surbrillance**. +3. Le texte apparaîtra en surbrillance la prochaine fois que vous consulterez l'article. + +### Ajouter des notes + +1. Mettre en surbrillance une section de texte où vous souhaitez ajouter une note. +2. Appuyez sur le bouton **Note**, tapez votre note et appuyez sur **Enregistrer**. +3. L'icône de note apparaîtra la prochaine fois que vous consulterez cet article. + +### Afficher toutes les surbrillances et les notes enregistrées + +1. Appuyez sur l'icône Mettre en surbrillance/Note pour afficher une liste de toutes les sections de texte mises en surbrillance et les notes que vous avez ajoutées à cette page. +2. Pour supprimer une note ou une surbrillance, sélectionnez-la dans la liste et appuyez sur l'icône Corbeille. + +### Suivre l'avancement de la lecture + +Omnivore garde automatiquement une trace de votre avancement de lecture sur vos différents appareils, de sorte que vous puissiez facilement reprendre là où vous vous êtes arrêté. Une barre de progression apparaîtra en haut de chaque lien de votre bibliothèque après que vous avez commencé à lire. + +## Organisation + +Par défaut, la boîte de réception de la bibliothèque affiche tous les liens que vous avez enregistrés. Pour gérer votre liste et maintenir votre lecture organisée, Omnivore fournit les actions suivantes: + +* Archivage +* Étiquettes +* Recherche +* Filtres + +### Archivage + +1. Appuyez sur l'icône Menu à côté du lien que vous souhaitez archiver (dans l'application mobile, appuyez longuement sur le lien pour ouvrir le menu). +2. Sélectionnez **Archiver**. +3. Le lien disparaîtra de la vue par défaut de la bibliothèque, mais sera visible si vous sélectionnez le filtre Archivé (voir Filtres ci-dessous). + +### Étiquettes + +1. Appuyez sur l'icône Menu à côté de n'importe quel lien et sélectionnez **Définir l'étiquette**. +2. Sélectionnez une étiquette existante dans la liste ou appuyez sur **Modifier** les étiquettes pour en créer une nouvelle. +3. L'étiquette apparaîtra à côté du lien dans votre bibliothèque. Appuyez dessus pour afficher tous les liens avec la même étiquette. +4. _Application mobile d'Omnivore uniquement_: appuyez sur **Étiquettes** pour voir une liste complète de toutes les étiquettes que vous avez utilisées; appuyez sur une étiquette pour afficher tous les liens avec la même étiquette. +5. Note : Omnivore attribuera automatiquement certaines étiquettes, telles que "Newsletters". + +### Recherche + +1. Pour rechercher parmi tous les liens que vous avez enregistrés, entrez un mot-clé ou une phrase dans la barre de recherche. +2. Vous pouvez combiner les mots-clés avec les étiquettes et les filtres pour cibler encore plus votre recherche. [En savoir plus sur la recherche avancée.](https://omnivore.app/help/search). + +### Filtres + +1. Utilisez le menu **Filtres** pour affiner votre vue de la bibliothèque (certains filtres peuvent être visibles par défaut). +2. Sélectionnez **Lire plus tard** pour afficher une liste de tous vos liens non archivés à l'exception des newsletters. +3. Sélectionnez **Sélections** pour afficher les sélections de texte que vous avez surlignées dans toutes les pages que vous avez enregistrées. +4. Sélectionnez **Aujourd'hui** pour afficher une liste de liens que vous avez enregistrés aujourd'hui. +5. Sélectionnez **Newsletters** pour afficher les liens enregistrés via vos abonnements à des newsletters. + +## Intégrations + +Omnivore permet des intégrations avec des bases de connaissances et des applications de prise de notes, notamment : + +* Logseq +* Webhooks + +### Logseq + +Logseq +Avec le plugin Omnivore pour Logseq, vous pouvez synchroniser tous vos articles enregistrés, vos surlignages et vos notes dans Logseq, une base de connaissances populaire. Pour obtenir des informations sur la configuration et l'utilisation du plugin Logseq, veuillez consulter ce guide utile [Omnivore pour le plugin Logseq](https://briansunter.com/graph/#/page/omnivore-logseq-guide). + + +### Webhooks + +Omnivore peut déclencher des webhooks lorsque vous enregistrez un lien ou ajoutez des surlignages à une page que vous lisez. Cet exemple montre comment utiliser les webhooks pour écrire tous les liens enregistrés dans une feuille de calcul Google Sheets stockée sur Google Drive. \ No newline at end of file From 0cfc87dae92e1e7c33958f25d1c6e0e18e10d826 Mon Sep 17 00:00:00 2001 From: Joseph Mearman Date: Mon, 20 Feb 2023 07:36:20 +0000 Subject: [PATCH 03/13] add links to readme --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 2ff862c17..1d8f2ad22 100644 --- a/README.md +++ b/README.md @@ -19,12 +19,14 @@ We built Omnivore because we love reading and we want it to be more social. Join - PDF support - [Web app](https://omnivore.app/) written in Node.js and TypeScript - [Native iOS app](https://omnivore.app/install/ios) +- [Android app](https://omnivore.app/install/android) ([source](https://github.com/omnivore-app/omnivore/tree/main/android/Omnivore)) - Progressive web app for Android users - Browser extensions for [Chrome](https://omnivore.app/install/chrome), [Safari](https://omnivore.app/install/safari), [Firefox](https://omnivore.app/install/firefox), and [Edge](https://omnivore.app/install/edge) - Labels (aka tagging) - Offline support - Text to speech (iOS only) - [Logseq](https://logseq.com/) support via our [Logseq Plugin](https://github.com/omnivore-app/logseq-omnivore) +- [Obsidian](https://obsidian.md/) support via our [Obsidian Plugin](https://github.com/omnivore-app/obsidian-omnivore) Every single part is fully open source! Fork it, extend it, or deploy it to your own server. From 4a6d478890b78a64b94a3024d316753d932fa0ed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Kemp=C3=A9?= Date: Thu, 23 Feb 2023 18:41:41 +0100 Subject: [PATCH 04/13] Reset to English the words used in the app UI as those won't get translated to French --- .../fr/getting-started-guide.md | 47 +++++++++---------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/docs/guides/getting-started/fr/getting-started-guide.md b/docs/guides/getting-started/fr/getting-started-guide.md index 15723938b..7c9f71557 100644 --- a/docs/guides/getting-started/fr/getting-started-guide.md +++ b/docs/guides/getting-started/fr/getting-started-guide.md @@ -10,7 +10,7 @@ Ce guide vous montrera comment utiliser les fonctions de base et les fonctionnal * Organisation * Intégrations -La **bibliothèque** est le centre de votre expérience Omnivore, où vous pouvez accéder rapidement à tous les liens que vous avez enregistrés. Les liens enregistrés restent dans votre bibliothèque à jamais, à moins que vous ne les supprimiez. +La **Library** est le centre de votre expérience Omnivore, où vous pouvez accéder rapidement à tous les liens que vous avez enregistrés. Les liens enregistrés restent dans votre bibliothèque à jamais, à moins que vous ne les supprimiez. ## Sauvegarde @@ -27,13 +27,13 @@ Il existe cinq façons de sauvegarder des liens vers des pages ou des articles q * Sauvegarde de PDF à partir d'un Mac -### Saving from Your Omnivore Library +### Sauvegarde depuis votre bibliothèque Omnivore 1. Dans le coin supérieur droit de votre bibliothèque, appuyez sur le bouton **Ajouter un lien**. 2. Entrez l'URL que vous souhaitez enregistrer et appuyez sur **Ajouter un lien**. 3. Le lien apparaîtra dans votre bibliothèque la prochaine fois que vous la rafraîchissez. -### Saving from a Browser +### Sauvegarde depuis un navigateur 1. Téléchargez et installez l'extension Omnivore pour votre navigateur : @@ -48,7 +48,7 @@ Il existe cinq façons de sauvegarder des liens vers des pages ou des articles q -### Enregistrement à partir d'un téléphone ou d'une tablette +### Sauvegarde depuis un téléphone ou une tablette La meilleure façon d'enregistrer des liens à partir de votre appareil mobile est via l'application Omnivore. Vous pouvez télécharger l'application ici : @@ -57,16 +57,16 @@ La meilleure façon d'enregistrer des liens à partir de votre appareil mobile e Une fois que l'application mobile est installée : -1. Dans votre navigateur, accédez à la page que vous souhaitez enregistrer et appuyez sur le bouton **Partager**. +1. Dans votre navigateur, accédez à la page que vous souhaitez enregistrer et appuyez sur le bouton **Share**. 2. Appuyez sur l'icône **Omnivore** dans le menu Partager. 3. Le lien apparaîtra dans votre bibliothèque la prochaine fois que vous la rafraîchirez. ### Abonnements à la newsletter via e-mail 1. Sur le site web ou l'application Omnivore, appuyez sur votre photo, initiale ou avatar dans le coin supérieur droit pour accéder au menu de profil. Sélectionnez **Emails** dans le menu. -2. Appuyez sur **Créer une nouvelle adresse e-mail** pour ajouter une nouvelle adresse e-mail (par exemple : username-123_abc@inbox.omnivore.app) à la liste. +2. Appuyez sur **Create a New Email Address** pour ajouter une nouvelle adresse e-mail (par exemple : username-123_abc@inbox.omnivore.app) à la liste. 3. Cliquez sur l'icône Copier à côté de l'adresse e-mail. -4. Accédez à la page d'inscription pour la newsletter à laquelle vous souhaitez vous abonner. \ +4. Accédez à la page d'inscription pour la newsletter à laquelle vous souhaitez vous abonner. 5. Collez l'adresse e-mail Omnivore dans le formulaire d'inscription. 6. Les nouvelles newsletters seront automatiquement livrées à votre boîte de réception Omnivore. @@ -75,7 +75,7 @@ Une fois que l'application mobile est installée : 1. Installez [l'application Mac](https://omnivore.app/install/mac). 2. Sur votre Mac, localisez le PDF que vous souhaitez enregistrer et faites un clic droit ou ctrl + clic sur le nom de fichier. -3. Sélectionnez **Partager** dans le menu et choisissez **Omnivore**. +3. Sélectionnez **Share** dans le menu et choisissez **Omnivore**. 4. Le lien apparaîtra dans votre bibliothèque la prochaine fois que vous la rafraîchirez. @@ -101,18 +101,18 @@ Pendant la lecture, vous pouvez : ### Mettre en surbrillance du texte 1. Sélectionnez le texte que vous souhaitez mettre en surbrillance. -2. Appuyez sur le bouton **Mettre en surbrillance**. +2. Appuyez sur le bouton **Highlight**. 3. Le texte apparaîtra en surbrillance la prochaine fois que vous consulterez l'article. ### Ajouter des notes 1. Mettre en surbrillance une section de texte où vous souhaitez ajouter une note. -2. Appuyez sur le bouton **Note**, tapez votre note et appuyez sur **Enregistrer**. +2. Appuyez sur le bouton **Note**, tapez votre note et appuyez sur **Save**. 3. L'icône de note apparaîtra la prochaine fois que vous consulterez cet article. ### Afficher toutes les surbrillances et les notes enregistrées -1. Appuyez sur l'icône Mettre en surbrillance/Note pour afficher une liste de toutes les sections de texte mises en surbrillance et les notes que vous avez ajoutées à cette page. +1. Appuyez sur l'icône Highlight/Note pour afficher une liste de toutes les sections de texte mises en surbrillance et les notes que vous avez ajoutées à cette page. 2. Pour supprimer une note ou une surbrillance, sélectionnez-la dans la liste et appuyez sur l'icône Corbeille. ### Suivre l'avancement de la lecture @@ -123,23 +123,23 @@ Omnivore garde automatiquement une trace de votre avancement de lecture sur vos Par défaut, la boîte de réception de la bibliothèque affiche tous les liens que vous avez enregistrés. Pour gérer votre liste et maintenir votre lecture organisée, Omnivore fournit les actions suivantes: -* Archivage -* Étiquettes -* Recherche -* Filtres +* Archiving +* Labels +* Search +* Filters ### Archivage 1. Appuyez sur l'icône Menu à côté du lien que vous souhaitez archiver (dans l'application mobile, appuyez longuement sur le lien pour ouvrir le menu). -2. Sélectionnez **Archiver**. +2. Sélectionnez **Archive**. 3. Le lien disparaîtra de la vue par défaut de la bibliothèque, mais sera visible si vous sélectionnez le filtre Archivé (voir Filtres ci-dessous). ### Étiquettes -1. Appuyez sur l'icône Menu à côté de n'importe quel lien et sélectionnez **Définir l'étiquette**. -2. Sélectionnez une étiquette existante dans la liste ou appuyez sur **Modifier** les étiquettes pour en créer une nouvelle. +1. Appuyez sur l'icône Menu à côté de n'importe quel lien et sélectionnez **Set Labels**. +2. Sélectionnez une étiquette existante dans la liste ou appuyez sur **Edit Labels** les étiquettes pour en créer une nouvelle. 3. L'étiquette apparaîtra à côté du lien dans votre bibliothèque. Appuyez dessus pour afficher tous les liens avec la même étiquette. -4. _Application mobile d'Omnivore uniquement_: appuyez sur **Étiquettes** pour voir une liste complète de toutes les étiquettes que vous avez utilisées; appuyez sur une étiquette pour afficher tous les liens avec la même étiquette. +4. _Application mobile d'Omnivore uniquement_: appuyez sur **Labels ** pour voir une liste complète de toutes les étiquettes que vous avez utilisées; appuyez sur une étiquette pour afficher tous les liens avec la même étiquette. 5. Note : Omnivore attribuera automatiquement certaines étiquettes, telles que "Newsletters". ### Recherche @@ -149,10 +149,10 @@ Par défaut, la boîte de réception de la bibliothèque affiche tous les liens ### Filtres -1. Utilisez le menu **Filtres** pour affiner votre vue de la bibliothèque (certains filtres peuvent être visibles par défaut). -2. Sélectionnez **Lire plus tard** pour afficher une liste de tous vos liens non archivés à l'exception des newsletters. -3. Sélectionnez **Sélections** pour afficher les sélections de texte que vous avez surlignées dans toutes les pages que vous avez enregistrées. -4. Sélectionnez **Aujourd'hui** pour afficher une liste de liens que vous avez enregistrés aujourd'hui. +1. Utilisez le menu **Filters** pour affiner votre vue de la bibliothèque (certains filtres peuvent être visibles par défaut). +2. Sélectionnez **Read Later** pour afficher une liste de tous vos liens non archivés à l'exception des newsletters. +3. Sélectionnez **Highlights** pour afficher les sélections de texte que vous avez surlignées dans toutes les pages que vous avez enregistrées. +4. Sélectionnez **Today** pour afficher une liste de liens que vous avez enregistrés aujourd'hui. 5. Sélectionnez **Newsletters** pour afficher les liens enregistrés via vos abonnements à des newsletters. ## Intégrations @@ -164,7 +164,6 @@ Omnivore permet des intégrations avec des bases de connaissances et des applica ### Logseq -Logseq Avec le plugin Omnivore pour Logseq, vous pouvez synchroniser tous vos articles enregistrés, vos surlignages et vos notes dans Logseq, une base de connaissances populaire. Pour obtenir des informations sur la configuration et l'utilisation du plugin Logseq, veuillez consulter ce guide utile [Omnivore pour le plugin Logseq](https://briansunter.com/graph/#/page/omnivore-logseq-guide). From b8272b3a47f9541e0777617ebb83fb64b419f55a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Laurent=20Kemp=C3=A9?= Date: Thu, 23 Feb 2023 18:44:52 +0100 Subject: [PATCH 05/13] Fix some missing words found during review --- docs/guides/getting-started/fr/getting-started-guide.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/guides/getting-started/fr/getting-started-guide.md b/docs/guides/getting-started/fr/getting-started-guide.md index 7c9f71557..79dce2450 100644 --- a/docs/guides/getting-started/fr/getting-started-guide.md +++ b/docs/guides/getting-started/fr/getting-started-guide.md @@ -28,8 +28,8 @@ Il existe cinq façons de sauvegarder des liens vers des pages ou des articles q ### Sauvegarde depuis votre bibliothèque Omnivore -1. Dans le coin supérieur droit de votre bibliothèque, appuyez sur le bouton **Ajouter un lien**. -2. Entrez l'URL que vous souhaitez enregistrer et appuyez sur **Ajouter un lien**. +1. Dans le coin supérieur droit de votre bibliothèque, appuyez sur le bouton **Add Link**. +2. Entrez l'URL que vous souhaitez enregistrer et appuyez sur **Add Link**. 3. Le lien apparaîtra dans votre bibliothèque la prochaine fois que vous la rafraîchissez. From de9524c3e8fb744411e436c865a1627f8c8169b7 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Mon, 27 Feb 2023 12:06:46 +0800 Subject: [PATCH 06/13] Fix confusing unsubscribing url with email address --- .../content-handler/src/content-handler.ts | 4 +-- .../content-handler/test/newsletter.test.ts | 31 +++++++++++++++++++ 2 files changed, 33 insertions(+), 2 deletions(-) diff --git a/packages/content-handler/src/content-handler.ts b/packages/content-handler/src/content-handler.ts index 1a27344f0..7ef7dffd2 100644 --- a/packages/content-handler/src/content-handler.ts +++ b/packages/content-handler/src/content-handler.ts @@ -150,8 +150,8 @@ export abstract class ContentHandler { // e.g. List-Unsubscribe: , const decoded = rfc2047.decode(unSubHeader) return { - mailTo: decoded.match(/<(https?:\/\/[^>]*)>/)?.[1], - httpUrl: decoded.match(/]*)>/)?.[1], + httpUrl: decoded.match(/<(https?:\/\/[^>]*)>/)?.[1], + mailTo: decoded.match(/]*)>/)?.[1], } } diff --git a/packages/content-handler/test/newsletter.test.ts b/packages/content-handler/test/newsletter.test.ts index 0ffa6d666..a515cf486 100644 --- a/packages/content-handler/test/newsletter.test.ts +++ b/packages/content-handler/test/newsletter.test.ts @@ -516,4 +516,35 @@ describe('Newsletter email test', () => { expect(url1).to.not.eql(url2) }) }) + + describe('get unsubscribe from header', () => { + const mailTo = 'unsub@omnivore.com' + const httpUrl = 'https://omnivore.com/unsubscribe' + + it('returns mail to address if exists', () => { + const header = `, ` + + expect(new GenericHandler().parseUnsubscribe(header).mailTo).to.equal( + mailTo + ) + }) + + it('returns http url if exists', () => { + const header = `<${httpUrl}>` + + expect(new GenericHandler().parseUnsubscribe(header).httpUrl).to.equal( + httpUrl + ) + }) + + context('when unsubscribe header rfc2047 encoded', () => { + it('returns mail to address if exists', () => { + const header = `=?us-ascii?Q?=3Cmailto=3A654e9594-184c-4884-8e02-e6e58a3a6871+87e39b3d-c3ca-4be?= =?us-ascii?Q?b-ba4d-977cc2ba61e7+067a353f-f775-4f2c-?= =?us-ascii?Q?a5cc-978df38deeca=40unsub=2Ebeehiiv=2Ecom=3E=2C?= =?us-ascii?Q?_=3Chttps=3A=2F=2Fwww=2Emilkroad=2Ecom=2Fsubscribe=2F87e39b3d-c3ca-4beb-ba4d-97?= =?us-ascii?Q?7cc2ba61e7=2Fmanage=3Fpost=5Fid=3D067a353f-f775?= =?us-ascii?Q?-4f2c-a5cc-978df38deeca=3E?=',` + + expect(new GenericHandler().parseUnsubscribe(header).mailTo).to.equal( + '654e9594-184c-4884-8e02-e6e58a3a6871+87e39b3d-c3ca-4beb-ba4d-977cc2ba61e7+067a353f-f775-4f2c-a5cc-978df38deeca@unsub.beehiiv.com' + ) + }) + }) + }) }) From ef34ced1d24020c1d81ee0e36b68c8b5352f16cd Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 27 Feb 2023 21:18:05 +0000 Subject: [PATCH 07/13] Bump cypress from 10.6.0 to 12.7.0 Bumps [cypress](https://github.com/cypress-io/cypress) from 10.6.0 to 12.7.0. - [Release notes](https://github.com/cypress-io/cypress/releases) - [Changelog](https://github.com/cypress-io/cypress/blob/develop/CHANGELOG.md) - [Commits](https://github.com/cypress-io/cypress/compare/v10.6.0...v12.7.0) --- updated-dependencies: - dependency-name: cypress dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] --- packages/cypress/package.json | 2 +- yarn.lock | 38 ++++++++++++----------------------- 2 files changed, 14 insertions(+), 26 deletions(-) diff --git a/packages/cypress/package.json b/packages/cypress/package.json index 34a14a5a6..f13495814 100644 --- a/packages/cypress/package.json +++ b/packages/cypress/package.json @@ -7,7 +7,7 @@ }, "dependencies": { "@testing-library/cypress": "^8.0.2", - "cypress": "^10.1.0" + "cypress": "^12.7.0" }, "devDependencies": {}, "volta": { diff --git a/yarn.lock b/yarn.lock index 33ab030a3..f6fe25371 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12536,10 +12536,10 @@ cyclist@^1.0.1: resolved "https://registry.yarnpkg.com/cyclist/-/cyclist-1.0.1.tgz#596e9698fd0c80e12038c2b82d6eb1b35b6224d9" integrity sha1-WW6WmP0MgOEgOMK4LW6xs1tiJNk= -cypress@^10.1.0: - version "10.6.0" - resolved "https://registry.yarnpkg.com/cypress/-/cypress-10.6.0.tgz#13f46867febf2c3715874ed5dce9c2e946b175fe" - integrity sha512-6sOpHjostp8gcLO34p6r/Ci342lBs8S5z9/eb3ZCQ22w2cIhMWGUoGKkosabPBfKcvRS9BE4UxybBtlIs8gTQA== +cypress@^12.7.0: + version "12.7.0" + resolved "https://registry.yarnpkg.com/cypress/-/cypress-12.7.0.tgz#69900f82af76cf3ba0ddb9b59ec3b0d38222ab22" + integrity sha512-7rq+nmhzz0u6yabCFyPtADU2OOrYt6pvUau9qV7xyifJ/hnsaw/vkr0tnLlcuuQKUAOC1v1M1e4Z0zG7S0IAvA== dependencies: "@cypress/request" "^2.88.10" "@cypress/xvfb" "^1.2.4" @@ -12558,9 +12558,9 @@ cypress@^10.1.0: commander "^5.1.0" common-tags "^1.8.0" dayjs "^1.10.4" - debug "^4.3.2" + debug "^4.3.4" enquirer "^2.3.6" - eventemitter2 "^6.4.3" + eventemitter2 "6.4.7" execa "4.1.0" executable "^4.1.1" extract-zip "2.0.1" @@ -12640,16 +12640,11 @@ dateformat@^3.0.0: resolved "https://registry.yarnpkg.com/dateformat/-/dateformat-3.0.3.tgz#a6e37499a4d9a9cf85ef5872044d62901c9889ae" integrity sha512-jyCETtSl3VMZMWeRo7iY1FL19ges1t55hMo5yaam4Jrsm5EPL89UQkoQRyiI+Yf4k8r2ZpdngkV8hr1lIdjb3Q== -dayjs@1.x: +dayjs@1.x, dayjs@^1.10.4: version "1.11.6" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.6.tgz#2e79a226314ec3ec904e3ee1dd5a4f5e5b1c7afb" integrity sha512-zZbY5giJAinCG+7AGaw0wIhNZ6J8AhWuSXKvuc1KAyMiRsvGQWqh4L+MomvhdAYjN+lqvVCMq1I41e3YHvXkyQ== -dayjs@^1.10.4: - version "1.11.0" - resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.0.tgz#009bf7ef2e2ea2d5db2e6583d2d39a4b5061e805" - integrity sha512-JLC809s6Y948/FuCZPm5IX8rRhQwOiyMb2TfVVQEixG7P8Lm/gt5S7yoQZmC8x1UehI9Pb7sksEt4xx14m+7Ug== - debounce@^1.2.0: version "1.2.0" resolved "https://registry.yarnpkg.com/debounce/-/debounce-1.2.0.tgz#44a540abc0ea9943018dc0eaa95cce87f65cd131" @@ -12662,7 +12657,7 @@ debug@2.6.9, debug@^2.2.0, debug@^2.3.3, debug@^2.6.0, debug@^2.6.9: dependencies: ms "2.0.0" -debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3: +debug@4, debug@4.3.4, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2, debug@^4.3.3, debug@^4.3.4: version "4.3.4" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.4.tgz#1319f6579357f2338d3337d2cdd4914bb5dcc865" integrity sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ== @@ -14088,10 +14083,10 @@ event-target-shim@^5.0.0: resolved "https://registry.yarnpkg.com/event-target-shim/-/event-target-shim-5.0.1.tgz#5d4d3ebdf9583d63a5333ce2deb7480ab2b05789" integrity sha512-i/2XbnSz/uxRCU6+NdVJgKWDTM427+MqYbkQzD321DuCQJUqOuJKIA0IM2+W2xtYHdKOmZ4dR6fExsd4SXL+WQ== -eventemitter2@^6.4.3: - version "6.4.5" - resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.5.tgz#97380f758ae24ac15df8353e0cc27f8b95644655" - integrity sha512-bXE7Dyc1i6oQElDG0jMRZJrRAn9QR2xyyFGmBdZleNmyQX0FqGYmhZIrIrpPfm/w//LTo4tVQGOGQcGCb5q9uw== +eventemitter2@6.4.7: + version "6.4.7" + resolved "https://registry.yarnpkg.com/eventemitter2/-/eventemitter2-6.4.7.tgz#a7f6c4d7abf28a14c1ef3442f21cb306a054271d" + integrity sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg== eventemitter3@^3.1.0: version "3.1.2" @@ -24091,14 +24086,7 @@ semver@^6.0.0, semver@^6.1.1, semver@^6.1.2, semver@^6.2.0, semver@^6.3.0: resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" integrity sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw== -semver@^7.1.1, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: - version "7.3.5" - resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.5.tgz#0b621c879348d8998e4b0e4be94b3f12e6018ef7" - integrity sha512-PoeGJYh8HK4BTO/a9Tf6ZG3veo/A7ZVsYrSA6J8ny9nb3B1VrpkuN+z9OE5wfE5p6H4LchYZsegiQgbJD94ZFQ== - dependencies: - lru-cache "^6.0.0" - -semver@^7.1.2: +semver@^7.1.1, semver@^7.1.2, semver@^7.1.3, semver@^7.2.1, semver@^7.3.2, semver@^7.3.4, semver@^7.3.5: version "7.3.8" resolved "https://registry.yarnpkg.com/semver/-/semver-7.3.8.tgz#07a78feafb3f7b32347d725e33de7e2a2df67798" integrity sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A== From bd12ecd7ecf7694ff808b1df8d1c919d7b05d201 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Thu, 2 Mar 2023 13:40:59 +0800 Subject: [PATCH 08/13] Add publishedAt to the updatePageInput --- packages/api/src/generated/graphql.ts | 1 + packages/api/src/generated/schema.graphql | 1 + packages/api/src/resolvers/update/index.ts | 1 + packages/api/src/schema.ts | 1 + 4 files changed, 4 insertions(+) diff --git a/packages/api/src/generated/graphql.ts b/packages/api/src/generated/graphql.ts index 161a0dca3..4f1b91032 100644 --- a/packages/api/src/generated/graphql.ts +++ b/packages/api/src/generated/graphql.ts @@ -2813,6 +2813,7 @@ export type UpdatePageInput = { byline?: InputMaybe; description?: InputMaybe; pageId: Scalars['ID']; + publishedAt?: InputMaybe; savedAt?: InputMaybe; title?: InputMaybe; }; diff --git a/packages/api/src/generated/schema.graphql b/packages/api/src/generated/schema.graphql index 34968394b..7156d96ce 100644 --- a/packages/api/src/generated/schema.graphql +++ b/packages/api/src/generated/schema.graphql @@ -2166,6 +2166,7 @@ input UpdatePageInput { byline: String description: String pageId: ID! + publishedAt: Date savedAt: Date title: String } diff --git a/packages/api/src/resolvers/update/index.ts b/packages/api/src/resolvers/update/index.ts index 8b2551518..0570e43b8 100644 --- a/packages/api/src/resolvers/update/index.ts +++ b/packages/api/src/resolvers/update/index.ts @@ -41,6 +41,7 @@ export const updatePageResolver = authorized< description: input.description ?? undefined, author: input.byline ?? undefined, savedAt: input.savedAt ? new Date(input.savedAt) : undefined, + publishedAt: input.publishedAt ? new Date(input.publishedAt) : undefined, } const updateResult = await updatePage(input.pageId, pageData, { ...ctx, uid }) diff --git a/packages/api/src/schema.ts b/packages/api/src/schema.ts index 5d4353c0b..4d3403066 100755 --- a/packages/api/src/schema.ts +++ b/packages/api/src/schema.ts @@ -565,6 +565,7 @@ const schema = gql` description: String byline: String savedAt: Date + publishedAt: Date } type UpdatePageSuccess { From 0a350bef6d62c844123317e00d547c52ab4d9883 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Sun, 5 Mar 2023 21:36:46 +0800 Subject: [PATCH 09/13] Fix issues with knex version bump --- packages/api/src/apollo.ts | 4 ++-- packages/api/src/datalayer/article/index.ts | 2 +- .../datalayer/article_saving_request/index.ts | 4 ++-- packages/api/src/datalayer/helpers.ts | 4 ++-- packages/api/src/datalayer/highlight/index.ts | 11 +++++++---- packages/api/src/datalayer/knex_config.ts | 4 ++-- packages/api/src/datalayer/links/index.ts | 2 +- packages/api/src/datalayer/links/share_info.ts | 2 +- packages/api/src/datalayer/model.ts | 4 ++-- packages/api/src/datalayer/reaction/index.ts | 6 +++--- packages/api/src/datalayer/reminders/index.ts | 2 +- packages/api/src/datalayer/report/index.ts | 2 +- packages/api/src/datalayer/task/index.ts | 4 ++-- packages/api/src/datalayer/upload_files/index.ts | 2 +- packages/api/src/datalayer/user/index.ts | 2 +- packages/api/src/datalayer/user_friends/index.ts | 2 +- .../src/datalayer/user_personalization/index.ts | 2 +- packages/api/src/graphql.d.ts | 2 +- packages/api/src/resolvers/types.ts | 2 +- packages/api/src/resolvers/user_friends/index.ts | 16 ++++++++-------- packages/api/src/server.ts | 2 +- packages/api/src/services/save_file.ts | 2 +- 22 files changed, 43 insertions(+), 40 deletions(-) diff --git a/packages/api/src/apollo.ts b/packages/api/src/apollo.ts index 075245092..0a8f49fb8 100644 --- a/packages/api/src/apollo.ts +++ b/packages/api/src/apollo.ts @@ -7,7 +7,7 @@ import { ContextFunction } from 'apollo-server-core' import { ClaimsToSet, ResolverContext } from './resolvers/types' import { SetClaimsRole } from './utils/dictionary' -import Knex, { Transaction } from 'knex' +import { Knex } from 'knex' import { ExpressContext } from 'apollo-server-express/dist/ApolloServer' import * as jwt from 'jsonwebtoken' import { kx } from './datalayer/knex_config' @@ -48,7 +48,7 @@ const contextFunc: ContextFunction = async ({ const claims = await getClaimsByToken(token) async function setClaims( - tx: Transaction, + tx: Knex.Transaction, uuid?: string, userRole?: string ): Promise { diff --git a/packages/api/src/datalayer/article/index.ts b/packages/api/src/datalayer/article/index.ts index 5ddb6f12a..f6235265a 100644 --- a/packages/api/src/datalayer/article/index.ts +++ b/packages/api/src/datalayer/article/index.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import { ArticleData, CreateSet, keys as modelKeys, UpdateSet } from './model' import DataModel from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { Table } from '../../utils/dictionary' import { logMethod } from '../helpers' diff --git a/packages/api/src/datalayer/article_saving_request/index.ts b/packages/api/src/datalayer/article_saving_request/index.ts index c753fcddb..c9d625622 100644 --- a/packages/api/src/datalayer/article_saving_request/index.ts +++ b/packages/api/src/datalayer/article_saving_request/index.ts @@ -1,11 +1,11 @@ import { + ArticleSavingRequestData, CreateSet, keys as modelKeys, UpdateSet, - ArticleSavingRequestData, } from './model' import DataModel from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { Table } from '../../utils/dictionary' import { logMethod } from '../helpers' diff --git a/packages/api/src/datalayer/helpers.ts b/packages/api/src/datalayer/helpers.ts index 65cd78ef0..7768d0667 100644 --- a/packages/api/src/datalayer/helpers.ts +++ b/packages/api/src/datalayer/helpers.ts @@ -5,7 +5,7 @@ /* eslint-disable @typescript-eslint/no-explicit-any */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import DataModel from './model' -import Knex, { Transaction } from 'knex' +import { Knex } from 'knex' import DataLoader from 'dataloader' import { snakeCase } from 'snake-case' import { buildLogger } from '../utils/logger' @@ -14,7 +14,7 @@ import { SetClaimsRole } from '../utils/dictionary' const logger = buildLogger('datalayer') export const setClaims = async ( - tx: Transaction, + tx: Knex.Transaction, uuid?: string, userRole?: string ): Promise => { diff --git a/packages/api/src/datalayer/highlight/index.ts b/packages/api/src/datalayer/highlight/index.ts index 1f7ac2fc5..8bd8fb06a 100644 --- a/packages/api/src/datalayer/highlight/index.ts +++ b/packages/api/src/datalayer/highlight/index.ts @@ -4,7 +4,7 @@ import DataModel, { DataModelError, MAX_RECORDS_LIMIT } from '../model' import { CreateSet, HighlightData, keys as modelKeys, UpdateSet } from './model' import { Table } from '../../utils/dictionary' -import Knex from 'knex' +import { Knex } from 'knex' import { ENABLE_DB_REQUEST_LOGGING, globalCounter } from '../helpers' import DataLoader from 'dataloader' @@ -26,7 +26,8 @@ class HighlightModel extends DataModel { } try { - const rows: HighlightData[] = await kx(this.tableName) + const rows: HighlightData[] = await kx + .table(this.tableName) .select(this.modelKeys) .whereIn('id', keys) .andWhere('deleted', false) @@ -60,7 +61,8 @@ class HighlightModel extends DataModel { ) } - const result = await this.kx(Table.HIGHLIGHT) + const result = await this.kx + .table(Table.HIGHLIGHT) .select(modelKeys) .whereIn('elasticPageId', articleIds) .andWhere('deleted', false) @@ -153,7 +155,8 @@ class HighlightModel extends DataModel { userId: string, articleId: string ): Promise { - const highlights = await this.kx(Table.HIGHLIGHT) + const highlights: HighlightData[] = await this.kx + .table(Table.HIGHLIGHT) .select(modelKeys) .where('user_id', userId) .andWhere('elastic_page_id', articleId) diff --git a/packages/api/src/datalayer/knex_config.ts b/packages/api/src/datalayer/knex_config.ts index 6758a4454..06ff66783 100644 --- a/packages/api/src/datalayer/knex_config.ts +++ b/packages/api/src/datalayer/knex_config.ts @@ -1,8 +1,8 @@ import { env } from '../env' -import Knex from 'knex' +import knex from 'knex' import knexStringcase from 'knex-stringcase' -export const kx = Knex( +export const kx = knex( knexStringcase({ client: 'pg', connection: { diff --git a/packages/api/src/datalayer/links/index.ts b/packages/api/src/datalayer/links/index.ts index ab8a36308..08ba9e266 100644 --- a/packages/api/src/datalayer/links/index.ts +++ b/packages/api/src/datalayer/links/index.ts @@ -12,7 +12,7 @@ import { UserFeedArticleData, } from './model' import DataModel, { MAX_RECORDS_LIMIT } from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { Table } from '../../utils/dictionary' import { Article, diff --git a/packages/api/src/datalayer/links/share_info.ts b/packages/api/src/datalayer/links/share_info.ts index 2646cfc57..cf1126eaa 100644 --- a/packages/api/src/datalayer/links/share_info.ts +++ b/packages/api/src/datalayer/links/share_info.ts @@ -1,6 +1,6 @@ /* eslint-disable @typescript-eslint/no-unsafe-return */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ -import Knex from 'knex' +import { Knex } from 'knex' import { LinkShareInfo } from '../../generated/graphql' import { DataModels } from '../../resolvers/types' import { getPageByParam } from '../../elastic/pages' diff --git a/packages/api/src/datalayer/model.ts b/packages/api/src/datalayer/model.ts index 98b3d5dac..f2ebfe2d2 100644 --- a/packages/api/src/datalayer/model.ts +++ b/packages/api/src/datalayer/model.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/no-floating-promises */ /* eslint-disable @typescript-eslint/no-unsafe-assignment */ import DataLoader from 'dataloader' -import Knex from 'knex' +import { Knex } from 'knex' import { ENABLE_DB_REQUEST_LOGGING, globalCounter } from './helpers' export enum DataModelError { @@ -113,7 +113,7 @@ abstract class DataModel< tx: Knex.Transaction ): Promise { const rows: ModelData[] = await tx - .batchInsert(this.tableName, data) + .batchInsert(this.tableName, data as never) .returning('*') for (const row of rows) { this.loader.prime(row.id, row) diff --git a/packages/api/src/datalayer/reaction/index.ts b/packages/api/src/datalayer/reaction/index.ts index 2b1cec74c..6c77544f1 100644 --- a/packages/api/src/datalayer/reaction/index.ts +++ b/packages/api/src/datalayer/reaction/index.ts @@ -1,11 +1,11 @@ import { - globalCounter, ENABLE_DB_REQUEST_LOGGING, + globalCounter, logMethod, } from './../helpers' -import { CreateSet, keys as modelKeys, UpdateSet, ReactionData } from './model' +import { CreateSet, keys as modelKeys, ReactionData, UpdateSet } from './model' import DataModel, { DataModelError, MAX_RECORDS_LIMIT } from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { Table } from '../../utils/dictionary' import DataLoader from 'dataloader' diff --git a/packages/api/src/datalayer/reminders/index.ts b/packages/api/src/datalayer/reminders/index.ts index c910dc605..2b6e74728 100644 --- a/packages/api/src/datalayer/reminders/index.ts +++ b/packages/api/src/datalayer/reminders/index.ts @@ -6,7 +6,7 @@ import { UpdateSet, } from './model' import DataModel, { DataModelError } from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { Table } from '../../utils/dictionary' import { logMethod } from '../helpers' import { ArticleData } from '../article/model' diff --git a/packages/api/src/datalayer/report/index.ts b/packages/api/src/datalayer/report/index.ts index fbcbd8166..0906e281e 100644 --- a/packages/api/src/datalayer/report/index.ts +++ b/packages/api/src/datalayer/report/index.ts @@ -1,4 +1,4 @@ -import Knex from 'knex' +import { Knex } from 'knex' import { ReportType } from '../../generated/graphql' interface ReportItem { diff --git a/packages/api/src/datalayer/task/index.ts b/packages/api/src/datalayer/task/index.ts index 969f883dd..b0f31624d 100644 --- a/packages/api/src/datalayer/task/index.ts +++ b/packages/api/src/datalayer/task/index.ts @@ -1,6 +1,6 @@ -import { CreateSet, keys as modelKeys, UpdateSet, TaskData } from './model' +import { CreateSet, keys as modelKeys, TaskData, UpdateSet } from './model' import DataModel from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { logMethod } from '../helpers' class TaskModel extends DataModel { diff --git a/packages/api/src/datalayer/upload_files/index.ts b/packages/api/src/datalayer/upload_files/index.ts index 6a412b99f..6899d6309 100644 --- a/packages/api/src/datalayer/upload_files/index.ts +++ b/packages/api/src/datalayer/upload_files/index.ts @@ -7,7 +7,7 @@ import { UploadFileData, } from './model' import DataModel from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { Table } from '../../utils/dictionary' import { logMethod } from '../helpers' diff --git a/packages/api/src/datalayer/user/index.ts b/packages/api/src/datalayer/user/index.ts index a4f6058b2..5112c08b6 100644 --- a/packages/api/src/datalayer/user/index.ts +++ b/packages/api/src/datalayer/user/index.ts @@ -11,7 +11,7 @@ import { UserData, } from './model' import DataModel, { DataModelError, MAX_RECORDS_LIMIT } from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { ENABLE_DB_REQUEST_LOGGING, globalCounter, logMethod } from '../helpers' import { Table } from '../../utils/dictionary' import DataLoader from 'dataloader' diff --git a/packages/api/src/datalayer/user_friends/index.ts b/packages/api/src/datalayer/user_friends/index.ts index 15695261d..8ff18e0d8 100644 --- a/packages/api/src/datalayer/user_friends/index.ts +++ b/packages/api/src/datalayer/user_friends/index.ts @@ -6,7 +6,7 @@ import { UserFriendData, } from './model' import DataModel, { MAX_RECORDS_LIMIT } from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { Table } from '../../utils/dictionary' import { ENABLE_DB_REQUEST_LOGGING, globalCounter, logMethod } from '../helpers' import DataLoader from 'dataloader' diff --git a/packages/api/src/datalayer/user_personalization/index.ts b/packages/api/src/datalayer/user_personalization/index.ts index 1fd0894e0..424de749d 100644 --- a/packages/api/src/datalayer/user_personalization/index.ts +++ b/packages/api/src/datalayer/user_personalization/index.ts @@ -9,7 +9,7 @@ import { UserPersonalizationData, } from './model' import DataModel from '../model' -import Knex from 'knex' +import { Knex } from 'knex' import { Table } from '../../utils/dictionary' import { camelCase } from 'voca' import { logMethod } from '../helpers' diff --git a/packages/api/src/graphql.d.ts b/packages/api/src/graphql.d.ts index edc12ba67..6c4bc953c 100755 --- a/packages/api/src/graphql.d.ts +++ b/packages/api/src/graphql.d.ts @@ -8,7 +8,7 @@ declare module '*.graphql' { } declare module 'knex-stringcase' { - import * as Knex from 'knex' + import { Knex } from 'knex' type StringCase = | 'camelcase' diff --git a/packages/api/src/resolvers/types.ts b/packages/api/src/resolvers/types.ts index 00e11b978..5e7aa2d00 100644 --- a/packages/api/src/resolvers/types.ts +++ b/packages/api/src/resolvers/types.ts @@ -1,7 +1,7 @@ /* eslint-disable @typescript-eslint/ban-types */ import { Context as ApolloContext } from 'apollo-server-core' import winston from 'winston' -import Knex from 'knex' +import { Knex } from 'knex' import UserModel from '../datalayer/user' import ArticleModel from '../datalayer/article' import UserArticleModel from '../datalayer/links' diff --git a/packages/api/src/resolvers/user_friends/index.ts b/packages/api/src/resolvers/user_friends/index.ts index ea13cc095..39da6e5d8 100644 --- a/packages/api/src/resolvers/user_friends/index.ts +++ b/packages/api/src/resolvers/user_friends/index.ts @@ -1,18 +1,18 @@ -import Knex from 'knex' +import { Knex } from 'knex' import { UserData } from '../../datalayer/user/model' import { - User, - ResolverFn, - SetFollowSuccess, - SetFollowError, - MutationSetFollowArgs, - SetFollowErrorCode, GetFollowersResult, GetFollowingResult, + MutationSetFollowArgs, QueryGetFollowersArgs, QueryGetFollowingArgs, + ResolverFn, + SetFollowError, + SetFollowErrorCode, + SetFollowSuccess, + User, } from '../../generated/graphql' -import { userDataToUser, authorized } from '../../utils/helpers' +import { authorized, userDataToUser } from '../../utils/helpers' import { DataModels, WithDataSourcesContext } from '../types' export const setFollowResolver = authorized< diff --git a/packages/api/src/server.ts b/packages/api/src/server.ts index bb15c3d3e..506046777 100755 --- a/packages/api/src/server.ts +++ b/packages/api/src/server.ts @@ -7,7 +7,7 @@ import { json, urlencoded } from 'body-parser' import cookieParser from 'cookie-parser' import express, { Express } from 'express' import { createServer, Server } from 'http' -import Knex from 'knex' +import { Knex } from 'knex' import { env } from './env' import * as Sentry from '@sentry/node' import * as lw from '@google-cloud/logging-winston' diff --git a/packages/api/src/services/save_file.ts b/packages/api/src/services/save_file.ts index da3e32f4f..64233aab6 100644 --- a/packages/api/src/services/save_file.ts +++ b/packages/api/src/services/save_file.ts @@ -1,4 +1,4 @@ -import Knex from 'knex' +import { Knex } from 'knex' import { PubsubClient } from '../datalayer/pubsub' import { UserData } from '../datalayer/user/model' import { homePageURL } from '../env' From e39a7cc16b9fef8d50e7e174526e042379040dd3 Mon Sep 17 00:00:00 2001 From: kristol07 Date: Mon, 6 Mar 2023 10:08:48 +0800 Subject: [PATCH 10/13] improve urlParse for puppeteer-parse --- packages/puppeteer-parse/index.js | 24 +++++++++++++++++++++--- 1 file changed, 21 insertions(+), 3 deletions(-) diff --git a/packages/puppeteer-parse/index.js b/packages/puppeteer-parse/index.js index a9da97977..f84b5534a 100644 --- a/packages/puppeteer-parse/index.js +++ b/packages/puppeteer-parse/index.js @@ -397,15 +397,33 @@ function validateUrlString(url) { } } +function tryParseUrl(urlStr) { + if (!urlStr) { + return null; + } + + // a regular expression to match URLs + var regex = /(https?:\/\/[^\s]+)/g; + + var match = regex.exec(urlStr); + + if (match) { + return match[1]; + } else { + return null; + } +} + function getUrl(req) { const urlStr = (req.query ? req.query.url : undefined) || (req.body ? req.body.url : undefined); - if (!urlStr) { + const url = tryParseUrl(urlStr) + if (!url) { throw new Error('No URL specified'); } - validateUrlString(urlStr); + validateUrlString(url); - const parsed = Url.parse(urlStr); + const parsed = Url.parse(url); return parsed.href; } From 1002e0baeb8f56cd47ecbe312432e9d9b8d29891 Mon Sep 17 00:00:00 2001 From: kristol07 Date: Tue, 7 Mar 2023 13:51:46 +0800 Subject: [PATCH 11/13] improve regex for url parse --- packages/puppeteer-parse/index.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/packages/puppeteer-parse/index.js b/packages/puppeteer-parse/index.js index f84b5534a..26dc7eef2 100644 --- a/packages/puppeteer-parse/index.js +++ b/packages/puppeteer-parse/index.js @@ -402,13 +402,13 @@ function tryParseUrl(urlStr) { return null; } - // a regular expression to match URLs - var regex = /(https?:\/\/[^\s]+)/g; + // a regular expression to match all URLs + const regex = /(https?:\/\/[^\s]+)/g; - var match = regex.exec(urlStr); + const matches = urlStr.match(regex); - if (match) { - return match[1]; + if (matches) { + return matches[0]; // only return first match } else { return null; } From 017c8f5f8ac2697902937e60fb8aabddc1668955 Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Tue, 7 Mar 2023 18:50:08 +0800 Subject: [PATCH 12/13] Forward Gmail verification email to the user --- packages/inbound-email-handler/src/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/inbound-email-handler/src/index.ts b/packages/inbound-email-handler/src/index.ts index 12e587e3c..adb44f4eb 100644 --- a/packages/inbound-email-handler/src/index.ts +++ b/packages/inbound-email-handler/src/index.ts @@ -141,7 +141,6 @@ export const inboundEmailHandler = Sentry.GCPFunction.wrapHttpFunction( if (isConfirmationEmail(from, subject)) { console.log('handleConfirmation', from) await handleConfirmation(to, subject) - return res.send('ok') } if (pdfAttachment) { @@ -187,6 +186,7 @@ export const inboundEmailHandler = Sentry.GCPFunction.wrapHttpFunction( receivedEmailId, }, }) + res.send('ok') } } catch (e) { console.log(e) From a1e3ac8a0791aa8ccc3f2eef893212997f8e014d Mon Sep 17 00:00:00 2001 From: Hongbo Wu Date: Wed, 8 Mar 2023 15:37:24 +0800 Subject: [PATCH 13/13] Add quote to the updateHighlightInput of the updateHighlight API --- packages/api/src/elastic/highlights.ts | 7 ++- packages/api/src/generated/graphql.ts | 1 + packages/api/src/generated/schema.graphql | 1 + packages/api/src/resolvers/highlight/index.ts | 11 ++--- packages/api/src/schema.ts | 3 +- packages/api/test/resolvers/highlight.test.ts | 47 ++++++++++++++----- 6 files changed, 44 insertions(+), 26 deletions(-) diff --git a/packages/api/src/elastic/highlights.ts b/packages/api/src/elastic/highlights.ts index 19564c80e..7a93338b4 100644 --- a/packages/api/src/elastic/highlights.ts +++ b/packages/api/src/elastic/highlights.ts @@ -254,7 +254,7 @@ export const updateHighlight = async ( ctx: PageContext ): Promise => { try { - const { body } = await client.updateByQuery({ + await client.updateByQuery({ index: INDEX_ALIAS, body: { script: { @@ -263,7 +263,7 @@ export const updateHighlight = async ( ctx._source.updatedAt = params.highlight.updatedAt`, lang: 'painless', params: { - highlight: highlight, + highlight, }, }, query: { @@ -289,10 +289,9 @@ export const updateHighlight = async ( }, }, refresh: ctx.refresh, + conflicts: 'proceed', }) - if (body.updated === 0) return false - await ctx.pubsub.entityUpdated( EntityType.HIGHLIGHT, highlight, diff --git a/packages/api/src/generated/graphql.ts b/packages/api/src/generated/graphql.ts index 4f1b91032..44c16e204 100644 --- a/packages/api/src/generated/graphql.ts +++ b/packages/api/src/generated/graphql.ts @@ -2714,6 +2714,7 @@ export enum UpdateHighlightErrorCode { export type UpdateHighlightInput = { annotation?: InputMaybe; highlightId: Scalars['ID']; + quote?: InputMaybe; sharedAt?: InputMaybe; }; diff --git a/packages/api/src/generated/schema.graphql b/packages/api/src/generated/schema.graphql index 7156d96ce..7c7b36037 100644 --- a/packages/api/src/generated/schema.graphql +++ b/packages/api/src/generated/schema.graphql @@ -2075,6 +2075,7 @@ enum UpdateHighlightErrorCode { input UpdateHighlightInput { annotation: String highlightId: ID! + quote: String sharedAt: Date } diff --git a/packages/api/src/resolvers/highlight/index.ts b/packages/api/src/resolvers/highlight/index.ts index 120554c86..55c2a7879 100644 --- a/packages/api/src/resolvers/highlight/index.ts +++ b/packages/api/src/resolvers/highlight/index.ts @@ -204,8 +204,7 @@ export const updateHighlightResolver = authorized< UpdateHighlightError, MutationUpdateHighlightArgs >(async (_, { input }, { pubsub, claims, log }) => { - const { highlightId } = input - const highlight = await getHighlightById(highlightId) + const highlight = await getHighlightById(input.highlightId) if (!highlight?.id) { return { @@ -219,20 +218,16 @@ export const updateHighlightResolver = authorized< } } - if (input.annotation && input.annotation.length > 4000) { - return { - errorCodes: [UpdateHighlightErrorCode.BadData], - } - } - // unescape HTML entities const annotation = input.annotation ? unescapeHtml(input.annotation) : undefined + const quote = input.quote ? unescapeHtml(input.quote) : highlight.quote const updatedHighlight: HighlightData = { ...highlight, annotation, + quote, updatedAt: new Date(), } diff --git a/packages/api/src/schema.ts b/packages/api/src/schema.ts index 4d3403066..1a1efa40d 100755 --- a/packages/api/src/schema.ts +++ b/packages/api/src/schema.ts @@ -748,8 +748,9 @@ const schema = gql` input UpdateHighlightInput { highlightId: ID! - annotation: String @sanitize + annotation: String @sanitize(maxLength: 4000) sharedAt: Date + quote: String @sanitize(maxLength: 6000) } type UpdateHighlightSuccess { diff --git a/packages/api/test/resolvers/highlight.test.ts b/packages/api/test/resolvers/highlight.test.ts index bd7a6d1dc..3a687c12a 100644 --- a/packages/api/test/resolvers/highlight.test.ts +++ b/packages/api/test/resolvers/highlight.test.ts @@ -104,23 +104,29 @@ const mergeHighlightQuery = ( ` } -const updateHighlightQuery = ( - authToken: string, - highlightId: string, - annotation = '_annotation' -) => { +const updateHighlightQuery = ({ + highlightId, + annotation = null, + quote = null, +}: { + highlightId: string + annotation?: string | null + quote?: string | null +}) => { return ` mutation { updateHighlight( input: { annotation: "${annotation}", highlightId: "${highlightId}", + quote: "${quote}" } ) { ... on UpdateHighlightSuccess { highlight { id annotation + quote } } ... on UpdateHighlightError { @@ -271,15 +277,30 @@ describe('Highlights API', () => { ) }) - context('when the annotation has HTML reserved characters', () => { - it('unescapes the annotation and updates', async () => { - const annotation = '> This is a test' - const query = updateHighlightQuery(authToken, highlightId, annotation) - const res = await graphqlRequest(query, authToken).expect(200) - expect(res.body.data.updateHighlight.highlight.annotation).to.eql( - '> This is a test' - ) + it('updates the quote when the quote is in HTML format when the annotation has HTML reserved characters', async () => { + const quote = '> This is a test' + const query = updateHighlightQuery({ highlightId, quote }) + const res = await graphqlRequest(query, authToken).expect(200) + expect(res.body.data.updateHighlight.highlight.quote).to.eql(quote) + }) + + it('updates the quote when the quote is in plain text format', async () => { + const quote = 'This is a test' + const query = updateHighlightQuery({ highlightId, quote }) + const res = await graphqlRequest(query, authToken).expect(200) + expect(res.body.data.updateHighlight.highlight.quote).to.eql(quote) + }) + + it('unescapes the annotation and updates the annotation when the annotation has HTML reserved characters', async () => { + const annotation = '> This is a test' + const query = updateHighlightQuery({ + highlightId, + annotation, }) + const res = await graphqlRequest(query, authToken).expect(200) + expect(res.body.data.updateHighlight.highlight.annotation).to.eql( + annotation + ) }) }) })