From 832d3dd98076e4799d50fb26e844e477edf69181 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Wed, 2 Nov 2022 05:33:28 +0000 Subject: [PATCH 01/19] chore(deps): update logto js sdk monorepo packages to v1.0.0-beta.12 --- packages/console/package.json | 2 +- packages/demo-app/package.json | 2 +- packages/integration-tests/package.json | 2 +- pnpm-lock.yaml | 34 ++++++++++++------------- 4 files changed, 20 insertions(+), 20 deletions(-) diff --git a/packages/console/package.json b/packages/console/package.json index 07e767f61..0eb6f0e5b 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -22,7 +22,7 @@ "@logto/language-kit": "1.0.0-beta.20", "@logto/phrases": "workspace:^", "@logto/phrases-ui": "workspace:^", - "@logto/react": "1.0.0-beta.11", + "@logto/react": "1.0.0-beta.12", "@logto/schemas": "workspace:^", "@mdx-js/react": "^1.6.22", "@parcel/core": "2.7.0", diff --git a/packages/demo-app/package.json b/packages/demo-app/package.json index 3aa49eb91..245754ce1 100644 --- a/packages/demo-app/package.json +++ b/packages/demo-app/package.json @@ -20,7 +20,7 @@ "@logto/core-kit": "1.0.0-beta.20", "@logto/language-kit": "1.0.0-beta.20", "@logto/phrases": "workspace:^", - "@logto/react": "1.0.0-beta.11", + "@logto/react": "1.0.0-beta.12", "@logto/schemas": "workspace:^", "@parcel/core": "2.7.0", "@parcel/transformer-sass": "2.7.0", diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index ae31215c1..92757976c 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -15,7 +15,7 @@ }, "devDependencies": { "@jest/types": "^29.1.2", - "@logto/node": "1.0.0-beta.11", + "@logto/node": "1.0.0-beta.12", "@logto/schemas": "workspace:^", "@peculiar/webcrypto": "^1.3.3", "@silverhand/eslint-config": "1.3.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 845cb4563..df45c4c9d 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -109,7 +109,7 @@ importers: '@logto/language-kit': 1.0.0-beta.20 '@logto/phrases': workspace:^ '@logto/phrases-ui': workspace:^ - '@logto/react': 1.0.0-beta.11 + '@logto/react': 1.0.0-beta.12 '@logto/schemas': workspace:^ '@mdx-js/react': ^1.6.22 '@parcel/core': 2.7.0 @@ -176,7 +176,7 @@ importers: '@logto/language-kit': 1.0.0-beta.20 '@logto/phrases': link:../phrases '@logto/phrases-ui': link:../phrases-ui - '@logto/react': 1.0.0-beta.11_react@18.2.0 + '@logto/react': 1.0.0-beta.12_react@18.2.0 '@logto/schemas': link:../schemas '@mdx-js/react': 1.6.22_react@18.2.0 '@parcel/core': 2.7.0 @@ -408,7 +408,7 @@ importers: '@logto/core-kit': 1.0.0-beta.20 '@logto/language-kit': 1.0.0-beta.20 '@logto/phrases': workspace:^ - '@logto/react': 1.0.0-beta.11 + '@logto/react': 1.0.0-beta.12 '@logto/schemas': workspace:^ '@parcel/core': 2.7.0 '@parcel/transformer-sass': 2.7.0 @@ -435,7 +435,7 @@ importers: '@logto/core-kit': 1.0.0-beta.20 '@logto/language-kit': 1.0.0-beta.20 '@logto/phrases': link:../phrases - '@logto/react': 1.0.0-beta.11_react@18.2.0 + '@logto/react': 1.0.0-beta.12_react@18.2.0 '@logto/schemas': link:../schemas '@parcel/core': 2.7.0 '@parcel/transformer-sass': 2.7.0_@parcel+core@2.7.0 @@ -462,7 +462,7 @@ importers: packages/integration-tests: specifiers: '@jest/types': ^29.1.2 - '@logto/node': 1.0.0-beta.11 + '@logto/node': 1.0.0-beta.12 '@logto/schemas': workspace:^ '@peculiar/webcrypto': ^1.3.3 '@silverhand/eslint-config': 1.3.0 @@ -487,7 +487,7 @@ importers: typescript: ^4.7.4 devDependencies: '@jest/types': 29.1.2 - '@logto/node': 1.0.0-beta.11 + '@logto/node': 1.0.0-beta.12 '@logto/schemas': link:../schemas '@peculiar/webcrypto': 1.3.3 '@silverhand/eslint-config': 1.3.0_swk2g7ygmfleszo5c33j4vooni @@ -2293,16 +2293,16 @@ packages: dev: true optional: true - /@logto/browser/1.0.0-beta.11: - resolution: {integrity: sha512-Ofdj5UqLzwoW66XGnff+1U6Lix90qI2Q30+TISJz6soCm97oqJdWpY2SRlMAfnvDobsFPqAxyCAz49Cg16h50Q==} + /@logto/browser/1.0.0-beta.12: + resolution: {integrity: sha512-ImlZ/+fcBEhz8F3QqhQU1HXYjJwA+3hJIqGzcYDUeLvAeMIY7gP1N/RtXauacaeh+F0UfpoKeoD45Q3EedHOwA==} dependencies: - '@logto/client': 1.0.0-beta.11 + '@logto/client': 1.0.0-beta.12 '@silverhand/essentials': 1.3.0 js-base64: 3.7.2 dev: true - /@logto/client/1.0.0-beta.11: - resolution: {integrity: sha512-7Nl+53JPgB0wjMU9zJH6SrOj4OKn0Kl9U1cumt/IHSYuaDyV7TgvR/HaaeSZuZ0JxbMg66Riee87Qx9Tv46k6A==} + /@logto/client/1.0.0-beta.12: + resolution: {integrity: sha512-9u5uHqKYv7uq85lfX+EkytYnks0fQexO/vRt6/kz74DC5CqFdJPYHu4njbJyAYB8rCQoiB/Bbw1RGIC5AyRWLA==} dependencies: '@logto/core-kit': 1.0.0-beta.20 '@logto/js': 1.0.0-beta.11 @@ -2358,10 +2358,10 @@ packages: dependencies: zod: 3.19.1 - /@logto/node/1.0.0-beta.11: - resolution: {integrity: sha512-nsa9RtrzBRmLMJNeNzutJ72bLwZpGUr4lhBAze7YXJi6o9ujvZOLgdvZAZeoSdxxBhTilwbDWNXmj8n3Ndavaw==} + /@logto/node/1.0.0-beta.12: + resolution: {integrity: sha512-SA2H2JH5S5mXZyBPR79Z9U4zYZDXHijqYpreDdSd5abjMu0g+rq00Ht80TwYby2vCj/a4GV/OUew7jzGh3lwlw==} dependencies: - '@logto/client': 1.0.0-beta.11 + '@logto/client': 1.0.0-beta.12 '@silverhand/essentials': 1.3.0 js-base64: 3.7.2 node-fetch: 2.6.7 @@ -2369,12 +2369,12 @@ packages: - encoding dev: true - /@logto/react/1.0.0-beta.11_react@18.2.0: - resolution: {integrity: sha512-W9L1QrJml4tHlrUkmdaJRsj4ln+SgwGAeyF+QhmKBq5CoSR+EauE63ySLhPn2KFVrc3m/sioejJIVy+1sUe21w==} + /@logto/react/1.0.0-beta.12_react@18.2.0: + resolution: {integrity: sha512-8LOAZx7+zs+Uyr/ciudtjiiXVimxrydodRscQGFx+PQcbie/efVOijwbLrHDrBzB4cjmgSvdFnBH/2z9Tpiz0g==} peerDependencies: react: '>=16.8.0 || ^18.0.0' dependencies: - '@logto/browser': 1.0.0-beta.11 + '@logto/browser': 1.0.0-beta.12 '@silverhand/essentials': 1.3.0 react: 18.2.0 dev: true From 492ce312be0ec9e65973f10c90c21ab5a689f881 Mon Sep 17 00:00:00 2001 From: Lukas Date: Thu, 3 Nov 2022 10:16:44 +0100 Subject: [PATCH 02/19] feat(phrases): add german language (#2053) --- packages/phrases-ui/src/index.ts | 8 +- packages/phrases-ui/src/locales/de.ts | 90 +++++++++++ packages/phrases/src/index.ts | 8 +- packages/phrases/src/locales/de/errors.ts | 133 +++++++++++++++++ packages/phrases/src/locales/de/index.ts | 10 ++ .../admin-console/api-resource-details.ts | 11 ++ .../admin-console/api-resources.ts | 14 ++ .../admin-console/application-details.ts | 44 ++++++ .../translation/admin-console/applications.ts | 50 +++++++ .../admin-console/connector-details.ts | 22 +++ .../translation/admin-console/connectors.ts | 37 +++++ .../de/translation/admin-console/contact.ts | 22 +++ .../de/translation/admin-console/dashboard.ts | 22 +++ .../de/translation/admin-console/errors.ts | 21 +++ .../de/translation/admin-console/general.ts | 42 ++++++ .../translation/admin-console/get-started.ts | 29 ++++ .../de/translation/admin-console/index.ts | 52 +++++++ .../translation/admin-console/log-details.ts | 17 +++ .../de/translation/admin-console/logs.ts | 12 ++ .../admin-console/session-expired.ts | 8 + .../de/translation/admin-console/settings.ts | 27 ++++ .../translation/admin-console/sign-in-exp.ts | 140 ++++++++++++++++++ .../translation/admin-console/tab-sections.ts | 8 + .../de/translation/admin-console/tabs.ts | 15 ++ .../translation/admin-console/user-details.ts | 41 +++++ .../de/translation/admin-console/users.ts | 15 ++ .../de/translation/admin-console/welcome.ts | 8 + .../src/locales/de/translation/demo-app.ts | 15 ++ .../src/locales/de/translation/index.ts | 9 ++ 29 files changed, 924 insertions(+), 6 deletions(-) create mode 100644 packages/phrases-ui/src/locales/de.ts create mode 100644 packages/phrases/src/locales/de/errors.ts create mode 100644 packages/phrases/src/locales/de/index.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/api-resource-details.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/api-resources.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/application-details.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/applications.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/connector-details.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/connectors.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/contact.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/dashboard.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/errors.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/general.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/get-started.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/index.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/log-details.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/logs.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/session-expired.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/settings.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/sign-in-exp.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/tab-sections.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/tabs.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/user-details.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/users.ts create mode 100644 packages/phrases/src/locales/de/translation/admin-console/welcome.ts create mode 100644 packages/phrases/src/locales/de/translation/demo-app.ts create mode 100644 packages/phrases/src/locales/de/translation/index.ts diff --git a/packages/phrases-ui/src/index.ts b/packages/phrases-ui/src/index.ts index 792000a91..247666d59 100644 --- a/packages/phrases-ui/src/index.ts +++ b/packages/phrases-ui/src/index.ts @@ -4,6 +4,7 @@ import { languages } from '@logto/language-kit'; import type { NormalizeKeyPaths } from '@silverhand/essentials'; import { z } from 'zod'; +import de from './locales/de'; import en from './locales/en'; import fr from './locales/fr'; import ko from './locales/ko'; @@ -16,7 +17,7 @@ export type { LocalePhrase } from './types'; export type I18nKey = NormalizeKeyPaths; -export const builtInLanguages = ['en', 'fr', 'pt-PT', 'zh-CN', 'ko', 'tr-TR'] as const; +export const builtInLanguages = ['de', 'en', 'fr', 'ko', 'pt-PT', 'tr-TR', 'zh-CN'] as const; export const builtInLanguageOptions = builtInLanguages.map((languageTag) => ({ value: languageTag, @@ -30,12 +31,13 @@ export type BuiltInLanguageTag = z.infer; export type Resource = Record; const resource: Resource = { + de, en, fr, - 'pt-PT': ptPT, - 'zh-CN': zhCN, ko, + 'pt-PT': ptPT, 'tr-TR': trTR, + 'zh-CN': zhCN, }; export const getDefaultLanguageTag = (language: string): LanguageTag => diff --git a/packages/phrases-ui/src/locales/de.ts b/packages/phrases-ui/src/locales/de.ts new file mode 100644 index 000000000..406787485 --- /dev/null +++ b/packages/phrases-ui/src/locales/de.ts @@ -0,0 +1,90 @@ +import type { LocalePhrase } from '../types'; + +const translation = { + input: { + username: 'Benutzername', + password: 'Passwort', + email: 'Email', + phone_number: 'Telefonnummer', + confirm_password: 'Passwort bestätigen', + }, + secondary: { + sign_in_with: 'Anmelden mit {{methods, list(type: disjunction;)}}', + social_bind_with: + 'Besitzt du schon ein Konto? Melde dich an, um {{methods, list(type: disjunction;)}} mit deiner Identität zu verbinden.', + }, + action: { + sign_in: 'Anmelden', + continue: 'Weiter', + create_account: 'Konto erstellen', + create: 'Erstellen', + enter_passcode: 'Bestätigungscode eingeben', + confirm: 'Bestätigen', + cancel: 'Abbrechen', + save_password: 'Speichern', + bind: 'Mit {{address}} verknüpfen', + back: 'Gehe zurück', + nav_back: 'Zurück', + agree: 'Zustimmen', + got_it: 'Alles klar', + sign_in_with: 'Mit {{name}} anmelden', + forgot_password: 'Passwort vergessen?', + switch_to: 'Zu {{method}} wechseln', + }, + description: { + email: 'Email', + phone_number: 'Telefonnummer', + reminder: 'Erinnerung', + not_found: '404 Nicht gefunden', + agree_with_terms: 'Ich akzeptiere die ', + agree_with_terms_modal: 'Bitte akzeptiere die .', + terms_of_use: 'Nutzungsbedingungen', + create_account: 'Konto erstellen', + or: 'oder', + enter_passcode: 'Der Bestätigungscode wurde an deine {{address}} gesendet', + passcode_sent: 'Der Bestätigungscode wurde erneut gesendet', + resend_after_seconds: 'Nach {{seconds}} Sekunden erneut senden', + resend_passcode: 'Bestätigungscode erneut senden', + continue_with: 'Weiter mit', + create_account_id_exists: + 'Das Konto mit {{type}} {{value}} existiert bereits, möchtest du dich anmelden?', + sign_in_id_does_not_exists: + 'Das Konto mit {{type}} {{value}} existiert nicht, möchtest du ein neues Konto erstellen?', + forgot_password_id_does_not_exits: 'Das Konto mit {{type}} {{value}} existiert nicht.', + bind_account_title: 'Konto verknüpfen', + social_create_account: 'Kein Konto? Du kannst ein neues Konto erstellen und es verknüpfen.', + social_bind_account: + 'Besitzt du schon ein Konto? Melde dich an, um die Identität zu verknüpfen.', + social_bind_with_existing: 'Wir haben ein Konto gefunden, das du verknüpfen kannst.', + reset_password: 'Passwort zurücksetzen', + reset_password_description_email: + 'Gib die Email Adresse deines Kontos ein und wir senden dir einen Bestätigungscode um dein Passwort zurückzusetzen.', + reset_password_description_sms: + 'Gib die Telefonnummer deines Kontos ein und wir senden dir einen Bestätigungscode um dein Passwort zurückzusetzen.', + new_password: 'Neues Passwort', + password_changed: 'Passwort geändert', + }, + error: { + username_password_mismatch: 'Benutzername oder Passwort ist falsch', + username_required: 'Benutzername ist erforderlich', + password_required: 'Passwort ist erforderlich', + username_exists: 'Benutzername existiert bereits', + username_should_not_start_with_number: 'Benutzername darf nicht mit einer Zahl beginnen', + username_valid_charset: 'Benutzername darf nur Buchstaben, Zahlen und Unterstriche enthalten', + invalid_email: 'Die Email ist ungültig', + invalid_phone: 'Die Telefonnummer ist ungültig', + password_min_length: 'Passwort muss mindestens {{min}} Zeichen lang sein', + passwords_do_not_match: 'Passwörter stimmen nicht überein', + invalid_passcode: 'Der Bestätigungscode ist ungültig', + invalid_connector_auth: 'Die Autorisierung ist ungültig', + invalid_connector_request: 'Connector Daten sind ungültig', + unknown: 'Unbekannter Fehler. Versuche es später noch einmal.', + invalid_session: 'Die Sitzung ist ungültig. Bitte melde dich erneut an.', + }, +}; + +const de: LocalePhrase = Object.freeze({ + translation, +}); + +export default de; diff --git a/packages/phrases/src/index.ts b/packages/phrases/src/index.ts index 33f9efeaf..e8a821620 100644 --- a/packages/phrases/src/index.ts +++ b/packages/phrases/src/index.ts @@ -4,6 +4,7 @@ import { languages } from '@logto/language-kit'; import type { NormalizeKeyPaths } from '@silverhand/essentials'; import { z } from 'zod'; +import de from './locales/de'; import en from './locales/en'; import fr from './locales/fr'; import ko from './locales/ko'; @@ -16,7 +17,7 @@ export type { LocalPhrase } from './types'; export type I18nKey = NormalizeKeyPaths; -export const builtInLanguages = ['en', 'fr', 'pt-PT', 'zh-CN', 'ko', 'tr-TR'] as const; +export const builtInLanguages = ['de', 'en', 'fr', 'ko', 'pt-PT', 'tr-TR', 'zh-CN'] as const; export const builtInLanguageOptions = builtInLanguages.map((languageTag) => ({ value: languageTag, @@ -42,12 +43,13 @@ export const isBuiltInLanguageTag = (language: string): language is BuiltInLangu export type Resource = Record; const resource: Resource = { + de, en, fr, - 'pt-PT': ptPT, - 'zh-CN': zhCN, ko, + 'pt-PT': ptPT, 'tr-TR': trTR, + 'zh-CN': zhCN, }; export default resource; diff --git a/packages/phrases/src/locales/de/errors.ts b/packages/phrases/src/locales/de/errors.ts new file mode 100644 index 000000000..5cf6d8303 --- /dev/null +++ b/packages/phrases/src/locales/de/errors.ts @@ -0,0 +1,133 @@ +const errors = { + auth: { + authorization_header_missing: 'Autorisierungs-Header fehlt.', + authorization_token_type_not_supported: 'Autorisierungs-Typ wird nicht unterstützt.', + unauthorized: 'Unautorisiert. Bitte überprüfe deine Zugangsdaten.', + forbidden: 'Verboten. Bitte überprüfe deine Rollen und Berechtigungen.', + expected_role_not_found: + 'Erwartete Rolle nicht gefunden. Bitte überprüfe deine Rollen und Berechtigungen.', + jwt_sub_missing: '`sub` fehlt in JWT.', + }, + guard: { + invalid_input: 'Die Anfrage {{type}} ist ungültig.', + invalid_pagination: 'Die Paginierung der Anfrage ist ungültig.', + }, + oidc: { + aborted: 'Der Endnutzer hat die Interaktion abgebrochen.', + invalid_scope: 'Scope {{scope}} wird nicht unterstützt.', + invalid_scope_plural: 'Scopes {{scopes}} werden nicht unterstützt.', + invalid_token: 'Ungültiger Token übermittelt.', + invalid_client_metadata: 'Ungültige Client Metadaten übermittelt.', + insufficient_scope: 'Access token fehlen angefragte scope {{scopes}}.', + invalid_request: 'Anfrage ist ungültig.', + invalid_grant: 'Grant request ist ungültig.', + invalid_redirect_uri: + '`redirect_uri` stimmt nicht mit den registrierten `redirect_uris` des Clients überein.', + access_denied: 'Zugang verweigert.', + invalid_target: 'Ungültiger resource indicator.', + unsupported_grant_type: 'Nicht unterstützter `grant_type` angefragt.', + unsupported_response_mode: 'Nicht unterstützter `response_mode` angefragt.', + unsupported_response_type: 'Nicht unterstützter `response_type` angefragt.', + provider_error: 'OIDC interner Fehler: {{message}}.', + }, + user: { + username_exists_register: 'Der Benutzername wurde registriert.', + email_exists_register: 'Die E-Mail wurde registriert.', + phone_exists_register: 'Die Telefonnummer wurde registriert.', + invalid_email: 'Ungültige E-Mail.', + invalid_phone: 'Ungültige Telefonnummer.', + email_not_exists: 'Die E-Mail wurde noch nicht registriert.', + phone_not_exists: 'Die Telefonnummer wurde noch nicht registriert.', + identity_not_exists: 'Die Identität wurde noch nicht registriert.', + identity_exists: 'Die Identität wurde registriert.', + invalid_role_names: 'Rollennamen ({{roleNames}}) sind ungültig', + cannot_delete_self: 'Du kannst dich nicht selbst löschen.', + same_password: 'Das neue Passwort muss sich vom alten unterscheiden.', + }, + password: { + unsupported_encryption_method: 'Die Verschlüsselungsmethode {{name}} wird nicht unterstützt.', + pepper_not_found: 'Password pepper not found. Please check your core envs.', + }, + session: { + not_found: 'Sitzung nicht gefunden. Bitte melde dich erneut an.', + invalid_credentials: 'Ungültige Zugangsdaten. Überprüfe deine Eingaben.', + invalid_sign_in_method: 'Aktuelle Anmeldemethode ist ungültig.', + invalid_connector_id: 'Connector mit ID {{connectorId}} wurde nicht gefunden.', + insufficient_info: 'Unzureichende Informationen für die Anmeldung.', + connector_id_mismatch: 'Connector ID stimmt nicht mit Sitzung überein.', + connector_session_not_found: 'Connector Sitzung nicht gefunden. Bitte melde dich erneut an.', + verification_session_not_found: + 'Die Verifizierung war nicht erfolgreich. Starte die Verifizierung neu und versuche es erneut.', + verification_expired: + 'Die Verbindung wurde unterbrochen. Verifiziere erneut, um die Sicherheit deines Kontos zu gewährleisten.', + unauthorized: 'Bitte melde dich erst an.', + unsupported_prompt_name: 'Nicht unterstützter prompt Name.', + }, + connector: { + // UNTRANSLATED + general: 'An unexpected error occurred in connector.{{errorDescription}}', + not_found: 'Cannot find any available connector for type: {{type}}.', + not_enabled: 'The connector is not enabled.', + invalid_metadata: "The connector's metadata is invalid.", + invalid_config_guard: "The connector's config guard is invalid.", + unexpected_type: "The connector's type is unexpected.", + invalid_request_parameters: 'The request is with wrong input parameter(s).', + insufficient_request_parameters: 'The request might miss some input parameters.', + invalid_config: "The connector's config is invalid.", + invalid_response: "The connector's response is invalid.", + template_not_found: 'Unable to find correct template in connector config.', + not_implemented: '{{method}}: has not been implemented yet.', + social_invalid_access_token: "The connector's access token is invalid.", + invalid_auth_code: "The connector's auth code is invalid.", + social_invalid_id_token: "The connector's id token is invalid.", + authorization_failed: "The user's authorization process is unsuccessful.", + social_auth_code_invalid: 'Unable to get access token, please check authorization code.', + more_than_one_sms: 'The number of SMS connectors is larger then 1.', + more_than_one_email: 'The number of Email connectors is larger then 1.', + db_connector_type_mismatch: 'There is a connector in the DB that does not match the type.', + }, + passcode: { + phone_email_empty: 'Telefonnummer oder E-Mail darf nicht leer sein.', + not_found: 'Passcode nicht gefunden. Bitte sende erst einen Passcode.', + phone_mismatch: + 'Telefonnummer stimmt nicht mit Passcode überein. Frage einen neuen Passcode an.', + email_mismatch: 'E-Mail stimmt nicht mit Passcode überein. Frage einen neuen Passcode an.', + code_mismatch: 'Ungültiger Passcode.', + expired: 'Passcode ist abgelaufen. Frage einen neuen Passcode an.', + exceed_max_try: 'Passcode wurde zu oft versucht. Frage einen neuen Passcode an.', + }, + sign_in_experiences: { + empty_content_url_of_terms_of_use: + 'Leere "Nutzungsbedingungen" URL. Bitte füge die URL hinzu, wenn "Nutzungsbedingungen" aktiviert ist.', + empty_logo: 'Bitte füge eine Logo URL hinzu.', + empty_slogan: + 'Leerer Branding-Slogan. Bitte füge einen Branding-Slogan hinzu, wenn ein UI-Stil ausgewählt wird, der den Slogan enthält.', + empty_social_connectors: + 'Leere Social Connectors. Bitte füge aktivierte Social Connectoren hinzu, wenn Social Anmeldung aktiviert ist.', + enabled_connector_not_found: 'Aktivierter {{type}} Connector nicht gefunden.', + not_one_and_only_one_primary_sign_in_method: + 'Es darf nur eine primäre Anmeldemethode geben. Bitte überprüfe deine Eingabe.', + unsupported_default_language: 'Die Sprache - {{language}} wird momentan nicht unterstützt.', + }, + localization: { + cannot_delete_default_language: + '{{languageTag}} ist die Standard-Sprache und kann nicht gelöscht werden.', + invalid_translation_structure: 'Ungültige Übersetzungsstruktur. Bitte überprüfe deine Eingabe.', + }, + swagger: { + invalid_zod_type: 'Ungültiger Zod Typ. Überprüfe deine route guard Konfiguration.', + not_supported_zod_type_for_params: + 'Nicht unterstützter Zod Typ für diese Parameter. Überprüfe deine route guard Konfiguration.', + }, + entity: { + create_failed: 'Fehler beim erstellen von {{name}}.', + not_exists: '{{name}} existiert nicht.', + not_exists_with_id: '{{name}} mit ID `{{id}}` existiert nicht.', + not_found: 'Die Ressource wurde nicht gefunden.', + }, + log: { + invalid_type: 'Der Log Typ ist ungültig.', + }, +}; + +export default errors; diff --git a/packages/phrases/src/locales/de/index.ts b/packages/phrases/src/locales/de/index.ts new file mode 100644 index 000000000..10ea8ed97 --- /dev/null +++ b/packages/phrases/src/locales/de/index.ts @@ -0,0 +1,10 @@ +import type { LocalPhrase } from '../../types'; +import errors from './errors'; +import translation from './translation'; + +const de: LocalPhrase = Object.freeze({ + translation, + errors, +}); + +export default de; diff --git a/packages/phrases/src/locales/de/translation/admin-console/api-resource-details.ts b/packages/phrases/src/locales/de/translation/admin-console/api-resource-details.ts new file mode 100644 index 000000000..900414932 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/api-resource-details.ts @@ -0,0 +1,11 @@ +const api_resource_details = { + back_to_api_resources: 'Zurück zu API Ressourcen', + token_expiration_time_in_seconds: 'Token Ablaufzeit (in Sekunden)', + token_expiration_time_in_seconds_placeholder: 'Gib die Ablaufzeit des Tokens ein', + delete_description: + 'Diese Aktion kann nicht rückgängig gemacht werden. Die API Ressource wird permanent gelöscht. Bitte gib den API Ressourcennamen {{name}} zur Bestätigung ein.', + enter_your_api_resource_name: 'Gib einen API Ressourcennamen ein', + api_resource_deleted: 'Die API Ressource {{name}} wurde erfolgreich gelöscht', +}; + +export default api_resource_details; diff --git a/packages/phrases/src/locales/de/translation/admin-console/api-resources.ts b/packages/phrases/src/locales/de/translation/admin-console/api-resources.ts new file mode 100644 index 000000000..b15b5094d --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/api-resources.ts @@ -0,0 +1,14 @@ +const api_resources = { + title: 'API Ressourcen', + subtitle: 'Lege APIs an, die du in deinen autorisierten Anwendungen verwenden kannst', + create: 'Erstelle API Ressource', + api_name: 'API Name', + api_name_placeholder: 'Gib einen API Namen ein', + api_identifier: 'API Identifikator', + api_identifier_tip: + 'Der eindeutige Identifikator der API Ressource muss eine absolute URI ohne Fragmentbezeichner (#) sein. Entspricht dem Ressourcen Parameter in OAuth 2.0.', + api_resource_created: 'Die API Ressource {{name}} wurde erfolgreich angelegt', + api_identifier_placeholder: 'https://dein-api-identifikator/', +}; + +export default api_resources; diff --git a/packages/phrases/src/locales/de/translation/admin-console/application-details.ts b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts new file mode 100644 index 000000000..1311893ab --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/application-details.ts @@ -0,0 +1,44 @@ +const application_details = { + back_to_applications: 'Zurück zu Anwendungen', + check_guide: 'Zur Anleitung', + advanced_settings: 'Erweiterte Einstellungen', + application_name: 'Anwendungsname', + application_name_placeholder: 'Meine App', + description: 'Beschreibung', + description_placeholder: 'Gib eine Beschreibung ein', + authorization_endpoint: 'Autorisierungs-Endpoint', + authorization_endpoint_tip: + 'Der Endpoint, der für die Authentifizierung und Autorisierung via OpenID Connect verwendet wird.', + application_id: 'App ID', + application_secret: 'App Geheimnis', + redirect_uri: 'Umleitungs-URI', + redirect_uris: 'Umleitungs-URIs', + redirect_uri_placeholder: 'https://deine.website.de/app', + redirect_uri_placeholder_native: 'io.logto://callback', + redirect_uri_tip: + 'URI zu der der Benutzer nach der Anmeldung (egal ob erfolgreich oder nicht) weitergeleitet wird. See OpenID Connect AuthRequest for more info.', + post_sign_out_redirect_uri: 'Post Sign-out Umleitungs-URI', + post_sign_out_redirect_uris: 'Post Sign-out Umleitungs-URIs', + post_sign_out_redirect_uri_placeholder: 'https://deine.website.de/home', + post_sign_out_redirect_uri_tip: + 'URI zu der der Benutzer nach dem Abmelden weitergeleitet wird (optional). Hat bei einigen Anwendungstypen keine Auswirkungen.', + cors_allowed_origins: 'CORS allowed origins', + cors_allowed_origins_placeholder: 'https://your.website.de', + cors_allowed_origins_tip: + 'Es sind standardmäßig alle Umleitungs-URI Origins erlaubt. Normalerweise ist dieses Feld nicht erforderlich.', + add_another: 'Weitere hinzufügen', + id_token_expiration: 'ID Token Ablaufzeit', + refresh_token_expiration: 'Refresh Token Ablaufzeit', + token_endpoint: 'Token Endpoint', + user_info_endpoint: 'Benutzerinformations-Endpoint', + enable_admin_access: 'Admin-Zugang aktivieren', + enable_admin_access_label: + 'Zugang zur Management API aktivieren oder deaktivieren. Falls aktiviert, können access tokens verwendet werden, um die Management API im Namen der Anwendung aufzurufen.', + delete_description: + 'Diese Aktion kann nicht rückgängig gemacht werden. Die Anwendung wird permanent gelöscht. Bitte gib den Anwendungsnamen {{name}} zur Bestätigung ein.', + enter_your_application_name: 'Gib einen Anwendungsnamen ein', + application_deleted: 'Anwendung {{name}} wurde erfolgreich gelöscht', + redirect_uri_required: 'Gebe mindestens eine Umleitungs-URI an', +}; + +export default application_details; diff --git a/packages/phrases/src/locales/de/translation/admin-console/applications.ts b/packages/phrases/src/locales/de/translation/admin-console/applications.ts new file mode 100644 index 000000000..a5539a1ad --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/applications.ts @@ -0,0 +1,50 @@ +const applications = { + title: 'Anwendungen', + subtitle: + 'Richte eine native, Single Page oder herkömmliche Anwendung ein, die Logto zur Authentifizierung nutzt.', + create: 'Anwendung erstellen', + application_name: 'Anwendungsname', + application_name_placeholder: 'Meine App', + application_description: 'Anwendungsbeschreibung', + application_description_placeholder: 'Gib eine Beschreibung ein', + select_application_type: 'Wähle einen Anwendungstyp', + no_application_type_selected: 'Du hast noch keinen Anwendungstyp ausgewählt', + application_created: + 'Die Anwendung {{name}} wurde erfolgreich erstellt! \nKonfiguriere jetzt die Anwendung.', + app_id: 'App ID', + type: { + native: { + title: 'Native App', + subtitle: 'Eine Anwendung, die in einer nativen Umgebung läuft', + description: 'z.B. iOS app, Android app', + }, + spa: { + title: 'Single Page App', + subtitle: + 'Eine Anwendung, die in einem Webbrowser ausgeführt wird und Daten dynamisch an Ort und Stelle aktualisiert', + description: 'z.B. React DOM app, Vue app', + }, + traditional: { + title: 'Herkömmliche Website', + subtitle: 'Eine Anwendung, die Seiten allein durch den Webserver rendert und aktualisiert', + description: 'z.B. Next.js, PHP', + }, + machine_to_machine: { + title: 'Machine to Machine', + subtitle: 'Eine Anwendung (normalerweise ein Dienst), die direkt mit Ressourcen kommuniziert', + description: 'z.B. Backend Dienst', + }, + }, + guide: { + get_sample_file: 'Zum Beispielprojekt', + header_description: + 'Folge der Schritt-für-Schritt-Anleitung, um die Anwendung zu integrieren, oder klick auf die rechte Schaltfläche, um unser Beispielprojekt zu erhalten', + title: 'Die Anwendung wurde erfolgreich erstellt', + subtitle: + 'Folge nun den folgenden Schritten, um deine App-Einstellungen abzuschließen. Bitte wähle den SDK-Typ aus, um fortzufahren.', + description_by_sdk: + 'Diese Schnellstart-Anleitung zeigt, wie man Logto in die {{sdk}} App integriert', + }, +}; + +export default applications; diff --git a/packages/phrases/src/locales/de/translation/admin-console/connector-details.ts b/packages/phrases/src/locales/de/translation/admin-console/connector-details.ts new file mode 100644 index 000000000..4a67369ad --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/connector-details.ts @@ -0,0 +1,22 @@ +const connector_details = { + back_to_connectors: 'Zurück zu Connectoren', + check_readme: 'Zur README', + save_error_empty_config: 'Bitte fülle die Konfiguration aus', + send: 'Senden', + send_error_invalid_format: 'Ungültige Eingabe', + edit_config_label: 'Gib deine JSON-Konfiguration ein', + test_email_sender: 'Teste den E-Mail Connector', + test_sms_sender: 'Teste den SMS Connector', + test_email_placeholder: 'Gib eine Test-E-Mail ein', + test_sms_placeholder: 'Gib eine Test-Telefonnummer ein', + test_message_sent: 'Testnachricht wurde gesendet!', + test_sender_description: 'Wenn dein JSON richtig konfiguriert ist, erhältst du eine Nachricht.', + options_change_email: 'E-Mail Connector bearbeiten', + options_change_sms: 'SMS Connector bearbeiten', + connector_deleted: 'Der Connector wurde erfolgreich gelöscht', + type_email: 'E-Mail connector', + type_sms: 'SMS connector', + type_social: 'Social connector', +}; + +export default connector_details; diff --git a/packages/phrases/src/locales/de/translation/admin-console/connectors.ts b/packages/phrases/src/locales/de/translation/admin-console/connectors.ts new file mode 100644 index 000000000..bbfb6c758 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/connectors.ts @@ -0,0 +1,37 @@ +const connectors = { + title: 'Connectoren', + subtitle: 'Richte Connectoren ein um passwortlose und Social Anmeldung zu aktivieren', + create: 'Social Connector erstellen', + tab_email_sms: 'E-Mail und SMS Connectoren', + tab_social: 'Social Connectoren', + connector_name: 'Connectorname', + connector_type: 'Typ', + connector_status: 'Anmeldeoberfläche', + connector_status_in_use: 'In Benutzung', + connector_status_not_in_use: 'Nicht in Benutzung', + social_connector_eg: 'z.B. Google, Facebook, Github', + save_and_done: 'Speichern und fertigstellen', + type: { + email: 'E-Mail Connector', + sms: 'SMS Connector', + social: 'Social Connector', + }, + setup_title: { + email: 'E-Mail Connector einrichten', + sms: 'SMS Connector einrichten', + social: 'Social Connector erstellen', + }, + guide: { + subtitle: 'Eine Schritt-für-Schritt-Anleitung zur Konfiguration deines Connectors', + }, + platform: { + universal: 'Universal', + web: 'Web', + native: 'Nativ', + }, + add_multi_platform: ' unterstützt mehrere Plattformen, wähle eine Plattform aus, um fortzufahren', + drawer_title: 'Connector Anleitung', + drawer_subtitle: 'Folge den Anweisungen, um deinen Connector zu integrieren', +}; + +export default connectors; diff --git a/packages/phrases/src/locales/de/translation/admin-console/contact.ts b/packages/phrases/src/locales/de/translation/admin-console/contact.ts new file mode 100644 index 000000000..f73339731 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/contact.ts @@ -0,0 +1,22 @@ +const contact = { + title: 'Kontakt', + description: + 'Tritt unserer Community bei, um Feedback zu geben, um Hilfe zu bitten und deine Gedanken mit anderen Entwicklern zu teilen', + discord: { + title: 'Discord channel', + description: 'Tritt unserem öffentlichen Kanal bei, um mit anderen Entwicklern zu chatten', + button: 'Beitreten', + }, + github: { + title: 'GitHub', + description: 'Erstelle ein Issue bei GitHub', + button: 'Öffnen', + }, + email: { + title: 'E-Mail senden', + description: 'Schick uns eine E-Mail für weitere Informationen und Hilfe', + button: 'Senden', + }, +}; + +export default contact; diff --git a/packages/phrases/src/locales/de/translation/admin-console/dashboard.ts b/packages/phrases/src/locales/de/translation/admin-console/dashboard.ts new file mode 100644 index 000000000..733900244 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/dashboard.ts @@ -0,0 +1,22 @@ +const dashboard = { + title: 'Dashboard', + description: 'Verschaffe dir einen Überblick über die Leistung deiner App', + total_users: 'Gesamtzahl der Benutzer', + total_users_tip: 'Gesamtzahl der Benutzer', + new_users_today: 'Neue Benutzer heute', + new_users_today_tip: 'Neue Benutzer, die sich heute in deinen Anwendungen registriert haben', + new_users_7_days: 'Neue Benutzer in den letzten 7 Tagen', + new_users_7_days_tip: + 'Neue Benutzer, die sich in den letzten 7 Tagen in deinen Anwendungen registriert haben', + daily_active_users: 'Täglich aktive Benutzer', + daily_active_users_tip: + 'Die Anzahl der einzelnen Benutzer, die heute Token in deinen Anwendungen ausgetauscht haben', + weekly_active_users: 'Wöchentlich aktive Benutzer', + weekly_active_users_tip: + 'Die Anzahl der einzelnen Benutzer, die in den letzten 7 Tagen Token in deinen Anwendungen ausgetauscht haben', + monthly_active_users: 'Monatlich aktive Benutzer', + monthly_active_users_tip: + 'Die Anzahl der einzelnen Benutzer, die in den letzten 30 Tagen Token in deinen Anwendungen ausgetauscht haben', +}; + +export default dashboard; diff --git a/packages/phrases/src/locales/de/translation/admin-console/errors.ts b/packages/phrases/src/locales/de/translation/admin-console/errors.ts new file mode 100644 index 000000000..ef7ff49c4 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/errors.ts @@ -0,0 +1,21 @@ +const errors = { + something_went_wrong: 'Ups, da ist etwas schief gelaufen.', + page_not_found: 'Seite nicht gefunden', + unknown_server_error: 'Unbekannter Serverfehler', + empty: 'Keine Daten verfügbar', + missing_total_number: 'Total-Number wurde nicht in Response Headern gefunden', + invalid_uri_format: 'Ungültiges URI-Format', + invalid_origin_format: 'Ungültiges URI Origin-Format', + invalid_json_format: 'Ungültiges JSON-Format', + invalid_error_message_format: 'Ungültiges Fehlermeldung-Format.', + required_field_missing: 'Bitte fülle {{field}} aus', + required_field_missing_plural: 'Mindestens ein {{field}} muss ausgefüllt sein', + more_details: 'Mehr Details', + username_pattern_error: + 'Der Benutzername sollte nur Buchstaben, Zahlen oder Unterstriche enthalten und nicht mit einer Zahl beginnen.', + password_pattern_error: 'Das Passwort muss aus mindestens 6 Zeichen lang sein', + insecure_contexts: 'Unsichere Kontexte (nicht-HTTPS) werden nicht unterstützt.', + unexpected_error: 'Ein unerwarteter Fehler ist aufgetreten', +}; + +export default errors; diff --git a/packages/phrases/src/locales/de/translation/admin-console/general.ts b/packages/phrases/src/locales/de/translation/admin-console/general.ts new file mode 100644 index 000000000..0c4aaa1bb --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/general.ts @@ -0,0 +1,42 @@ +const general = { + placeholder: 'Platzhalter', + skip: 'Überspringen', + next: 'Weiter', + retry: 'Erneut versuchen', + done: 'Fertig', + search: 'Suche', + search_placeholder: 'Suchen', + clear_result: 'Ergebnisse löschen', + save: 'Speichern', + save_changes: 'Änderungen speichern', + saved: 'Gespeichert!', + loading: 'Lade...', + redirecting: 'Weiterleiten...', + add: 'Hinzufügen', + added: 'Hinzugefügt', + cancel: 'Abbrechen', + confirm: 'Bestätigen', + check_out: 'Ansehen', + create: 'Erstellen', + set_up: 'Einrichten', + customize: 'Anpassen', + enable: 'Aktivieren', + reminder: 'Erinnerung', + delete: 'Löschen', + more_options: 'MEHR OPTIONEN', + close: 'Schließen', + copy: 'Kopieren', + copying: 'Kopiere', + copied: 'Kopiert', + required: 'Erforderlich', + add_another: '+ Weitere hinzufügen', + deletion_confirmation: 'Willst du {{title}} wirklich löschen?', + settings_nav: 'Einstellungen', + unsaved_changes_warning: + 'Du hast ungespeicherte Änderungen. Willst du diese Seite wirklich verlassen?', + leave_page: 'Seite verlassen', + stay_on_page: 'Auf Seite bleiben', + type_to_search: 'Tippe um zu suchen', +}; + +export default general; diff --git a/packages/phrases/src/locales/de/translation/admin-console/get-started.ts b/packages/phrases/src/locales/de/translation/admin-console/get-started.ts new file mode 100644 index 000000000..8897b4703 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/get-started.ts @@ -0,0 +1,29 @@ +const get_started = { + progress: 'Erste Schritte: {{completed}}/{{total}}', + progress_dropdown_title: 'Was du machen kannst...', + title: 'Wie willst du mit Logto loslegen?', + subtitle_part1: 'Ein paar Dinge, die du tun kannst, um schnell von Logto zu profitieren', + subtitle_part2: 'Ich bin fertig mit der Einrichtung.', + hide_this: 'Ausblenden', + confirm_message: + 'Bist du sicher, dass du diese Seite ausblenden willst? Diese Aktion kann nicht rückgängig gemacht werden.', + card1_title: 'Zur Demo', + card1_subtitle: 'Probiere die Logto-Anmeldung jetzt aus, um zu sehen, wie sie funktioniert', + card2_title: 'Erste Anwendung erstellen und integrieren', + card2_subtitle: + 'Richte eine native, Single Page oder herkömmliche Anwendung ein, die Logto zur Authentifizierung nutzt.', + card3_title: 'Anmeldeoberfläche anpassen', + card3_subtitle: + 'Passe die Benutzeroberfläche für die Anmeldung an deine Marke an und zeige eine Vorschau in Echtzeit an', + card4_title: 'SMS- und E-Mail-Verbindung einrichten', + card4_subtitle: + 'Probiere die passwortlose Anmeldung mit Telefonnummer oder E-Mail aus, um ein sicheres und reibungsloses Kundenerlebnis zu ermöglichen.', + card5_title: 'Social Connector hinzufügen', + card5_subtitle: + 'Lass deine Kunden sich mit einem Klick mit ihren sozialen Identitäten bei deiner App anmelden', + card6_title: 'Weitere Informationen', + card6_subtitle: + 'Schau dir unsere schrittweisen, szenariobasierten Dokumentationen ohne langweilige Konzepte an', +}; + +export default get_started; diff --git a/packages/phrases/src/locales/de/translation/admin-console/index.ts b/packages/phrases/src/locales/de/translation/admin-console/index.ts new file mode 100644 index 000000000..2964cba88 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/index.ts @@ -0,0 +1,52 @@ +import api_resource_details from './api-resource-details'; +import api_resources from './api-resources'; +import application_details from './application-details'; +import applications from './applications'; +import connector_details from './connector-details'; +import connectors from './connectors'; +import contact from './contact'; +import dashboard from './dashboard'; +import errors from './errors'; +import general from './general'; +import get_started from './get-started'; +import log_details from './log-details'; +import logs from './logs'; +import session_expired from './session-expired'; +import settings from './settings'; +import sign_in_exp from './sign-in-exp'; +import tab_sections from './tab-sections'; +import tabs from './tabs'; +import user_details from './user-details'; +import users from './users'; +import welcome from './welcome'; + +const admin_console = { + title: 'Admin Konsole', + sign_out: 'Abmelden', + profile: 'Profil', + admin_user: 'Admin', + system_app: 'System', + general, + errors, + tab_sections, + tabs, + applications, + application_details, + api_resources, + api_resource_details, + connectors, + connector_details, + get_started, + users, + user_details, + contact, + sign_in_exp, + settings, + dashboard, + logs, + log_details, + session_expired, + welcome, +}; + +export default admin_console; diff --git a/packages/phrases/src/locales/de/translation/admin-console/log-details.ts b/packages/phrases/src/locales/de/translation/admin-console/log-details.ts new file mode 100644 index 000000000..056530189 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/log-details.ts @@ -0,0 +1,17 @@ +const log_details = { + back_to_logs: 'Zurück zu Audit Logs', + back_to_user: 'Zurück zu {{name}}', + success: 'Erfolgreich', + failed: 'Fehlgeschlagen', + event_type: 'Event Typ', + application: 'Anwendung', + ip_address: 'IP Adresse', + user: 'Benutzer', + log_id: 'Log ID', + time: 'Zeit', + user_agent: 'User agent', + tab_details: 'Details', + raw_data: 'Rohe Daten', +}; + +export default log_details; diff --git a/packages/phrases/src/locales/de/translation/admin-console/logs.ts b/packages/phrases/src/locales/de/translation/admin-console/logs.ts new file mode 100644 index 000000000..7c548f676 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/logs.ts @@ -0,0 +1,12 @@ +const logs = { + title: 'Audit Logs', + subtitle: + 'Anzeige der Log Daten von Authentifizierungsereignissen, die von Admins und Benutzern stammen', + event: 'Event', + user: 'Benutzer', + application: 'Anwendung', + time: 'Zeit', + filter_by: 'Filter nach', +}; + +export default logs; diff --git a/packages/phrases/src/locales/de/translation/admin-console/session-expired.ts b/packages/phrases/src/locales/de/translation/admin-console/session-expired.ts new file mode 100644 index 000000000..f1052d50e --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/session-expired.ts @@ -0,0 +1,8 @@ +const session_expired = { + title: 'Sitzung abgelaufen', + subtitle: + 'Deine Sitzung ist möglicherweise abgelaufen und deine Verbindung wurde unterbrochen. Klicke auf die Schaltfläche unten, um dich erneut an der Admin Konsole anzumelden.', + button: 'Erneut anmelden', +}; + +export default session_expired; diff --git a/packages/phrases/src/locales/de/translation/admin-console/settings.ts b/packages/phrases/src/locales/de/translation/admin-console/settings.ts new file mode 100644 index 000000000..e20d8050e --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/settings.ts @@ -0,0 +1,27 @@ +const settings = { + title: 'Einstellungen', + description: 'Verwalte die globalen Einstellungen', + tabs: { + general: 'Allgemein', + }, + custom_domain: 'Benutzerdefinierte Domain', + language: 'Sprache', + appearance: 'Darstellung', + appearance_system: 'Synchonisiere mit Systemeinstellungen', + appearance_light: 'Hell', + appearance_dark: 'Dunkel', + saved: 'Gespeichert!', + change_password: 'Passwort ändern', + change_password_description: + 'Du kannst das Passwort für dieses Konto ändern. Du verwendest den aktuellen Benutzernamen mit dem neuen Passwort, um dich in der Admin Konsole anzumelden.', + change_modal_title: 'Account Password ändern', + change_modal_description: + 'Du verwendest den aktuellen Benutzernamen mit dem neuen Passwort, um dich in der Admin Konsole anzumelden.', + new_password: 'Neues Passwort', + new_password_placeholder: 'Gib ein neues Passwort ein', + confirm_password: 'Passwort bestätigen', + confirm_password_placeholder: 'Bestätige das neue Passwort', + password_changed: 'Passwort geändert!', +}; + +export default settings; diff --git a/packages/phrases/src/locales/de/translation/admin-console/sign-in-exp.ts b/packages/phrases/src/locales/de/translation/admin-console/sign-in-exp.ts new file mode 100644 index 000000000..9bfde3546 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/sign-in-exp.ts @@ -0,0 +1,140 @@ +const sign_in_exp = { + title: 'Anmeldeoberfläche', + description: + 'Passe die Benutzeroberfläche für die Anmeldung an deine Marke an und zeige eine Vorschau in Echtzeit an', + tabs: { + branding: 'Branding', + methods: 'Anmeldemethoden', + others: 'Andere', + }, + welcome: { + title: + 'Dies ist das erste Mal, dass du deine Anmeldeoberfläche anpasst. Diese Anleitung hilft dir, alle notwendigen Einstellungen vorzunehmen und schnell loszulegen.', + get_started: 'Erste Schritte', + apply_remind: + 'Bitte beachte, dass die Anmeldeoberfläche für alle Anwendungen unter diesem Konto gilt.', + got_it: 'Alles klar', + }, + color: { + title: 'FARBE', + primary_color: 'Markenfarbe', + dark_primary_color: 'Markenfarbe (Dunkler Modus)', + dark_mode: 'Aktiviere Dunklen Modus', + dark_mode_description: + 'Deine App erhält einen automatisch generierten Dunklen Modus, der auf deiner Markenfarbe und dem Logto-Algorithmus basiert. Du kannst diesen nach Belieben anpassen.', + dark_mode_reset_tip: 'Neuberechnung der Farbe des dunklen Modus basierend auf der Markenfarbe.', + reset: 'Neuberechnen', + }, + branding: { + title: 'BRANDING', + ui_style: 'Stil', + styles: { + logo_slogan: 'App logo mit Slogan', + logo: 'Nur App logo', + }, + logo_image_url: 'App logo URL', + logo_image_url_placeholder: 'https://dein.cdn.domain/logo.png', + dark_logo_image_url: 'App logo URL (Dunkler Modus)', + dark_logo_image_url_placeholder: 'https://dein.cdn.domain/logo-dark.png', + slogan: 'Slogan', + slogan_placeholder: 'Entfessle deine Kreativität', + }, + sign_in_methods: { + title: 'ANMELDEMETHODEN', + primary: 'Primäre Anmeldemethode', + enable_secondary: 'Aktiviere sekundäre Anmeldemethoden', + enable_secondary_description: + 'Sobald sie aktiviert ist, unterstützt deine App neben der primären Anmeldemethode noch weitere Anmeldemethoden. ', + methods: 'Anmeldemethode', + methods_sms: 'SMS Anmeldung', + methods_email: 'E-Mail Anmeldung', + methods_social: 'Social Anmeldung', + methods_username: 'Benutzername-und-Passwort Anmeldung', + methods_primary_tag: '(Primär)', + define_social_methods: 'Definiere die unterstützten Social Anmeldemethoden', + transfer: { + title: 'Social Connectoren', + footer: { + not_in_list: 'Nicht in der Liste?', + set_up_more: 'Mehr Social Connectoren einrichten', + go_to: 'oder "Connectoren" aufrufen.', + }, + }, + }, + others: { + terms_of_use: { + title: 'NUTZUNGSBEDINGUNGEN', + enable: 'Aktiviere Nutzungsbedingungen', + description: 'Füge die rechtlichen Vereinbarungen für die Nutzung deines Produkts hinzu', + terms_of_use: 'Nutzungsbedingungen', + terms_of_use_placeholder: 'https://beispiel.de/nutzungsbedingungen', + terms_of_use_tip: 'URL zu den Nutzungsbedingungen', + }, + languages: { + title: 'SPRACHEN', + enable_auto_detect: 'Aktiviere automatische Spracherkennung', + description: + 'Deine Software erkennt die Sprach-Einstellung des Nutzers und schaltet auf die lokale Sprache um. Du kannst neue Sprachen hinzufügen, indem du die Benutzeroberfläche vom Englischen in eine andere Sprache übersetzt.', + manage_language: 'Sprachen verwalten', + default_language: 'Standard-Sprache', + default_language_description_auto: + 'Die Standardsprache wird verwendet, wenn die erkannte Benutzersprache nicht in der aktuellen Sprachbibliothek enthalten ist.', + default_language_description_fixed: + 'Wenn die automatische Erkennung deaktiviert ist, ist die Standardsprache die einzige Sprache, die deine Software anzeigt. Schalte die automatische Erkennung ein um weitere Sprachen anzuzeigen.', + }, + manage_language: { + title: 'Sprachen verwalten', + subtitle: + 'Erweitere die Anmeldeoberfläche durch neue Sprachen und Übersetzungen. Deine Übersetzung kann als Standard-Sprache verwendet werden.', + add_language: 'Sprache hinzufügen', + logto_provided: 'Von Logto bereitgestellt', + key: 'Schlüssel', + logto_source_values: 'Logto Übersetzungen', + custom_values: 'Benutzerdefinierte Übersetzungen', + clear_all_tip: 'Alle benutzerdefinierten Übersetzungen löschen', + unsaved_description: + 'Wenn du diese Seite verlässt, ohne zu speichern, werden die Änderungen nicht gespeichert.', + deletion_tip: 'Sprache löschen', + deletion_title: 'Willst du diese Sprache wirklich löschen?', + deletion_description: + 'Nach dem Löschen können deine Benutzer diese Sprache nicht mehr nutzen.', + default_language_deletion_title: 'Die Standardsprache kann nicht gelöscht werden.', + default_language_deletion_description: + '{{language}} ist als Standardsprache eingestellt und kann nicht gelöscht werden. ', + got_it: 'Alles klar', + }, + authentication: { + title: 'AUTHENTIFIZIERUNG', + enable_create_account: 'Aktiviere Registrierung', + enable_create_account_description: + 'Aktiviere oder deaktiviere Konto Registrierung. Wenn diese Funktion deaktiviert ist, können deine Kunden keine Konten über die Anmeldeoberfläche erstellen, aber du kannst immer noch Benutzer in der Admin Konsole hinzufügen.', + }, + }, + setup_warning: { + no_connector: '', + no_connector_sms: + 'Du hast noch keinen SMS Connector eingerichtet. Deine Anmeldung wird erst freigeschaltet, wenn du die Einstellungen abgeschlossen hast. ', + no_connector_email: + 'Du hast noch keinen E-Mail Connector eingerichtet. Deine Anmeldung wird erst freigeschaltet, wenn du die Einstellungen abgeschlossen hast. ', + no_connector_social: + 'Du hast noch keinen Social Connector eingerichtet. Deine Anmeldung wird erst freigeschaltet, wenn du die Einstellungen abgeschlossen hast. ', + no_added_social_connector: + 'Du hast jetzt ein paar Social Connectoren eingerichtet. Füge jetzt einige zu deinem Anmeldeerlebnis hinzu.', + }, + save_alert: { + description: + 'Du änderst die Anmeldemethoden. Das wird sich auf einige deiner Benutzer auswirken. Bist du sicher, dass du das tun willst?', + before: 'Vorher', + after: 'Nachher', + }, + preview: { + title: 'Vorschau', + dark: 'Dunkel', + light: 'Hell', + native: 'Nativ', + desktop_web: 'Desktop Web', + mobile_web: 'Mobil Web', + }, +}; + +export default sign_in_exp; diff --git a/packages/phrases/src/locales/de/translation/admin-console/tab-sections.ts b/packages/phrases/src/locales/de/translation/admin-console/tab-sections.ts new file mode 100644 index 000000000..e5cfecc8c --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/tab-sections.ts @@ -0,0 +1,8 @@ +const tab_sections = { + overview: 'Übersicht', + resource_management: 'Ressourcenverwaltung', + user_management: 'Benutzerverwaltung', + help_and_support: 'Hilfe und Support', +}; + +export default tab_sections; diff --git a/packages/phrases/src/locales/de/translation/admin-console/tabs.ts b/packages/phrases/src/locales/de/translation/admin-console/tabs.ts new file mode 100644 index 000000000..4cd526fb3 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/tabs.ts @@ -0,0 +1,15 @@ +const tabs = { + get_started: 'Erste Schritte', + dashboard: 'Dashboard', + applications: 'Anwendungen', + api_resources: 'API Ressourcen', + sign_in_experience: 'Anmeldeoberfläche', + connectors: 'Connectoren', + users: 'Benutzerverwaltung', + audit_logs: 'Audit Logs', + docs: 'Dokumentation', + contact_us: 'Kontakt', + settings: 'Einstellungen', +}; + +export default tabs; diff --git a/packages/phrases/src/locales/de/translation/admin-console/user-details.ts b/packages/phrases/src/locales/de/translation/admin-console/user-details.ts new file mode 100644 index 000000000..e0643d761 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/user-details.ts @@ -0,0 +1,41 @@ +const user_details = { + back_to_users: 'Zurück zur Benutzerverwaltung', + created_title: 'Der Benutzer wurde erfolgreich erstellt', + created_guide: 'Sende dem Benutzer folgende Anmeldeinformationen', + created_username: 'Benutzername:', + created_password: 'Passwort:', + menu_delete: 'Löschen', + delete_description: + 'Diese Aktion kann nicht rückgängig gemacht werden. Der Benutzer wird permanent gelöscht.', + deleted: 'Der Benutzer wurde erfolgreich gelöscht', + reset_password: { + reset_password: 'Passwort zurücksetzen', + title: 'Willst du das Passwort wirklich zurücksetzen?', + content: + 'Diese Aktion kann nicht rückgängig gemacht werden. Das Anmeldeinformationen werden zurückgesetzt.', + congratulations: 'Der Benutzer wurde erfolgreich zurückgesetzt', + new_password: 'Neues Passwort:', + }, + tab_logs: 'Benutzer-Logs', + field_email: 'Primäre E-Mail', + field_phone: 'Primäre Telefonnummer', + field_username: 'Benutzername', + field_name: 'Name', + field_avatar: 'Profilbild URL', + field_avatar_placeholder: 'https://dein.cdn.domain/profilbild.png', + field_custom_data: 'Benutzerdefinierte Daten', + field_custom_data_tip: + 'Zusätzliche Benutzerinformationen, die nicht in den vordefinierten Benutzereigenschaften aufgeführt sind, wie z. B. die vom Benutzer bevorzugte Farbe und Sprache.', + field_connectors: 'Social Connections', + custom_data_invalid: 'Benutzerdefinierte Daten müssen ein gültiges JSON-Objekt sein.', + connectors: { + connectors: 'Connectoren', + user_id: 'Benutzer ID', + remove: 'Löschen', + not_connected: 'Der Nutzer ist nicht mit einem Social Connector verbunden', + deletion_confirmation: + 'Du entfernst die bestehende Identität. Bist du sicher, dass du das tun willst?', + }, +}; + +export default user_details; diff --git a/packages/phrases/src/locales/de/translation/admin-console/users.ts b/packages/phrases/src/locales/de/translation/admin-console/users.ts new file mode 100644 index 000000000..0407bfc42 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/users.ts @@ -0,0 +1,15 @@ +const users = { + title: 'Benutzerverwaltung', + subtitle: + 'Verwalten von Benutzeridentitäten, einschließlich des Anlegens von Benutzern, Bearbeiten von Benutzerinformationen, Anzeigen von Benutzer-Logs, Zurücksetzen von Passwörtern und Löschen von Benutzern', + create: 'Benutzer hinzufügen', + user_name: 'Benutzer', + application_name: 'Anwendungsname', + latest_sign_in: 'Letzte Anmeldung', + create_form_username: 'Benutzername', + create_form_password: 'Passwort', + create_form_name: 'Name', + unnamed: 'Unbenannt', +}; + +export default users; diff --git a/packages/phrases/src/locales/de/translation/admin-console/welcome.ts b/packages/phrases/src/locales/de/translation/admin-console/welcome.ts new file mode 100644 index 000000000..d07d47bf4 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/admin-console/welcome.ts @@ -0,0 +1,8 @@ +const welcome = { + title: 'Willkommen in der Admin Konsole', + description: + 'Die Admin-Konsole ist eine Web-App, mit der du Logto verwalten kannst, ohne programmieren zu müssen. Legen wir zunächst ein Konto an. Mit diesem Konto kannst du Logto selbst oder im Namen deines Unternehmens verwalten.', + create_account: 'Konto erstellen', +}; + +export default welcome; diff --git a/packages/phrases/src/locales/de/translation/demo-app.ts b/packages/phrases/src/locales/de/translation/demo-app.ts new file mode 100644 index 000000000..18d473be0 --- /dev/null +++ b/packages/phrases/src/locales/de/translation/demo-app.ts @@ -0,0 +1,15 @@ +const demo_app = { + notification: + 'Nutze dein existierendes Admin Konto oder erstelle ein neues Konto um dich in die Demo App einzuloggen.', + title: 'Du hast dich erfolgreich in der Demo App angemeldet!', + subtitle: 'Here is your log in information:', + username: 'Benutzername: ', + user_id: 'Benutzer ID: ', + sign_out: 'Aus der Demo App ausloggen', + continue_explore: 'Oder weiter zum Entdecken', + customize_sign_in_experience: 'Anmeldeoberfläche anpassen', + enable_passwordless: 'Passwordless einschalten', + add_social_connector: 'Social Connector hinzufügen', +}; + +export default demo_app; diff --git a/packages/phrases/src/locales/de/translation/index.ts b/packages/phrases/src/locales/de/translation/index.ts new file mode 100644 index 000000000..4d123d04e --- /dev/null +++ b/packages/phrases/src/locales/de/translation/index.ts @@ -0,0 +1,9 @@ +import admin_console from './admin-console'; +import demo_app from './demo-app'; + +const translation = { + admin_console, + demo_app, +}; + +export default translation; From 938608e72b58ac36899b952e654d36de481be3f8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=C4=B0hsan=20G=C3=BCld=C3=BCr?= <100419187+ihsanguldur@users.noreply.github.com> Date: Fri, 4 Nov 2022 05:47:54 +0300 Subject: [PATCH 03/19] feat: add case insensitive user search (#2300) Co-authored-by: wangsijie Co-authored-by: Charles Zhao Co-authored-by: wangsijie --- packages/core/src/queries/user.test.ts | 61 +++++++++++++++++++++++--- packages/core/src/queries/user.ts | 40 ++++++++++++----- packages/core/src/routes/admin-user.ts | 13 ++++-- 3 files changed, 94 insertions(+), 20 deletions(-) diff --git a/packages/core/src/queries/user.test.ts b/packages/core/src/queries/user.test.ts index 22dbb24fd..6eb556874 100644 --- a/packages/core/src/queries/user.test.ts +++ b/packages/core/src/queries/user.test.ts @@ -240,7 +240,7 @@ describe('user query', () => { const expectSql = sql` select count(*) from ${table} - where ${fields.primaryEmail} like $1 or ${fields.primaryPhone} like $2 or ${fields.username} like $3 or ${fields.name} like $4 + where ${fields.primaryEmail} ilike $1 or ${fields.primaryPhone} ilike $2 or ${fields.username} ilike $3 or ${fields.name} ilike $4 `; mockQuery.mockImplementationOnce(async (sql, values) => { @@ -259,7 +259,7 @@ describe('user query', () => { select count(*) from ${table} where not (${fields.roleNames}::jsonb?$1) - and (${fields.primaryEmail} like $2 or ${fields.primaryPhone} like $3 or ${fields.username} like $4 or ${fields.name} like $5) + and (${fields.primaryEmail} ilike $2 or ${fields.primaryPhone} ilike $3 or ${fields.username} ilike $4 or ${fields.name} ilike $5) `; mockQuery.mockImplementationOnce(async (sql, values) => { @@ -278,6 +278,24 @@ describe('user query', () => { await expect(countUsers(search, true)).resolves.toEqual(dbvalue); }); + it('countUsers with isCaseSensitive', async () => { + const search = 'foo'; + const expectSql = sql` + select count(*) + from ${table} + where ${fields.primaryEmail} like $1 or ${fields.primaryPhone} like $2 or ${fields.username} like $3 or ${fields.name} like $4 + `; + + mockQuery.mockImplementationOnce(async (sql, values) => { + expectSqlAssert(sql, expectSql.sql); + expect(values).toEqual([`%${search}%`, `%${search}%`, `%${search}%`, `%${search}%`]); + + return createMockQueryResult([dbvalue]); + }); + + await expect(countUsers(search, undefined, true)).resolves.toEqual(dbvalue); + }); + it('findUsers', async () => { const search = 'foo'; const limit = 100; @@ -285,9 +303,9 @@ describe('user query', () => { const expectSql = sql` select ${sql.join(Object.values(fields), sql`,`)} from ${table} - where ${fields.primaryEmail} like $1 or ${fields.primaryPhone} like $2 or ${ + where ${fields.primaryEmail} ilike $1 or ${fields.primaryPhone} ilike $2 or ${ fields.username - } like $3 or ${fields.name} like $4 + } ilike $3 or ${fields.name} ilike $4 limit $5 offset $6 `; @@ -317,9 +335,9 @@ describe('user query', () => { select ${sql.join(Object.values(fields), sql`,`)} from ${table} where not (${fields.roleNames}::jsonb?$1) - and (${fields.primaryEmail} like $2 or ${fields.primaryPhone} like $3 or ${ + and (${fields.primaryEmail} ilike $2 or ${fields.primaryPhone} ilike $3 or ${ fields.username - } like $4 or ${fields.name} like $5) + } ilike $4 or ${fields.name} ilike $5) limit $6 offset $7 `; @@ -342,6 +360,37 @@ describe('user query', () => { await expect(findUsers(limit, offset, search, true)).resolves.toEqual([dbvalue]); }); + it('findUsers with isCaseSensitive', async () => { + const search = 'foo'; + const limit = 100; + const offset = 1; + const expectSql = sql` + select ${sql.join(Object.values(fields), sql`,`)} + from ${table} + where ${fields.primaryEmail} like $1 or ${fields.primaryPhone} like $2 or ${ + fields.username + } like $3 or ${fields.name} like $4 + limit $5 + offset $6 + `; + + mockQuery.mockImplementationOnce(async (sql, values) => { + expectSqlAssert(sql, expectSql.sql); + expect(values).toEqual([ + `%${search}%`, + `%${search}%`, + `%${search}%`, + `%${search}%`, + limit, + offset, + ]); + + return createMockQueryResult([dbvalue]); + }); + + await expect(findUsers(limit, offset, search, undefined, true)).resolves.toEqual([dbvalue]); + }); + it('updateUserById', async () => { const username = 'Joe'; const id = 'foo'; diff --git a/packages/core/src/queries/user.ts b/packages/core/src/queries/user.ts index 67b1bb8d2..6a4e70881 100644 --- a/packages/core/src/queries/user.ts +++ b/packages/core/src/queries/user.ts @@ -84,44 +84,64 @@ export const hasUserWithIdentity = async (target: string, userId: string) => ` ); -const buildUserSearchConditionSql = (search: string) => { +const buildUserSearchConditionSql = (search: string, isCaseSensitive = false) => { const searchFields = [fields.primaryEmail, fields.primaryPhone, fields.username, fields.name]; - const conditions = searchFields.map((filedName) => sql`${filedName} like ${'%' + search + '%'}`); - return sql`${sql.join(conditions, sql` or `)}`; + return sql`${sql.join( + searchFields.map( + (filedName) => + sql`${filedName} ${isCaseSensitive ? sql`like` : sql`ilike`} ${'%' + search + '%'}` + ), + sql` or ` + )}`; }; -const buildUserConditions = (search?: string, hideAdminUser?: boolean) => { +const buildUserConditions = ( + search?: string, + hideAdminUser?: boolean, + isCaseSensitive?: boolean +) => { if (hideAdminUser) { return sql` where not (${fields.roleNames}::jsonb?${UserRole.Admin}) - ${conditionalSql(search, (search) => sql`and (${buildUserSearchConditionSql(search)})`)} + ${conditionalSql( + search, + (search) => sql`and (${buildUserSearchConditionSql(search, isCaseSensitive)})` + )} `; } return sql` - ${conditionalSql(search, (search) => sql`where ${buildUserSearchConditionSql(search)}`)} + ${conditionalSql( + search, + (search) => sql`where ${buildUserSearchConditionSql(search, isCaseSensitive)}` + )} `; }; -export const countUsers = async (search?: string, hideAdminUser?: boolean) => +export const countUsers = async ( + search?: string, + hideAdminUser?: boolean, + isCaseSensitive?: boolean +) => envSet.pool.one<{ count: number }>(sql` select count(*) from ${table} - ${buildUserConditions(search, hideAdminUser)} + ${buildUserConditions(search, hideAdminUser, isCaseSensitive)} `); export const findUsers = async ( limit: number, offset: number, search?: string, - hideAdminUser?: boolean + hideAdminUser?: boolean, + isCaseSensitive?: boolean ) => envSet.pool.any( sql` select ${sql.join(Object.values(fields), sql`,`)} from ${table} - ${buildUserConditions(search, hideAdminUser)} + ${buildUserConditions(search, hideAdminUser, isCaseSensitive)} limit ${limit} offset ${offset} ` diff --git a/packages/core/src/routes/admin-user.ts b/packages/core/src/routes/admin-user.ts index c62653a69..8c83437b2 100644 --- a/packages/core/src/routes/admin-user.ts +++ b/packages/core/src/routes/admin-user.ts @@ -27,18 +27,23 @@ export default function adminUserRoutes(router: T) { '/users', koaPagination(), koaGuard({ - query: object({ search: string().optional(), hideAdminUser: literal('true').optional() }), + query: object({ + search: string().optional(), + hideAdminUser: literal('true').optional(), + isCaseSensitive: literal('true').optional(), + }), }), async (ctx, next) => { const { limit, offset } = ctx.pagination; const { - query: { search, hideAdminUser: _hideAdminUser }, + query: { search, hideAdminUser: _hideAdminUser, isCaseSensitive: _isCaseSensitive }, } = ctx.guard; const hideAdminUser = _hideAdminUser === 'true'; + const isCaseSensitive = _isCaseSensitive === 'true'; const [{ count }, users] = await Promise.all([ - countUsers(search, hideAdminUser), - findUsers(limit, offset, search, hideAdminUser), + countUsers(search, hideAdminUser, isCaseSensitive), + findUsers(limit, offset, search, hideAdminUser, isCaseSensitive), ]); ctx.pagination.totalCount = count; From 0ade7fd492d317b8096195670d60b73cbd842d16 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Nov 2022 10:58:53 +0800 Subject: [PATCH 04/19] chore(deps): update dependency jest-environment-jsdom to v29 (#1816) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Gao Sun --- packages/integration-tests/jest.config.ts | 4 +- packages/ui/package.json | 2 +- pnpm-lock.yaml | 618 ++++++++++------------ 3 files changed, 276 insertions(+), 348 deletions(-) diff --git a/packages/integration-tests/jest.config.ts b/packages/integration-tests/jest.config.ts index e397c3752..d9955574a 100644 --- a/packages/integration-tests/jest.config.ts +++ b/packages/integration-tests/jest.config.ts @@ -1,7 +1,7 @@ -import { merge, Config } from '@silverhand/jest-config'; +import type { Config } from '@silverhand/jest-config'; +import { merge } from '@silverhand/jest-config'; const config: Config.InitialOptions = merge({ - testEnvironment: 'jsdom', setupFilesAfterEnv: ['/jest.setup.js'], }); diff --git a/packages/ui/package.json b/packages/ui/package.json index 685d3cd6c..881351cc7 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -48,7 +48,7 @@ "i18next": "^21.8.16", "i18next-browser-languagedetector": "^6.1.4", "jest": "^29.1.2", - "jest-environment-jsdom": "^28.1.3", + "jest-environment-jsdom": "^29.0.0", "jest-transformer-svg": "^2.0.0", "js-base64": "^3.7.2", "ky": "^0.31.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index df45c4c9d..2d7e2df48 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -683,7 +683,7 @@ importers: i18next: ^21.8.16 i18next-browser-languagedetector: ^6.1.4 jest: ^29.1.2 - jest-environment-jsdom: ^28.1.3 + jest-environment-jsdom: ^29.0.0 jest-transformer-svg: ^2.0.0 js-base64: ^3.7.2 ky: ^0.31.0 @@ -737,7 +737,7 @@ importers: i18next: 21.8.16 i18next-browser-languagedetector: 6.1.4 jest: 29.1.2 - jest-environment-jsdom: 28.1.3 + jest-environment-jsdom: 29.2.2 jest-transformer-svg: 2.0.0_jest@29.1.2+react@18.2.0 js-base64: 3.7.2 ky: 0.31.0 @@ -829,7 +829,7 @@ packages: engines: {node: '>=6.9.0'} dependencies: '@ampproject/remapping': 2.1.2 - '@babel/code-frame': 7.16.7 + '@babel/code-frame': 7.18.6 '@babel/generator': 7.17.9 '@babel/helper-compilation-targets': 7.17.7_@babel+core@7.17.9 '@babel/helper-module-transforms': 7.17.7 @@ -1843,11 +1843,11 @@ packages: resolution: {integrity: sha512-ujEBCcYs82BTmRxqfHMQggSlkUZP63AE5YEaTPj7eFyJOzukkTorstOUC7L6nE3w5SYadGVAnTsQ/ZjTGL0qYQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.2 - '@types/node': 16.11.65 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 chalk: 4.1.2 - jest-message-util: 29.1.2 - jest-util: 29.1.2 + jest-message-util: 29.2.1 + jest-util: 29.2.1 slash: 3.0.0 dev: true @@ -1864,15 +1864,15 @@ packages: '@jest/reporters': 29.1.2 '@jest/test-result': 29.1.2 '@jest/transform': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.5.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.0.0 - jest-config: 29.1.2_@types+node@16.11.65 + jest-config: 29.1.2_@types+node@17.0.23 jest-haste-map: 29.1.2 jest-message-util: 29.1.2 jest-regex-util: 29.0.0 @@ -1881,7 +1881,7 @@ packages: jest-runner: 29.1.2 jest-runtime: 29.1.2 jest-snapshot: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 jest-watcher: 29.1.2 micromatch: 4.0.5 @@ -1906,15 +1906,15 @@ packages: '@jest/reporters': 29.1.2 '@jest/test-result': 29.1.2 '@jest/transform': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 ansi-escapes: 4.3.2 chalk: 4.1.2 ci-info: 3.5.0 exit: 0.1.2 graceful-fs: 4.2.10 jest-changed-files: 29.0.0 - jest-config: 29.1.2_7fnffnpg6qxg3uvt2vx7t77ic4 + jest-config: 29.1.2_hvivgrlmkyd4vgu6rkkmg6acly jest-haste-map: 29.1.2 jest-message-util: 29.1.2 jest-regex-util: 29.0.0 @@ -1923,7 +1923,7 @@ packages: jest-runner: 29.1.2 jest-runtime: 29.1.2 jest-snapshot: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 jest-watcher: 29.1.2 micromatch: 4.0.5 @@ -1945,24 +1945,14 @@ packages: jest-mock: 27.5.1 dev: true - /@jest/environment/28.1.3: - resolution: {integrity: sha512-1bf40cMFTEkKyEf585R9Iz1WayDjHoHqvts0XFYEqyKM3cFWDpeMoqKKTAF9LSYQModPUlh8FKptoM2YcMWAXA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/fake-timers': 28.1.3 - '@jest/types': 28.1.3 - '@types/node': 17.0.23 - jest-mock: 28.1.3 - dev: true - - /@jest/environment/29.1.2: - resolution: {integrity: sha512-rG7xZ2UeOfvOVzoLIJ0ZmvPl4tBEQ2n73CZJSlzUjPw4or1oSWC0s0Rk0ZX+pIBJ04aVr6hLWFn1DFtrnf8MhQ==} + /@jest/environment/29.2.2: + resolution: {integrity: sha512-OWn+Vhu0I1yxuGBJEFFekMYc8aGBGrY4rt47SOh/IFaI+D7ZHCk7pKRiSoZ2/Ml7b0Ony3ydmEHRx/tEOC7H1A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/fake-timers': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 - jest-mock: 29.1.2 + '@jest/fake-timers': 29.2.2 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 + jest-mock: 29.2.2 dev: true /@jest/expect-utils/29.1.2: @@ -1994,38 +1984,26 @@ packages: jest-util: 27.5.1 dev: true - /@jest/fake-timers/28.1.3: - resolution: {integrity: sha512-D/wOkL2POHv52h+ok5Oj/1gOG9HSywdoPtFsRCUmlCILXNn5eIWmcnd3DIiWlJnpGvQtmajqBP95Ei0EimxfLw==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@sinonjs/fake-timers': 9.1.2 - '@types/node': 17.0.23 - jest-message-util: 28.1.3 - jest-mock: 28.1.3 - jest-util: 28.1.3 - dev: true - - /@jest/fake-timers/29.1.2: - resolution: {integrity: sha512-GppaEqS+QQYegedxVMpCe2xCXxxeYwQ7RsNx55zc8f+1q1qevkZGKequfTASI7ejmg9WwI+SJCrHe9X11bLL9Q==} + /@jest/fake-timers/29.2.2: + resolution: {integrity: sha512-nqaW3y2aSyZDl7zQ7t1XogsxeavNpH6kkdq+EpXncIDvAkjvFD7hmhcIs1nWloengEWUoWqkqSA6MSbf9w6DgA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 '@sinonjs/fake-timers': 9.1.2 - '@types/node': 16.11.65 - jest-message-util: 29.1.2 - jest-mock: 29.1.2 - jest-util: 29.1.2 + '@types/node': 17.0.23 + jest-message-util: 29.2.1 + jest-mock: 29.2.2 + jest-util: 29.2.1 dev: true /@jest/globals/29.1.2: resolution: {integrity: sha512-uMgfERpJYoQmykAd0ffyMq8wignN4SvLUG6orJQRe9WAlTRc9cdpCaE/29qurXixYJVZWUqIBXhSk8v5xN1V9g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.1.2 + '@jest/environment': 29.2.2 '@jest/expect': 29.1.2 - '@jest/types': 29.1.2 - jest-mock: 29.1.2 + '@jest/types': 29.2.1 + jest-mock: 29.2.2 transitivePeerDependencies: - supports-color dev: true @@ -2043,9 +2021,9 @@ packages: '@jest/console': 29.1.2 '@jest/test-result': 29.1.2 '@jest/transform': 29.1.2 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 '@jridgewell/trace-mapping': 0.3.16 - '@types/node': 16.11.65 + '@types/node': 17.0.23 chalk: 4.1.2 collect-v8-coverage: 1.0.1 exit: 0.1.2 @@ -2056,8 +2034,8 @@ packages: istanbul-lib-report: 3.0.0 istanbul-lib-source-maps: 4.0.1 istanbul-reports: 3.1.5 - jest-message-util: 29.1.2 - jest-util: 29.1.2 + jest-message-util: 29.2.1 + jest-util: 29.2.1 jest-worker: 29.1.2 slash: 3.0.0 string-length: 4.0.2 @@ -2068,13 +2046,6 @@ packages: - supports-color dev: true - /@jest/schemas/28.1.3: - resolution: {integrity: sha512-/l/VWsdt/aBXgjshLWOFyFt3IVdYypu5y2Wn2rOO1un6nkqIn8SLXzgIMYXFyYsRWDyF5EthmKJMIdJvk08grg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@sinclair/typebox': 0.24.26 - dev: true - /@jest/schemas/29.0.0: resolution: {integrity: sha512-3Ab5HgYIIAnS0HjqJHQYZS+zXc4tUmTmBH3z83ajI6afXp8X3ZtdLX+nXx+I7LNkJD7uN9LAVhgnjDgZa2z0kA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -2096,7 +2067,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/console': 29.1.2 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 '@types/istanbul-lib-coverage': 2.0.4 collect-v8-coverage: 1.0.1 dev: true @@ -2116,7 +2087,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/core': 7.19.3 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 '@jridgewell/trace-mapping': 0.3.16 babel-plugin-istanbul: 6.1.1 chalk: 4.1.2 @@ -2125,7 +2096,7 @@ packages: graceful-fs: 4.2.10 jest-haste-map: 29.1.2 jest-regex-util: 29.0.0 - jest-util: 29.1.2 + jest-util: 29.2.1 micromatch: 4.0.5 pirates: 4.0.5 slash: 3.0.0 @@ -2138,27 +2109,27 @@ packages: resolution: {integrity: sha512-Cx46iJ9QpwQTjIdq5VJu2QTMMs3QlEjI0x1QbBP5W1+nMzyc2XmimiRR/CbX9TO0cPTeUlxWMOu8mslYsJ8DEw==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@types/istanbul-lib-coverage': 2.0.3 + '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 '@types/node': 17.0.23 '@types/yargs': 16.0.4 chalk: 4.1.2 dev: true - /@jest/types/28.1.3: - resolution: {integrity: sha512-RyjiyMUZrKz/c+zlMFO1pm70DcIlST8AeWTkoUdZevew44wcNZQHsEVOiCVtgVnlFFD82FPaXycys58cf2muVQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + /@jest/types/29.1.2: + resolution: {integrity: sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/schemas': 28.1.3 - '@types/istanbul-lib-coverage': 2.0.3 + '@jest/schemas': 29.0.0 + '@types/istanbul-lib-coverage': 2.0.4 '@types/istanbul-reports': 3.0.1 '@types/node': 17.0.23 '@types/yargs': 17.0.13 chalk: 4.1.2 dev: true - /@jest/types/29.1.2: - resolution: {integrity: sha512-DcXGtoTykQB5jiwCmVr8H4vdg2OJhQex3qPkG+ISyDO7xQXbt/4R6dowcRyPemRnkH7JoHvZuxPBdlq+9JxFCg==} + /@jest/types/29.2.1: + resolution: {integrity: sha512-O/QNDQODLnINEPAI0cl9U6zUIDXEWXt6IC1o2N2QENuos7hlGUIthlKyV4p6ki3TvXFX071blj8HUhgLGquPjw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/schemas': 29.0.0 @@ -3526,10 +3497,6 @@ packages: typescript: 4.7.4 dev: true - /@sinclair/typebox/0.24.26: - resolution: {integrity: sha512-1ZVIyyS1NXDRVT8GjWD5jULjhDyM3IsIHef2VGUMdnWOlX2tkPjyEX/7K0TGSH2S8EaPhp1ylFdjSjUGQ+gecg==} - dev: true - /@sinclair/typebox/0.24.46: resolution: {integrity: sha512-ng4ut1z2MCBhK/NwDVwIQp3pAUOCs/KNaW3cBxdFB2xTDrOuo1xuNmpr/9HHFhxqIvHrs1NTH3KJg6q+JSy1Kw==} dev: true @@ -3902,7 +3869,7 @@ packages: /@types/graceful-fs/4.1.5: resolution: {integrity: sha512-anKkLmZZ+xm4p8JWBf4hElkM4XR+EZeA2M9BAkkTldmcyDY4mbdIJnRghDJH3Ov5ooY7/UAoENtmdMSkaAd7Cw==} dependencies: - '@types/node': 16.11.65 + '@types/node': 17.0.23 dev: true /@types/hast/2.3.4: @@ -3943,10 +3910,6 @@ packages: ci-info: 3.5.0 dev: true - /@types/istanbul-lib-coverage/2.0.3: - resolution: {integrity: sha512-sz7iLqvVUg1gIedBOvlkxPlc8/uVzyS5OwGz1cKjXzkl3FpL3al0crU8YGU1WoHkxn0Wxbw5tyi6hvzJKNzFsw==} - dev: true - /@types/istanbul-lib-coverage/2.0.4: resolution: {integrity: sha512-z/QT1XN4K4KYuslS23k62yDIDLwLFkzxOuMplDtObz0+y7VqJCaO2o+SPwHCvLFZh7xazvvoor2tA/hPz9ee7g==} dev: true @@ -3954,7 +3917,7 @@ packages: /@types/istanbul-lib-report/3.0.0: resolution: {integrity: sha512-plGgXAPfVKFoYfa9NpYDAkseG+g6Jr294RqeqcqDixSbU34MZVJRi/P+7Y8GDpzkEwLaGZZOpKIEmeVZNtKsrg==} dependencies: - '@types/istanbul-lib-coverage': 2.0.3 + '@types/istanbul-lib-coverage': 2.0.4 dev: true /@types/istanbul-reports/3.0.1: @@ -3982,12 +3945,12 @@ packages: resolution: {integrity: sha512-FhpRzf927MNQdRZP0J5DLIdTXhjLYzeUTmLAu69mnVksLH9CJY3IuSeEgbKUki7GQZm0WqDkGzyxju2EZGD2wA==} dev: true - /@types/jsdom/16.2.15: - resolution: {integrity: sha512-nwF87yjBKuX/roqGYerZZM0Nv1pZDMAT5YhOHYeM/72Fic+VEqJh4nyoqoapzJnW3pUlfxPY5FhgsJtM+dRnQQ==} + /@types/jsdom/20.0.0: + resolution: {integrity: sha512-YfAchFs0yM1QPDrLm2VHe+WHGtqms3NXnXAMolrgrVP6fgBHHXy1ozAbo/dFtPNtZC/m66bPiCTWYmqp1F14gA==} dependencies: '@types/node': 17.0.23 - '@types/parse5': 6.0.3 '@types/tough-cookie': 4.0.2 + parse5: 7.1.1 dev: true /@types/json-schema/7.0.11: @@ -4106,10 +4069,6 @@ packages: resolution: {integrity: sha512-+2Iggwg7PxoO5Kyhvsq9VarmPbIelXP070HMImEpbtGCoyWNINQj4wzjbQCXzdHTRXnqufutJb5KAURZANNBAw==} dev: true - /@types/node/16.11.65: - resolution: {integrity: sha512-Vfz7wGMOr4jbQGiQHVJm8VjeQwM9Ya7mHe9LtQ264/Epf5n1KiZShOFqk++nBzw6a/ubgYdB9Od7P+MH/LjoWw==} - dev: true - /@types/node/17.0.23: resolution: {integrity: sha512-UxDxWn7dl97rKVeVS61vErvw086aCYhDLyvRQZ5Rk65rZKepaFdm53GeqXaKBuOhED4e9uWq34IC3TdSdJJ2Gw==} @@ -4130,10 +4089,6 @@ packages: resolution: {integrity: sha512-kUNnecmtkunAoQ3CnjmMkzNU/gtxG8guhi+Fk2U/kOpIKjIMKnXGp4IJCgQJrXSgMsWYimYG4TGjz/UzbGEBTw==} dev: true - /@types/parse5/6.0.3: - resolution: {integrity: sha512-SuT16Q1K51EAVPz1K29DJ/sXjhSQ0zjvsypYJ6tlwVsRV9jwW5Adq2ch8Dq8kDBCkYnELS7N7VNCSB5nC56t/g==} - dev: true - /@types/pluralize/0.0.29: resolution: {integrity: sha512-BYOID+l2Aco2nBik+iYS4SZX0Lf20KPILP5RGmM1IgzdwNdTs0eebiFriOPcej1sX9mLnSoiNte5zcFxssgpGA==} dev: true @@ -4446,7 +4401,7 @@ packages: resolution: {integrity: sha512-Il80Qs2WjYlJIBNzNkK6KYqlVMTbZLXgHx2oT0pU/fjRHyEp+PEfEPY0R3WCwAGVOtauxh1hOxNgIf5bv7dQpA==} engines: {node: '>= 0.6'} dependencies: - mime-types: 2.1.34 + mime-types: 2.1.35 negotiator: 0.6.2 /accepts/1.3.8: @@ -4457,11 +4412,11 @@ packages: negotiator: 0.6.3 dev: true - /acorn-globals/6.0.0: - resolution: {integrity: sha512-ZQl7LOWaF5ePqqcX4hLuv/bLXYQNfNWw2c0/yX/TsPRKamzHcTGQnlCjHT3TsmkOUVEPS3crCxiPfdzE/Trlhg==} + /acorn-globals/7.0.1: + resolution: {integrity: sha512-umOSDSDrfHbTNPuNpC2NSnnA3LUrqpevPb4T9jRx4MagXNS0rs+gwiTcAvqCRmsD6utzsrzNt+ebm00SNWiC3Q==} dependencies: - acorn: 7.4.1 - acorn-walk: 7.2.0 + acorn: 8.8.0 + acorn-walk: 8.2.0 dev: true /acorn-jsx/5.3.2_acorn@8.8.0: @@ -4472,28 +4427,11 @@ packages: acorn: 8.8.0 dev: true - /acorn-walk/7.2.0: - resolution: {integrity: sha512-OPdCF6GsMIP+Az+aWfAAOEt2/+iVDKE7oy6lJ098aoe59oAmK76qV6Gw60SbZ8jHuG2wH058GF4pLFbYamYrVA==} - engines: {node: '>=0.4.0'} - dev: true - /acorn-walk/8.2.0: resolution: {integrity: sha512-k+iyHEuPgSw6SbuDpGQM+06HQUa04DZ3o+F6CSzXMvvI5KMvnaEqXe+YVe555R9nn6GPt404fos4wcgpw12SDA==} engines: {node: '>=0.4.0'} dev: true - /acorn/7.4.1: - resolution: {integrity: sha512-nQyp0o1/mNdbTO1PO6kHkwSrmgZ0MT/jCCpNiwbUjGoRN4dlBhqJtoQuCnEOKzgTVwg0ZWiCoQy6SxMebQVh8A==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - - /acorn/8.7.0: - resolution: {integrity: sha512-V/LGr1APy+PXIwKebEWrkZPwoeoF+w1jiOBUmuxuiUIaOHtob8Qc9BTrYo7VuI5fR8tqsy+buA2WFooR5olqvQ==} - engines: {node: '>=0.4.0'} - hasBin: true - dev: true - /acorn/8.8.0: resolution: {integrity: sha512-QOxyigPVrpZ2GXT+PFyZTl6TtOFc5egxHIP9IlQ+RbupQuX4RkT/Bee4/kQuC02Xkzg84JcT7oLYtDIQxp+v7w==} engines: {node: '>=0.4.0'} @@ -4896,10 +4834,6 @@ packages: wcwidth: 1.0.1 dev: true - /browser-process-hrtime/1.0.0: - resolution: {integrity: sha512-9o5UecI3GhkpM6DrXr69PblIuWxPKk9Y0jHBRhdocZ2y7YECBFCsHm79Pr3OyR2AvjhDkabFJaDJMYRazHgsow==} - dev: true - /browserslist/4.20.3: resolution: {integrity: sha512-NBhymBQl1zM0Y5dQT/O+xiLP9/rzOIQdKM/eMJBAq7yBgaB6krIYLGejrwVYnSHZdqjscB1SPuAjHwxjvN6Wdg==} engines: {node: ^6 || ^7 || ^8 || ^9 || ^10 || ^11 || ^12 || >=13.7} @@ -4976,7 +4910,7 @@ packages: resolution: {integrity: sha512-IKufZ1o4Ut42YUrZSo8+qnMTrFuKkvyoLXUywKz9GJ5BrhOFGhLdkx9sG4KAnVvbY6kEcSFjLQul+DVmBm2bgA==} engines: {node: '>= 6.0.0'} dependencies: - mime-types: 2.1.34 + mime-types: 2.1.35 ylru: 1.2.1 /cacheable-lookup/5.0.4: @@ -5132,10 +5066,6 @@ packages: engines: {node: '>=6.0'} dev: true - /ci-info/3.3.2: - resolution: {integrity: sha512-xmDt/QIAdeZ9+nfdPsaBCpMvHNLFiLdjj59qjqn+6iPe6YmHGQ35sBnQ8uslRBXFmXkiZQOJRjvQeoGppoTjjg==} - dev: true - /ci-info/3.5.0: resolution: {integrity: sha512-yH4RezKOGlOhxkmhbeNuC4eYZKAUsEaGtBuBzDDP1eFUKiccDWzBABxBfOx31IDwDIXMTxWuwAxUGModvkbuVw==} dev: true @@ -5800,8 +5730,8 @@ packages: resolution: {integrity: sha512-qIMFpTMZmny+MMIitAB6D7iVPEorVw6YQRWkvarTkT4tBeSLLiHzcwj6q0MmYSFCiVpiqPJTJEYIrpcPzVEIvg==} dev: true - /decimal.js/10.3.1: - resolution: {integrity: sha512-V0pfhfr8suzyPGOx3nmq4aHqabehUZn6Ch9kyFpV79TGDTWFmHqUqXdabR7QHqxzrYolF4+tVmJhUG4OURg5dQ==} + /decimal.js/10.4.2: + resolution: {integrity: sha512-ic1yEvwT6GuvaYwBLLY6/aFFgjZdySKTE8en/fkU3QICTmRtgtSlFn0u0BXN06InZwtfCelR7j8LRiDI/02iGA==} dev: true /decode-named-character-reference/1.0.1: @@ -6116,6 +6046,11 @@ packages: engines: {node: '>=0.12'} dev: true + /entities/4.4.0: + resolution: {integrity: sha512-oYp7156SP8LkeGD0GF85ad1X9Ai79WtRsZ2gxJqtBuzH+98YUV6jkHEKlZkMbcrjJjIVJNIDP/3WL9wQkoPbWA==} + engines: {node: '>=0.12'} + dev: true + /error-ex/1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} dependencies: @@ -6760,7 +6695,7 @@ packages: jest-get-type: 29.0.0 jest-matcher-utils: 29.1.2 jest-message-util: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 dev: true /extend/3.0.2: @@ -8312,23 +8247,23 @@ packages: resolution: {integrity: sha512-ajQOdxY6mT9GtnfJRZBRYS7toNIJayiiyjDyoZcnvPRUPwJ58JX0ci0PKAKUo2C1RyzlHw0jabjLGKksO42JGA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.1.2 + '@jest/environment': 29.2.2 '@jest/expect': 29.1.2 '@jest/test-result': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 chalk: 4.1.2 co: 4.6.0 dedent: 0.7.0 is-generator-fn: 2.1.0 jest-each: 29.1.2 jest-matcher-utils: 29.1.2 - jest-message-util: 29.1.2 + jest-message-util: 29.2.1 jest-runtime: 29.1.2 jest-snapshot: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 p-limit: 3.1.0 - pretty-format: 29.1.2 + pretty-format: 29.2.1 slash: 3.0.0 stack-utils: 2.0.5 transitivePeerDependencies: @@ -8347,13 +8282,13 @@ packages: dependencies: '@jest/core': 29.1.2 '@jest/test-result': 29.1.2 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 jest-config: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 prompts: 2.4.2 yargs: 17.6.0 @@ -8375,13 +8310,13 @@ packages: dependencies: '@jest/core': 29.1.2 '@jest/test-result': 29.1.2 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 jest-config: 29.1.2_@types+node@16.11.12 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 prompts: 2.4.2 yargs: 17.6.0 @@ -8403,13 +8338,13 @@ packages: dependencies: '@jest/core': 29.1.2_ts-node@10.9.1 '@jest/test-result': 29.1.2 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 chalk: 4.1.2 exit: 0.1.2 graceful-fs: 4.2.10 import-local: 3.1.0 jest-config: 29.1.2_k5ytkvaprncdyzidqqws5bqksq - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 prompts: 2.4.2 yargs: 17.6.0 @@ -8433,7 +8368,7 @@ packages: dependencies: '@babel/core': 7.19.3 '@jest/test-sequencer': 29.1.2 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 babel-jest: 29.1.2_@babel+core@7.19.3 chalk: 4.1.2 ci-info: 3.5.0 @@ -8446,57 +8381,17 @@ packages: jest-regex-util: 29.0.0 jest-resolve: 29.1.2 jest-runner: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.1.2 + pretty-format: 29.2.1 slash: 3.0.0 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color dev: true - /jest-config/29.1.2_7fnffnpg6qxg3uvt2vx7t77ic4: - resolution: {integrity: sha512-EC3Zi86HJUOz+2YWQcJYQXlf0zuBhJoeyxLM6vb6qJsVmpP7KcCP1JnyF0iaqTaXdBP8Rlwsvs7hnKWQWWLwwA==} - engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} - peerDependencies: - '@types/node': '*' - ts-node: '>=9.0.0' - peerDependenciesMeta: - '@types/node': - optional: true - ts-node: - optional: true - dependencies: - '@babel/core': 7.19.3 - '@jest/test-sequencer': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 - babel-jest: 29.1.2_@babel+core@7.19.3 - chalk: 4.1.2 - ci-info: 3.5.0 - deepmerge: 4.2.2 - glob: 7.2.3 - graceful-fs: 4.2.10 - jest-circus: 29.1.2 - jest-environment-node: 29.1.2 - jest-get-type: 29.0.0 - jest-regex-util: 29.0.0 - jest-resolve: 29.1.2 - jest-runner: 29.1.2 - jest-util: 29.1.2 - jest-validate: 29.1.2 - micromatch: 4.0.5 - parse-json: 5.2.0 - pretty-format: 29.1.2 - slash: 3.0.0 - strip-json-comments: 3.1.1 - ts-node: 10.9.1_ccwudyfw5se7hgalwgkzhn2yp4 - transitivePeerDependencies: - - supports-color - dev: true - /jest-config/29.1.2_@types+node@16.11.12: resolution: {integrity: sha512-EC3Zi86HJUOz+2YWQcJYQXlf0zuBhJoeyxLM6vb6qJsVmpP7KcCP1JnyF0iaqTaXdBP8Rlwsvs7hnKWQWWLwwA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -8511,7 +8406,7 @@ packages: dependencies: '@babel/core': 7.19.3 '@jest/test-sequencer': 29.1.2 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 '@types/node': 16.11.12 babel-jest: 29.1.2_@babel+core@7.19.3 chalk: 4.1.2 @@ -8525,18 +8420,18 @@ packages: jest-regex-util: 29.0.0 jest-resolve: 29.1.2 jest-runner: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.1.2 + pretty-format: 29.2.1 slash: 3.0.0 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color dev: true - /jest-config/29.1.2_@types+node@16.11.65: + /jest-config/29.1.2_@types+node@17.0.23: resolution: {integrity: sha512-EC3Zi86HJUOz+2YWQcJYQXlf0zuBhJoeyxLM6vb6qJsVmpP7KcCP1JnyF0iaqTaXdBP8Rlwsvs7hnKWQWWLwwA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} peerDependencies: @@ -8550,8 +8445,8 @@ packages: dependencies: '@babel/core': 7.19.3 '@jest/test-sequencer': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 babel-jest: 29.1.2_@babel+core@7.19.3 chalk: 4.1.2 ci-info: 3.5.0 @@ -8564,17 +8459,57 @@ packages: jest-regex-util: 29.0.0 jest-resolve: 29.1.2 jest-runner: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.1.2 + pretty-format: 29.2.1 slash: 3.0.0 strip-json-comments: 3.1.1 transitivePeerDependencies: - supports-color dev: true + /jest-config/29.1.2_hvivgrlmkyd4vgu6rkkmg6acly: + resolution: {integrity: sha512-EC3Zi86HJUOz+2YWQcJYQXlf0zuBhJoeyxLM6vb6qJsVmpP7KcCP1JnyF0iaqTaXdBP8Rlwsvs7hnKWQWWLwwA==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + '@types/node': '*' + ts-node: '>=9.0.0' + peerDependenciesMeta: + '@types/node': + optional: true + ts-node: + optional: true + dependencies: + '@babel/core': 7.19.3 + '@jest/test-sequencer': 29.1.2 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 + babel-jest: 29.1.2_@babel+core@7.19.3 + chalk: 4.1.2 + ci-info: 3.5.0 + deepmerge: 4.2.2 + glob: 7.2.3 + graceful-fs: 4.2.10 + jest-circus: 29.1.2 + jest-environment-node: 29.1.2 + jest-get-type: 29.0.0 + jest-regex-util: 29.0.0 + jest-resolve: 29.1.2 + jest-runner: 29.1.2 + jest-util: 29.2.1 + jest-validate: 29.1.2 + micromatch: 4.0.5 + parse-json: 5.2.0 + pretty-format: 29.2.1 + slash: 3.0.0 + strip-json-comments: 3.1.1 + ts-node: 10.9.1_ccwudyfw5se7hgalwgkzhn2yp4 + transitivePeerDependencies: + - supports-color + dev: true + /jest-config/29.1.2_k5ytkvaprncdyzidqqws5bqksq: resolution: {integrity: sha512-EC3Zi86HJUOz+2YWQcJYQXlf0zuBhJoeyxLM6vb6qJsVmpP7KcCP1JnyF0iaqTaXdBP8Rlwsvs7hnKWQWWLwwA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -8589,7 +8524,7 @@ packages: dependencies: '@babel/core': 7.19.3 '@jest/test-sequencer': 29.1.2 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 '@types/node': 16.11.12 babel-jest: 29.1.2_@babel+core@7.19.3 chalk: 4.1.2 @@ -8603,11 +8538,11 @@ packages: jest-regex-util: 29.0.0 jest-resolve: 29.1.2 jest-runner: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 micromatch: 4.0.5 parse-json: 5.2.0 - pretty-format: 29.1.2 + pretty-format: 29.2.1 slash: 3.0.0 strip-json-comments: 3.1.1 ts-node: 10.9.1_ccwudyfw5se7hgalwgkzhn2yp4 @@ -8651,28 +8586,32 @@ packages: resolution: {integrity: sha512-AmTQp9b2etNeEwMyr4jc0Ql/LIX/dhbgP21gHAizya2X6rUspHn2gysMXaj6iwWuOJ2sYRgP8c1P4cXswgvS1A==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 chalk: 4.1.2 jest-get-type: 29.0.0 - jest-util: 29.1.2 - pretty-format: 29.1.2 + jest-util: 29.2.1 + pretty-format: 29.2.1 dev: true - /jest-environment-jsdom/28.1.3: - resolution: {integrity: sha512-HnlGUmZRdxfCByd3GM2F100DgQOajUBzEitjGqIREcb45kGjZvRrKUdlaF6escXBdcXNl0OBh+1ZrfeZT3GnAg==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + /jest-environment-jsdom/29.2.2: + resolution: {integrity: sha512-5mNtTcky1+RYv9kxkwMwt7fkzyX4EJUarV7iI+NQLigpV4Hz4sgfOdP4kOpCHXbkRWErV7tgXoXLm2CKtucr+A==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + peerDependencies: + canvas: ^2.5.0 + peerDependenciesMeta: + canvas: + optional: true dependencies: - '@jest/environment': 28.1.3 - '@jest/fake-timers': 28.1.3 - '@jest/types': 28.1.3 - '@types/jsdom': 16.2.15 + '@jest/environment': 29.2.2 + '@jest/fake-timers': 29.2.2 + '@jest/types': 29.2.1 + '@types/jsdom': 20.0.0 '@types/node': 17.0.23 - jest-mock: 28.1.3 - jest-util: 28.1.3 - jsdom: 19.0.0 + jest-mock: 29.2.2 + jest-util: 29.2.1 + jsdom: 20.0.2 transitivePeerDependencies: - bufferutil - - canvas - supports-color - utf-8-validate dev: true @@ -8693,12 +8632,12 @@ packages: resolution: {integrity: sha512-C59yVbdpY8682u6k/lh8SUMDJPbOyCHOTgLVVi1USWFxtNV+J8fyIwzkg+RJIVI30EKhKiAGNxYaFr3z6eyNhQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.1.2 - '@jest/fake-timers': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 - jest-mock: 29.1.2 - jest-util: 29.1.2 + '@jest/environment': 29.2.2 + '@jest/fake-timers': 29.2.2 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 + jest-mock: 29.2.2 + jest-util: 29.2.1 dev: true /jest-environment-puppeteer/6.1.1: @@ -8723,14 +8662,14 @@ packages: resolution: {integrity: sha512-xSjbY8/BF11Jh3hGSPfYTa/qBFrm3TPM7WU8pU93m2gqzORVLkHFWvuZmFsTEBPRKndfewXhMOuzJNHyJIZGsw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 '@types/graceful-fs': 4.1.5 - '@types/node': 16.11.65 + '@types/node': 17.0.23 anymatch: 3.1.2 fb-watchman: 2.0.2 graceful-fs: 4.2.10 jest-regex-util: 29.0.0 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-worker: 29.1.2 micromatch: 4.0.5 walker: 1.0.8 @@ -8743,7 +8682,7 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: jest-get-type: 29.0.0 - pretty-format: 29.1.2 + pretty-format: 29.2.1 dev: true /jest-matcher-specific-error/1.0.0: @@ -8764,7 +8703,7 @@ packages: resolution: {integrity: sha512-rMyFe1+jnyAAf+NHwTclDz0eAaLkVDdKVHHBFWsBWHnnh5YeJMNWWsv7AbFYXfK3oTqvL7VTWkhNLu1jX24D+g==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} dependencies: - '@babel/code-frame': 7.16.7 + '@babel/code-frame': 7.18.6 '@jest/types': 27.5.1 '@types/stack-utils': 2.0.1 chalk: 4.1.2 @@ -8775,27 +8714,12 @@ packages: stack-utils: 2.0.5 dev: true - /jest-message-util/28.1.3: - resolution: {integrity: sha512-PFdn9Iewbt575zKPf1286Ht9EPoJmYT7P0kY+RibeYZ2XtOr53pDLEFoTWXbd1h4JiGiWpTBC84fc8xMXQMb7g==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@babel/code-frame': 7.18.6 - '@jest/types': 28.1.3 - '@types/stack-utils': 2.0.1 - chalk: 4.1.2 - graceful-fs: 4.2.10 - micromatch: 4.0.5 - pretty-format: 28.1.3 - slash: 3.0.0 - stack-utils: 2.0.5 - dev: true - /jest-message-util/29.1.2: resolution: {integrity: sha512-9oJ2Os+Qh6IlxLpmvshVbGUiSkZVc2FK+uGOm6tghafnB2RyjKAxMZhtxThRMxfX1J1SOMhTn9oK3/MutRWQJQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@babel/code-frame': 7.18.6 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 '@types/stack-utils': 2.0.1 chalk: 4.1.2 graceful-fs: 4.2.10 @@ -8805,6 +8729,21 @@ packages: stack-utils: 2.0.5 dev: true + /jest-message-util/29.2.1: + resolution: {integrity: sha512-Dx5nEjw9V8C1/Yj10S/8ivA8F439VS8vTq1L7hEgwHFn9ovSKNpYW/kwNh7UglaEgXO42XxzKJB+2x0nSglFVw==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} + dependencies: + '@babel/code-frame': 7.18.6 + '@jest/types': 29.2.1 + '@types/stack-utils': 2.0.1 + chalk: 4.1.2 + graceful-fs: 4.2.10 + micromatch: 4.0.5 + pretty-format: 29.2.1 + slash: 3.0.0 + stack-utils: 2.0.5 + dev: true + /jest-mock/27.5.1: resolution: {integrity: sha512-K4jKbY1d4ENhbrG2zuPWaQBvDly+iZ2yAW+T1fATN78hc0sInwn7wZB8XtlNnvHug5RMwV897Xm4LqmPM4e2Og==} engines: {node: ^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0} @@ -8813,21 +8752,13 @@ packages: '@types/node': 17.0.23 dev: true - /jest-mock/28.1.3: - resolution: {integrity: sha512-o3J2jr6dMMWYVH4Lh/NKmDXdosrsJgi4AviS8oXLujcjpCMBb1FMsblDnOXKZKfSiHLxYub1eS0IHuRXsio9eA==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 17.0.23 - dev: true - - /jest-mock/29.1.2: - resolution: {integrity: sha512-PFDAdjjWbjPUtQPkQufvniXIS3N9Tv7tbibePEjIIprzjgo0qQlyUiVMrT4vL8FaSJo1QXifQUOuPH3HQC/aMA==} + /jest-mock/29.2.2: + resolution: {integrity: sha512-1leySQxNAnivvbcx0sCB37itu8f4OX2S/+gxLAV4Z62shT4r4dTG9tACDywUAEZoLSr36aYUTsVp3WKwWt4PMQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.2 - '@types/node': 16.11.65 - jest-util: 29.1.2 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 + jest-util: 29.2.1 dev: true /jest-pnp-resolver/1.2.2_jest-resolve@29.1.2: @@ -8878,7 +8809,7 @@ packages: graceful-fs: 4.2.10 jest-haste-map: 29.1.2 jest-pnp-resolver: 1.2.2_jest-resolve@29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-validate: 29.1.2 resolve: 1.22.1 resolve.exports: 1.1.0 @@ -8890,11 +8821,11 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/console': 29.1.2 - '@jest/environment': 29.1.2 + '@jest/environment': 29.2.2 '@jest/test-result': 29.1.2 '@jest/transform': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 chalk: 4.1.2 emittery: 0.10.2 graceful-fs: 4.2.10 @@ -8902,10 +8833,10 @@ packages: jest-environment-node: 29.1.2 jest-haste-map: 29.1.2 jest-leak-detector: 29.1.2 - jest-message-util: 29.1.2 + jest-message-util: 29.2.1 jest-resolve: 29.1.2 jest-runtime: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 jest-watcher: 29.1.2 jest-worker: 29.1.2 p-limit: 3.1.0 @@ -8918,26 +8849,26 @@ packages: resolution: {integrity: sha512-jr8VJLIf+cYc+8hbrpt412n5jX3tiXmpPSYTGnwcvNemY+EOuLNiYnHJ3Kp25rkaAcTWOEI4ZdOIQcwYcXIAZw==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/environment': 29.1.2 - '@jest/fake-timers': 29.1.2 + '@jest/environment': 29.2.2 + '@jest/fake-timers': 29.2.2 '@jest/globals': 29.1.2 '@jest/source-map': 29.0.0 '@jest/test-result': 29.1.2 '@jest/transform': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 chalk: 4.1.2 cjs-module-lexer: 1.2.2 collect-v8-coverage: 1.0.1 glob: 7.2.3 graceful-fs: 4.2.10 jest-haste-map: 29.1.2 - jest-message-util: 29.1.2 - jest-mock: 29.1.2 + jest-message-util: 29.2.1 + jest-mock: 29.2.2 jest-regex-util: 29.0.0 jest-resolve: 29.1.2 jest-snapshot: 29.1.2 - jest-util: 29.1.2 + jest-util: 29.2.1 slash: 3.0.0 strip-bom: 4.0.0 transitivePeerDependencies: @@ -8956,7 +8887,7 @@ packages: '@babel/types': 7.19.4 '@jest/expect-utils': 29.1.2 '@jest/transform': 29.1.2 - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 '@types/babel__traverse': 7.18.2 '@types/prettier': 2.7.1 babel-preset-current-node-syntax: 1.0.1_@babel+core@7.19.3 @@ -8967,10 +8898,10 @@ packages: jest-get-type: 29.0.0 jest-haste-map: 29.1.2 jest-matcher-utils: 29.1.2 - jest-message-util: 29.1.2 - jest-util: 29.1.2 + jest-message-util: 29.2.1 + jest-util: 29.2.1 natural-compare: 1.4.0 - pretty-format: 29.1.2 + pretty-format: 29.2.1 semver: 7.3.8 transitivePeerDependencies: - supports-color @@ -8997,29 +8928,17 @@ packages: '@jest/types': 27.5.1 '@types/node': 17.0.23 chalk: 4.1.2 - ci-info: 3.3.2 - graceful-fs: 4.2.10 - picomatch: 2.3.1 - dev: true - - /jest-util/28.1.3: - resolution: {integrity: sha512-XdqfpHwpcSRko/C35uLYFM2emRAltIIKZiJ9eAmhjsj0CqZMa0p1ib0R5fWIqGhn1a103DebTbpqIaP1qCQ6tQ==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} - dependencies: - '@jest/types': 28.1.3 - '@types/node': 17.0.23 - chalk: 4.1.2 ci-info: 3.5.0 graceful-fs: 4.2.10 picomatch: 2.3.1 dev: true - /jest-util/29.1.2: - resolution: {integrity: sha512-vPCk9F353i0Ymx3WQq3+a4lZ07NXu9Ca8wya6o4Fe4/aO1e1awMMprZ3woPFpKwghEOW+UXgd15vVotuNN9ONQ==} + /jest-util/29.2.1: + resolution: {integrity: sha512-P5VWDj25r7kj7kl4pN2rG/RN2c1TLfYYYZYULnS/35nFDjBai+hBeo3MDrYZS7p6IoY3YHZnt2vq4L6mKnLk0g==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.2 - '@types/node': 16.11.65 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 chalk: 4.1.2 ci-info: 3.5.0 graceful-fs: 4.2.10 @@ -9030,12 +8949,12 @@ packages: resolution: {integrity: sha512-k71pOslNlV8fVyI+mEySy2pq9KdXdgZtm7NHrBX8LghJayc3wWZH0Yr0mtYNGaCU4F1OLPXRkwZR0dBm/ClshA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/types': 29.1.2 + '@jest/types': 29.2.1 camelcase: 6.2.1 chalk: 4.1.2 jest-get-type: 29.0.0 leven: 3.1.0 - pretty-format: 29.1.2 + pretty-format: 29.2.1 dev: true /jest-watcher/29.1.2: @@ -9043,12 +8962,12 @@ packages: engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/test-result': 29.1.2 - '@jest/types': 29.1.2 - '@types/node': 16.11.65 + '@jest/types': 29.2.1 + '@types/node': 17.0.23 ansi-escapes: 4.3.2 chalk: 4.1.2 emittery: 0.10.2 - jest-util: 29.1.2 + jest-util: 29.2.1 string-length: 4.0.2 dev: true @@ -9056,8 +8975,8 @@ packages: resolution: {integrity: sha512-AdTZJxKjTSPHbXT/AIOjQVmoFx0LHFcVabWu0sxI7PAy7rFf8c0upyvgBKgguVXdM4vY74JdwkyD4hSmpTW8jA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@types/node': 16.11.65 - jest-util: 29.1.2 + '@types/node': 17.0.23 + jest-util: 29.2.1 merge-stream: 2.0.0 supports-color: 8.1.1 dev: true @@ -9161,9 +9080,9 @@ packages: dependencies: argparse: 2.0.1 - /jsdom/19.0.0: - resolution: {integrity: sha512-RYAyjCbxy/vri/CfnjUWJQQtZ3LKlLnDqj+9XLNnJPgEGeirZs3hllKR20re8LUZ6o1b1X4Jat+Qd26zmP41+A==} - engines: {node: '>=12'} + /jsdom/20.0.2: + resolution: {integrity: sha512-AHWa+QO/cgRg4N+DsmHg1Y7xnz+8KU3EflM0LVDTdmrYOc1WWTSkOjtpUveQH+1Bqd5rtcVnb/DuxV/UjDO4rA==} + engines: {node: '>=14'} peerDependencies: canvas: ^2.5.0 peerDependenciesMeta: @@ -9172,11 +9091,11 @@ packages: dependencies: abab: 2.0.6 acorn: 8.8.0 - acorn-globals: 6.0.0 + acorn-globals: 7.0.1 cssom: 0.5.0 cssstyle: 2.3.0 data-urls: 3.0.2 - decimal.js: 10.3.1 + decimal.js: 10.4.2 domexception: 4.0.0 escodegen: 2.0.0 form-data: 4.0.0 @@ -9184,18 +9103,17 @@ packages: http-proxy-agent: 5.0.0 https-proxy-agent: 5.0.1 is-potential-custom-element-name: 1.0.1 - nwsapi: 2.2.1 - parse5: 6.0.1 - saxes: 5.0.1 + nwsapi: 2.2.2 + parse5: 7.1.1 + saxes: 6.0.0 symbol-tree: 3.2.4 - tough-cookie: 4.0.0 - w3c-hr-time: 1.0.2 + tough-cookie: 4.1.2 w3c-xmlserializer: 3.0.0 webidl-conversions: 7.0.0 whatwg-encoding: 2.0.0 whatwg-mimetype: 3.0.0 - whatwg-url: 10.0.0 - ws: 8.8.1 + whatwg-url: 11.0.0 + ws: 8.10.0 xml-name-validator: 4.0.0 transitivePeerDependencies: - bufferutil @@ -10222,20 +10140,10 @@ packages: picomatch: 2.3.1 dev: true - /mime-db/1.51.0: - resolution: {integrity: sha512-5y8A56jg7XVQx2mbv1lu49NR4dokRnhZYTtL+KGfaa27uq4pSTXkwQkFJl4pkRMyNFz/EtYDSkiiEHx3F7UN6g==} - engines: {node: '>= 0.6'} - /mime-db/1.52.0: resolution: {integrity: sha512-sPU4uV7dYlvtWJxwwxHD0PuihVNiE7TyAbQ5SWxDCB9mUYvOgroQOwYQQOKPJ8CIbE+1ETVlOoK1UC2nU3gYvg==} engines: {node: '>= 0.6'} - /mime-types/2.1.34: - resolution: {integrity: sha512-6cP692WwGIs9XXdOO4++N+7qjqv0rqxxVvJ3VHPh/Sc9mVZcQP+ZGhkKiTvWMQRr2tbHkJP/Yn7Y0npb3ZBs4A==} - engines: {node: '>= 0.6'} - dependencies: - mime-db: 1.51.0 - /mime-types/2.1.35: resolution: {integrity: sha512-ZDY+bPm5zTTF+YpCrAU9nK0UgICYPT0QtT1NZWFv4s++TNkcgVaT0g6+4R2uI4MjQjzysHB1zxuWL50hzaeXiw==} engines: {node: '>= 0.6'} @@ -10627,8 +10535,8 @@ packages: resolution: {integrity: sha512-2vPPEi+Z7WqML2jZYddDIfy5Dqb0r2fze2zTxNNknZaFpVHU3mFB3R+DWeJWGVx0ecvttSGlJTI+WG+8Z4cDWw==} dev: true - /nwsapi/2.2.1: - resolution: {integrity: sha512-JYOWTeFoS0Z93587vRJgASD5Ut11fYl5NyihP3KrYBvMe1FRRs6RN7m20SA/16GM4P6hTnZjT+UmDOt38UeXNg==} + /nwsapi/2.2.2: + resolution: {integrity: sha512-90yv+6538zuvUMnN+zCr8LuV6bPFdq50304114vJYJ8RDyK8D5O9Phpbd6SZWgI7PwzmmfN1upeOJlvybDSgCw==} dev: true /obj-props/1.4.0: @@ -11008,6 +10916,12 @@ packages: resolution: {integrity: sha512-Ofn/CTFzRGTTxwpNEs9PP93gXShHcTq255nzRYSKe8AkVpZY7e1fpmTfOyoIvjP5HG7Z2ZM7VS9PPhQGW2pOpw==} dev: true + /parse5/7.1.1: + resolution: {integrity: sha512-kwpuwzB+px5WUg9pyK0IcK/shltJN5/OVhQagxhCQNtT9Y9QRZqNY2e1cmbu/paRh5LMnz/oVTVLBpjFmMZhSg==} + dependencies: + entities: 4.4.0 + dev: true + /parseurl/1.3.3: resolution: {integrity: sha512-CiyeOxFT/JZyN5m0z9PfXw4SCBJ6Sygz1Dpl0wqjlhDEGGBP1GnsUVEL0p63hoG1fcj3fHynXi9NYO4nWOL+qQ==} engines: {node: '>= 0.8'} @@ -11493,18 +11407,17 @@ packages: react-is: 17.0.2 dev: true - /pretty-format/28.1.3: - resolution: {integrity: sha512-8gFb/To0OmxHR9+ZTb14Df2vNxdGCX8g1xWGUTqUw5TiZvcQf5sHKObd5UcPyLLyowNwDAMTF3XWOG1B6mxl1Q==} - engines: {node: ^12.13.0 || ^14.15.0 || ^16.10.0 || >=17.0.0} + /pretty-format/29.1.2: + resolution: {integrity: sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==} + engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: - '@jest/schemas': 28.1.3 - ansi-regex: 5.0.1 + '@jest/schemas': 29.0.0 ansi-styles: 5.2.0 react-is: 18.2.0 dev: true - /pretty-format/29.1.2: - resolution: {integrity: sha512-CGJ6VVGXVRP2o2Dorl4mAwwvDWT25luIsYhkyVQW32E4nL+TgW939J7LlKT/npq5Cpq6j3s+sy+13yk7xYpBmg==} + /pretty-format/29.2.1: + resolution: {integrity: sha512-Y41Sa4aLCtKAXvwuIpTvcFBkyeYp2gdFWzXGA+ZNES3VwURIB165XO/z7CjETwzCCS53MjW/rLMyyqEnTtaOfA==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} dependencies: '@jest/schemas': 29.0.0 @@ -11674,6 +11587,10 @@ packages: strict-uri-encode: 2.0.0 dev: false + /querystringify/2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: true + /queue-microtask/1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} dev: true @@ -12238,8 +12155,7 @@ packages: dev: true /requires-port/1.0.0: - resolution: {integrity: sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=} - dev: false + resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} /resolve-alpn/1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -12417,9 +12333,9 @@ packages: source-map-js: 1.0.2 dev: true - /saxes/5.0.1: - resolution: {integrity: sha512-5LBh1Tls8c9xgGjw3QrMwETmTMVk0oFgvrFSvWx62llR2hcEInrKNZ2GZCCuuy2lvWrdl5jhbpeqc5hRYKFOcw==} - engines: {node: '>=10'} + /saxes/6.0.0: + resolution: {integrity: sha512-xAg7SOnEhrm5zI3puOOKyy1OMcMlIJZYNJY7xLBwSze0UjhPLnWfj2GF2EpT0jmzaJKIWKHLsaSSajf35bcYnA==} + engines: {node: '>=v12.22.7'} dependencies: xmlchars: 2.2.0 dev: true @@ -13443,13 +13359,14 @@ packages: nopt: 1.0.10 dev: true - /tough-cookie/4.0.0: - resolution: {integrity: sha512-tHdtEpQCMrc1YLrMaqXXcj6AxhYi/xgit6mZu1+EDWUn+qhUf8wMQoFIy9NXuq23zAwtcB0t/MjACGR18pcRbg==} + /tough-cookie/4.1.2: + resolution: {integrity: sha512-G9fqXWoYFZgTc2z8Q5zaHy/vJMjm+WV0AkAeHxVCQiEB1b+dGvWzFW6QV07cY5jQ5gRkeid2qIkzkxUnmoQZUQ==} engines: {node: '>=6'} dependencies: psl: 1.9.0 punycode: 2.1.1 - universalify: 0.1.2 + universalify: 0.2.0 + url-parse: 1.5.10 dev: true /tr46/0.0.3: @@ -13519,7 +13436,7 @@ packages: bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 jest: 29.1.2_k5ytkvaprncdyzidqqws5bqksq - jest-util: 29.1.2 + jest-util: 29.2.1 json5: 2.2.1 lodash.memoize: 4.1.2 make-error: 1.3.6 @@ -13548,7 +13465,7 @@ packages: '@tsconfig/node14': 1.0.1 '@tsconfig/node16': 1.0.2 '@types/node': 17.0.23 - acorn: 8.7.0 + acorn: 8.8.0 acorn-walk: 8.2.0 arg: 4.1.3 create-require: 1.1.1 @@ -13877,6 +13794,11 @@ packages: engines: {node: '>= 4.0.0'} dev: true + /universalify/0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + dev: true + /universalify/2.0.0: resolution: {integrity: sha512-hAZsKq7Yy11Zu1DE0OzWjw7nnLZmJZYTDZZyEFHZdUhV8FkH5MCfoU1XMaxXovpyW5nq5scPqq0ZDP9Zyl04oQ==} engines: {node: '>= 10.0.0'} @@ -13907,6 +13829,13 @@ packages: dependencies: punycode: 2.1.1 + /url-parse/1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: true + /use-debounced-loader/0.1.1_react@18.2.0: resolution: {integrity: sha512-FbY/ynor7wZV55v1EvvAvu8CvSoEKT1azS2zFb/aLlL0vySbqTM7x9fIcaOJN++E52mVINNDe2VmWWd+Q00S+A==} engines: {node: '>=10'} @@ -14011,12 +13940,6 @@ packages: engines: {node: '>=0.10.0'} dev: true - /w3c-hr-time/1.0.2: - resolution: {integrity: sha512-z8P5DvDNjKDoFIHK7q8r8lackT6l+jo/Ye3HOle7l9nICP9lf1Ci25fy9vHd0JOWewkIFzXIEig3TdKT7JQ5fQ==} - dependencies: - browser-process-hrtime: 1.0.0 - dev: true - /w3c-xmlserializer/3.0.0: resolution: {integrity: sha512-3WFqGEgSXIyGhOmAFtlicJNMjEps8b1MG31NCA0/vOF9+nKMUW1ckhi9cnNHmf88Rzw5V+dwIwsm2C7X8k9aQg==} engines: {node: '>=12'} @@ -14097,14 +14020,6 @@ packages: engines: {node: '>=12'} dev: true - /whatwg-url/10.0.0: - resolution: {integrity: sha512-CLxxCmdUby142H5FZzn4D8ikO1cmypvXVQktsgosNy4a4BHrDHeciBBGZhb0bNoR5/MltoCatso+vFjjGx8t0w==} - engines: {node: '>=12'} - dependencies: - tr46: 3.0.0 - webidl-conversions: 7.0.0 - dev: true - /whatwg-url/11.0.0: resolution: {integrity: sha512-RKT8HExMpoYx4igMiVMY83lN6UeITKJlBQ+vR/8ZJ8OCdSiN3RwCq+9gH0+Xzj0+5IrM6i4j/6LuvzbZIQgEcQ==} engines: {node: '>=12'} @@ -14204,6 +14119,19 @@ packages: signal-exit: 3.0.7 dev: true + /ws/8.10.0: + resolution: {integrity: sha512-+s49uSmZpvtAsd2h37vIPy1RBusaLawVe8of+GyEPsaJTCMpj/2v8NpeK1SHXjBlQ95lQTmQofOJnFiLoaN3yw==} + engines: {node: '>=10.0.0'} + peerDependencies: + bufferutil: ^4.0.1 + utf-8-validate: ^5.0.2 + peerDependenciesMeta: + bufferutil: + optional: true + utf-8-validate: + optional: true + dev: true + /ws/8.8.1: resolution: {integrity: sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==} engines: {node: '>=10.0.0'} From 8e45325e988f985cb0333bf0cf1c9394317e09b1 Mon Sep 17 00:00:00 2001 From: "renovate[bot]" <29139614+renovate[bot]@users.noreply.github.com> Date: Fri, 4 Nov 2022 04:19:20 +0000 Subject: [PATCH 05/19] chore(deps): update dependency puppeteer to v19 (#2164) Co-authored-by: renovate[bot] <29139614+renovate[bot]@users.noreply.github.com> Co-authored-by: Gao Sun --- .github/workflows/integration-test.yml | 14 +++++++ packages/integration-tests/package.json | 2 +- pnpm-lock.yaml | 55 +++++++++++++------------ 3 files changed, 44 insertions(+), 27 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 110ce31e5..f2483f27d 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -18,6 +18,13 @@ jobs: steps: - uses: actions/checkout@v3 + - name: Cache Puppeteer + uses: actions/cache@v3 + with: + # https://pptr.dev/guides/configuration/#changing-the-default-cache-directory + path: ~/.cache/puppeteer + key: ${{ runner.os }}-pptr-${{ hashFiles('packages/integration-tests/package.json') }} + - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v2 @@ -47,6 +54,13 @@ jobs: with: path: tests + - name: Cache Puppeteer + uses: actions/cache@v3 + with: + # https://pptr.dev/guides/configuration/#changing-the-default-cache-directory + path: ~/.cache/puppeteer + key: ${{ runner.os }}-pptr-${{ hashFiles('tests/packages/integration-tests/package.json') }} + - name: Copy lockfile run: | cp tests/pnpm-lock.yaml ./ diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index 92757976c..1b6c75726 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -34,7 +34,7 @@ "openapi-schema-validator": "^12.0.0", "openapi-types": "^12.0.0", "prettier": "^2.7.1", - "puppeteer": "^18.0.0", + "puppeteer": "^19.0.0", "text-encoder": "^0.0.4", "ts-node": "^10.9.1", "typescript": "^4.7.4" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 2d7e2df48..ba76cd4de 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -481,7 +481,7 @@ importers: openapi-schema-validator: ^12.0.0 openapi-types: ^12.0.0 prettier: ^2.7.1 - puppeteer: ^18.0.0 + puppeteer: ^19.0.0 text-encoder: ^0.0.4 ts-node: ^10.9.1 typescript: ^4.7.4 @@ -501,12 +501,12 @@ importers: eslint: 8.21.0 got: 11.8.3 jest: 29.1.2_k5ytkvaprncdyzidqqws5bqksq - jest-puppeteer: 6.1.1_puppeteer@18.0.0 + jest-puppeteer: 6.1.1_puppeteer@19.2.2 node-fetch: 2.6.7 openapi-schema-validator: 12.0.0 openapi-types: 12.0.0 prettier: 2.7.1 - puppeteer: 18.0.0 + puppeteer: 19.2.2 text-encoder: 0.0.4 ts-node: 10.9.1_ccwudyfw5se7hgalwgkzhn2yp4 typescript: 4.7.4 @@ -5849,8 +5849,8 @@ packages: resolution: {integrity: sha512-T0NIuQpnTvFDATNuHN5roPwSBG83rFsuO+MXXH9/3N1eFbn4wcPjttvjMLEPWJ0RGUYgQE7cGgS3tNxbqCGM7g==} dev: false - /devtools-protocol/0.0.1036444: - resolution: {integrity: sha512-0y4f/T8H9lsESV9kKP1HDUXgHxCdniFeJh6Erq+FbdOEvp/Ydp9t8kcAAM5gOd17pMrTDlFWntoHtzzeTUWKNw==} + /devtools-protocol/0.0.1056733: + resolution: {integrity: sha512-CmTu6SQx2g3TbZzDCAV58+LTxVdKplS7xip0g5oDXpZ+isr0rv5dDP8ToyVRywzPHkCCPKgKgScEcwz4uPWDIA==} dev: true /dezalgo/1.0.3: @@ -8773,14 +8773,14 @@ packages: jest-resolve: 29.1.2 dev: true - /jest-puppeteer/6.1.1_puppeteer@18.0.0: + /jest-puppeteer/6.1.1_puppeteer@19.2.2: resolution: {integrity: sha512-cBOszleUpyipDMNYmcmH3x+687x03ZvOVz7W8X5y5TgD+j4MK+BcumwGdE1YwVS21kPLjJUu1pIdEzEDuFEBfA==} peerDependencies: puppeteer: '>= 1.5.0' dependencies: expect-puppeteer: 6.1.1 jest-environment-puppeteer: 6.1.1 - puppeteer: 18.0.0 + puppeteer: 19.2.2 transitivePeerDependencies: - debug - supports-color @@ -11520,22 +11520,38 @@ packages: resolution: {integrity: sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==} engines: {node: '>=6'} - /puppeteer/18.0.0: - resolution: {integrity: sha512-g87rnbVwRbIJF3J2399jq7bic2TSJXxv6ysaPRi61pnwHf7eVm97YO3fEIldgVKWO/nxND192YWfhaeKjkcfOg==} + /puppeteer-core/19.2.2: + resolution: {integrity: sha512-faojf+1pZ/tHXSr4x1q+9MVd9FrL3rpdbC0w7qN7MNClMoLuCvMbpR4vzcjoiJYgclt1n+SOPUOmHQViTw6frw==} engines: {node: '>=14.1.0'} - requiresBuild: true dependencies: cross-fetch: 3.1.5 debug: 4.3.4 - devtools-protocol: 0.0.1036444 + devtools-protocol: 0.0.1056733 extract-zip: 2.0.1 https-proxy-agent: 5.0.1 - progress: 2.0.3 proxy-from-env: 1.1.0 rimraf: 3.0.2 tar-fs: 2.1.1 unbzip2-stream: 1.4.3 - ws: 8.8.1 + ws: 8.10.0 + transitivePeerDependencies: + - bufferutil + - encoding + - supports-color + - utf-8-validate + dev: true + + /puppeteer/19.2.2: + resolution: {integrity: sha512-m1T5Mog5qu5+dMBptWYTn6pXRdnFbydbVUCthqwbfd8/kOiMlzZBR9ywjX79LpvI1Sj+/z8+FKeIsjnMul8ZYA==} + engines: {node: '>=14.1.0'} + requiresBuild: true + dependencies: + cosmiconfig: 7.0.1 + devtools-protocol: 0.0.1056733 + https-proxy-agent: 5.0.1 + progress: 2.0.3 + proxy-from-env: 1.1.0 + puppeteer-core: 19.2.2 transitivePeerDependencies: - bufferutil - encoding @@ -14132,19 +14148,6 @@ packages: optional: true dev: true - /ws/8.8.1: - resolution: {integrity: sha512-bGy2JzvzkPowEJV++hF07hAD6niYSr0JzBNo/J29WsB57A2r7Wlc1UFcTR9IzrPvuNVO4B8LGqF8qcpsVOhJCA==} - engines: {node: '>=10.0.0'} - peerDependencies: - bufferutil: ^4.0.1 - utf-8-validate: ^5.0.2 - peerDependenciesMeta: - bufferutil: - optional: true - utf-8-validate: - optional: true - dev: true - /xml-name-validator/4.0.0: resolution: {integrity: sha512-ICP2e+jsHvAj2E2lIHxa5tjXRlKDJo4IdvPvCXbXQGdzSfmSpNVyIKMvoZHjDY9DP0zV17iI85o90vRFXNccRw==} engines: {node: '>=12'} From 68f2d56a2432299dd8f9a4731f857feb6b5537fd Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Fri, 4 Nov 2022 22:23:26 +0800 Subject: [PATCH 06/19] chore: add German language changeset (#2324) --- .changeset/config.json | 7 ------- .changeset/fifty-balloons-taste.md | 6 ++++++ .changeset/pre.json | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) create mode 100644 .changeset/fifty-balloons-taste.md create mode 100644 .changeset/pre.json diff --git a/.changeset/config.json b/.changeset/config.json index a408d2fa2..99aa3618b 100644 --- a/.changeset/config.json +++ b/.changeset/config.json @@ -12,13 +12,6 @@ "@logto/integration-tests", "@logto/ui" ]], - "//": "Ignore other release group members, only keep the major one.", - "ignore": [ - "@logto/create", - "@logto/console", - "@logto/integration-tests", - "@logto/ui" - ], "linked": [[ "@logto/phrases", "@logto/phrases-ui", diff --git a/.changeset/fifty-balloons-taste.md b/.changeset/fifty-balloons-taste.md new file mode 100644 index 000000000..8534ffa27 --- /dev/null +++ b/.changeset/fifty-balloons-taste.md @@ -0,0 +1,6 @@ +--- +"@logto/phrases": minor +"@logto/phrases-ui": minor +--- + +Add German language diff --git a/.changeset/pre.json b/.changeset/pre.json new file mode 100644 index 000000000..0b939e470 --- /dev/null +++ b/.changeset/pre.json @@ -0,0 +1,18 @@ +{ + "mode": "pre", + "tag": "beta", + "initialVersions": { + "@logto/cli": "1.0.0-beta.12", + "@logto/console": "1.0.0-beta.12", + "@logto/core": "1.0.0-beta.12", + "@logto/create": "1.0.0-beta.12", + "@logto/demo-app": "1.0.0-beta.12", + "@logto/integration-tests": "1.0.0-beta.12", + "@logto/phrases": "1.0.0-beta.12", + "@logto/phrases-ui": "1.0.0-beta.12", + "@logto/schemas": "1.0.0-beta.12", + "@logto/shared": "1.0.0-beta.12", + "@logto/ui": "1.0.0-beta.12" + }, + "changesets": [] +} From 877eb892c94115be0249172a78f1356590fffc39 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Fri, 4 Nov 2022 22:25:58 +0800 Subject: [PATCH 07/19] refactor(core): use `isTrue()` to check params (#2321) --- packages/core/src/env-set/parameters.ts | 6 ++++-- packages/core/src/middleware/koa-guard.ts | 4 ++-- packages/core/src/routes/admin-user.ts | 10 ++++++---- 3 files changed, 12 insertions(+), 8 deletions(-) diff --git a/packages/core/src/env-set/parameters.ts b/packages/core/src/env-set/parameters.ts index bd7157a04..d4fad5e6b 100644 --- a/packages/core/src/env-set/parameters.ts +++ b/packages/core/src/env-set/parameters.ts @@ -1,2 +1,4 @@ -export const isTrue = (value: string) => - ['1', 'true', 'y', 'yes', 'yep', 'yeah'].includes(value.toLowerCase()); +export const isTrue = (value?: string) => + // We need to leverage the native type guard + // eslint-disable-next-line no-implicit-coercion + !!value && ['1', 'true', 'y', 'yes', 'yep', 'yeah'].includes(value.toLowerCase()); diff --git a/packages/core/src/middleware/koa-guard.ts b/packages/core/src/middleware/koa-guard.ts index af8efe14a..45ad13c74 100644 --- a/packages/core/src/middleware/koa-guard.ts +++ b/packages/core/src/middleware/koa-guard.ts @@ -3,7 +3,7 @@ import { has } from '@silverhand/essentials'; import type { MiddlewareType } from 'koa'; import koaBody from 'koa-body'; import type { IMiddleware, IRouterParamContext } from 'koa-router'; -import type { ZodType } from 'zod'; +import type { ZodType, ZodTypeDef } from 'zod'; import envSet from '@/env-set'; import RequestError from '@/errors/RequestError'; @@ -48,7 +48,7 @@ export const isGuardMiddleware = ( ): function_ is WithGuardConfig => function_.name === 'guardMiddleware' && has(function_, 'config'); -const tryParse = ( +const tryParse = ( type: 'query' | 'body' | 'params', guard: Optional>, data: unknown diff --git a/packages/core/src/routes/admin-user.ts b/packages/core/src/routes/admin-user.ts index 8c83437b2..7e3e4a2f4 100644 --- a/packages/core/src/routes/admin-user.ts +++ b/packages/core/src/routes/admin-user.ts @@ -4,6 +4,7 @@ import { has } from '@silverhand/essentials'; import pick from 'lodash.pick'; import { literal, object, string } from 'zod'; +import { isTrue } from '@/env-set/parameters'; import RequestError from '@/errors/RequestError'; import { encryptUserPassword, generateUserId, insertUser } from '@/lib/user'; import koaGuard from '@/middleware/koa-guard'; @@ -29,8 +30,9 @@ export default function adminUserRoutes(router: T) { koaGuard({ query: object({ search: string().optional(), - hideAdminUser: literal('true').optional(), - isCaseSensitive: literal('true').optional(), + // Use `.transform()` once the type issue fixed + hideAdminUser: string().optional(), + isCaseSensitive: string().optional(), }), }), async (ctx, next) => { @@ -39,8 +41,8 @@ export default function adminUserRoutes(router: T) { query: { search, hideAdminUser: _hideAdminUser, isCaseSensitive: _isCaseSensitive }, } = ctx.guard; - const hideAdminUser = _hideAdminUser === 'true'; - const isCaseSensitive = _isCaseSensitive === 'true'; + const hideAdminUser = isTrue(_hideAdminUser); + const isCaseSensitive = isTrue(_isCaseSensitive); const [{ count }, users] = await Promise.all([ countUsers(search, hideAdminUser, isCaseSensitive), findUsers(limit, offset, search, hideAdminUser, isCaseSensitive), From c680c31c944ceb32ce37a3e39d86fcc8fd3b92ae Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Sun, 6 Nov 2022 00:16:40 +0800 Subject: [PATCH 08/19] chore(core): upgrade oidc-provider --- packages/core/package.json | 4 +- pnpm-lock.yaml | 92 +++++++++++++++++++++++++------------- 2 files changed, 64 insertions(+), 32 deletions(-) diff --git a/packages/core/package.json b/packages/core/package.json index 40a987b77..5d2209b99 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -55,7 +55,7 @@ "lodash.pick": "^4.4.0", "module-alias": "^2.2.2", "nanoid": "^3.1.23", - "oidc-provider": "^7.11.3", + "oidc-provider": "^7.13.0", "p-retry": "^4.6.1", "query-string": "^7.0.1", "roarr": "^7.11.0", @@ -84,7 +84,7 @@ "@types/koa-send": "^4.1.3", "@types/lodash.pick": "^4.4.6", "@types/node": "^16.0.0", - "@types/oidc-provider": "^7.11.1", + "@types/oidc-provider": "^7.12.0", "@types/supertest": "^2.0.11", "copyfiles": "^2.4.1", "eslint": "^8.21.0", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ba76cd4de..d3676d15b 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -266,7 +266,7 @@ importers: '@types/koa-send': ^4.1.3 '@types/lodash.pick': ^4.4.6 '@types/node': ^16.0.0 - '@types/oidc-provider': ^7.11.1 + '@types/oidc-provider': ^7.12.0 '@types/supertest': ^2.0.11 chalk: ^4 clean-deep: ^3.4.0 @@ -303,7 +303,7 @@ importers: nanoid: ^3.1.23 nock: ^13.2.2 nodemon: ^2.0.19 - oidc-provider: ^7.11.3 + oidc-provider: ^7.13.0 openapi-types: ^12.0.0 p-retry: ^4.6.1 prettier: ^2.7.1 @@ -354,7 +354,7 @@ importers: lodash.pick: 4.4.0 module-alias: 2.2.2 nanoid: 3.1.30 - oidc-provider: 7.11.3 + oidc-provider: 7.13.0 p-retry: 4.6.1 query-string: 7.0.1 roarr: 7.11.0 @@ -382,7 +382,7 @@ importers: '@types/koa-send': 4.1.3 '@types/lodash.pick': 4.4.6 '@types/node': 16.11.12 - '@types/oidc-provider': 7.11.1 + '@types/oidc-provider': 7.12.0 '@types/supertest': 2.0.11 copyfiles: 2.4.1 eslint: 8.21.0 @@ -2199,8 +2199,8 @@ packages: '@jridgewell/sourcemap-codec': 1.4.14 dev: true - /@koa/cors/3.1.0: - resolution: {integrity: sha512-7ulRC1da/rBa6kj6P4g2aJfnET3z8Uf3SWu60cjbtxTA5g8lxRdX/Bd2P92EagGwwAhANeNw8T8if99rJliR6Q==} + /@koa/cors/3.4.3: + resolution: {integrity: sha512-WPXQUaAeAMVaLTEFpoq3T2O1C+FstkjJnDQqy95Ck1UdILajsRhu6mhJ8H2f4NFPRBoCNN+qywTJfq/gGki5mw==} engines: {node: '>= 8.0.0'} dependencies: vary: 1.1.2 @@ -3467,7 +3467,7 @@ packages: '@jest/types': 29.1.2 deepmerge: 4.2.2 identity-obj-proxy: 3.0.0 - jest: 29.1.2_k5ytkvaprncdyzidqqws5bqksq + jest: 29.1.2_@types+node@16.11.12 jest-matcher-specific-error: 1.0.0 jest-transform-stub: 2.0.0 ts-jest: 29.0.3_37jxomqt5oevoqzq6g3r6n3ili @@ -4076,8 +4076,8 @@ packages: resolution: {integrity: sha512-Gj7cI7z+98M282Tqmp2K5EIsoouUEzbBJhQQzDE3jSIRk6r9gsz0oUokqIUR4u1R3dMHo0pDHM7sNOHyhulypw==} dev: true - /@types/oidc-provider/7.11.1: - resolution: {integrity: sha512-qimKqQ5HmQE2HKzhTvkLC0CQcOrQZv9+VAWEBb4EL+zqIZjE4X0PiCL0177eo6kitWrIjTQhhiLc2R3luA1AlQ==} + /@types/oidc-provider/7.12.0: + resolution: {integrity: sha512-PQtsWdbjzq/AARiNu2WjPnnbiCF78BCYgDOdKW0VYsjrbDa9HN8dALt7bSIJ0O67ti1l0pYDk8UCpmUu8rPAUQ==} dependencies: '@types/koa': 2.13.4 dev: true @@ -4641,8 +4641,8 @@ packages: hasBin: true dev: true - /async/0.9.2: - resolution: {integrity: sha512-l6ToIJIotphWahxxHyzK9bnLR6kM4jJIIgLShZeqLY7iboHoGkdgFl7W2/Ivi4SkMJYGKqW8vSuk0uKUj6qsSw==} + /async/3.2.4: + resolution: {integrity: sha512-iAB+JbDEGXhyIUavoDl9WP/Jj106Kz9DEn1DPgYw5ruDn0e3Wgi3sKFm55sASdGBNOQB8F59d9qQ7deqrHA8wQ==} dev: false /asynckit/0.4.0: @@ -5981,12 +5981,12 @@ packages: /ee-first/1.1.1: resolution: {integrity: sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0=} - /ejs/3.1.6: - resolution: {integrity: sha512-9lt9Zse4hPucPkoP7FHDF0LQAlGyF9JVpnClFLFH3aSSbxmyoqINRpp/9wePWJTUl4KOQwRL72Iw3InHPDkoGw==} + /ejs/3.1.8: + resolution: {integrity: sha512-/sXZeMlhS0ArkfX2Aw780gJzXSMPnKjtspYZv+f3NiKLlubezAHDU5+9xz6gd3/NhG3txQCo6xlglmTS+oTGEQ==} engines: {node: '>=0.10.0'} hasBin: true dependencies: - jake: 10.8.2 + jake: 10.8.5 dev: false /electron-to-chromium/1.4.141: @@ -7284,6 +7284,23 @@ packages: p-cancelable: 2.1.1 responselike: 2.0.0 + /got/11.8.5: + resolution: {integrity: sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==} + engines: {node: '>=10.19.0'} + dependencies: + '@sindresorhus/is': 4.2.0 + '@szmarczak/http-timer': 4.0.6 + '@types/cacheable-request': 6.0.2 + '@types/responselike': 1.0.0 + cacheable-lookup: 5.0.4 + cacheable-request: 7.0.2 + decompress-response: 6.0.0 + http2-wrapper: 1.0.3 + lowercase-keys: 2.0.0 + p-cancelable: 2.1.1 + responselike: 2.0.0 + dev: false + /graceful-fs/4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} @@ -8225,12 +8242,13 @@ packages: istanbul-lib-report: 3.0.0 dev: true - /jake/10.8.2: - resolution: {integrity: sha512-eLpKyrfG3mzvGE2Du8VoPbeSkRry093+tyNjdYaBbJS9v17knImYGNXQCUV0gLxQtF82m3E8iRb/wdSQZLoq7A==} + /jake/10.8.5: + resolution: {integrity: sha512-sVpxYeuAhWt0OTWITwT98oyV0GsXyMlXCF+3L1SuafBVUIr/uILGRB+NqwkzhgXKvoJpDIpQvqkUALgdmQsQxw==} + engines: {node: '>=10'} hasBin: true dependencies: - async: 0.9.2 - chalk: 2.4.2 + async: 3.2.4 + chalk: 4.1.2 filelist: 1.0.2 minimatch: 3.1.2 dev: false @@ -9051,6 +9069,10 @@ packages: '@sideway/pinpoint': 2.0.0 dev: true + /jose/4.10.4: + resolution: {integrity: sha512-eBH77Xs9Yc/oTDvukhAEDVMijhekPuNktXJL4tUlB22jqKP1k48v5nmsUmc8feoJPsxB3HsfEt2LbVSoz+1mng==} + dev: false + /jose/4.6.0: resolution: {integrity: sha512-0hNAkhMBNi4soKSAX4zYOFV+aqJlEz/4j4fregvasJzEVtjDChvWqRjPvHwLqr5hx28Ayr6bsOs1Kuj87V0O8w==} @@ -10549,8 +10571,8 @@ packages: engines: {node: '>=0.10.0'} dev: true - /object-hash/2.2.0: - resolution: {integrity: sha512-gScRMn0bS5fH+IuwyIFgnh9zBdo4DV+6GhygmWM9HyNJSgS0hScp1f5vjtm7oIIOiT9trXrShAkLFSc2IqKNgw==} + /object-hash/3.0.0: + resolution: {integrity: sha512-RSn9F68PjH9HqtltsSnqYC1XXoWe9Bju5+213R98cNGttag9q9yAOTzdbsqvIa7aNm5WffBZFpWYr2aWrklWAw==} engines: {node: '>= 6'} dev: false @@ -10608,25 +10630,25 @@ packages: /obuf/1.1.2: resolution: {integrity: sha512-PX1wu0AmAdPqOL1mWhqmlOd8kOIZQwGZw6rh7uby9fTc5lhaOWFLX3I6R1hrF9k3zUY40e6igsLGkDXK92LJNg==} - /oidc-provider/7.11.3: - resolution: {integrity: sha512-lk90N1+tXi4JX2/kdukMlSxummBTY78AFCX8meHev8pcxbCBjQqJwW2oKaujnTGxYIuDeUYjNI9zh0ur+oFu8g==} - engines: {node: ^12.19.0 || ^14.15.0 || ^16.13.0} + /oidc-provider/7.13.0: + resolution: {integrity: sha512-S8Ar9XrU3Gwe4XQMAw3bdfmE8bse9DIcJ2UNgHXcS77XeQuGsuotwbMQ/3fBNes5MnWc+nEgJMjzx5TQgqIheA==} + engines: {node: 12 || 14 || 16 || 18} dependencies: - '@koa/cors': 3.1.0 + '@koa/cors': 3.4.3 cacheable-lookup: 6.0.4 debug: 4.3.4 - ejs: 3.1.6 - got: 11.8.3 - jose: 4.6.0 + ejs: 3.1.8 + got: 11.8.5 + jose: 4.10.4 jsesc: 3.0.2 koa: 2.13.4 koa-compose: 4.1.0 nanoid: 3.3.4 - object-hash: 2.2.0 + object-hash: 3.0.0 oidc-token-hash: 5.0.1 paseto: 2.1.3 quick-lru: 5.1.1 - raw-body: 2.4.3 + raw-body: 2.5.1 optionalDependencies: paseto3: /paseto/3.1.1 transitivePeerDependencies: @@ -11635,6 +11657,16 @@ packages: unpipe: 1.0.0 dev: false + /raw-body/2.5.1: + resolution: {integrity: sha512-qqJBtEyVgS0ZmPGdCFPWJ3FreoqvG4MVQln/kCgF7Olq95IbOp0/BWyMwbdtn4VTvkM8Y7khCQ2Xgk/tcrCXig==} + engines: {node: '>= 0.8'} + dependencies: + bytes: 3.1.2 + http-errors: 2.0.0 + iconv-lite: 0.4.24 + unpipe: 1.0.0 + dev: false + /react-animate-height/3.0.4_biqbaboplfbrettd7655fr4n2y: resolution: {integrity: sha512-k+mBS8yCzpFp+7BdrHsL5bXd6CO/2bYO2SvRGKfxK+Ss3nzplAJLlgnd6Zhcxe/avdpy/CgcziicFj7pIHgG5g==} engines: {node: '>= 12.0.0'} @@ -13451,7 +13483,7 @@ packages: '@jest/types': 29.1.2 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.1.2_k5ytkvaprncdyzidqqws5bqksq + jest: 29.1.2_@types+node@16.11.12 jest-util: 29.2.1 json5: 2.2.1 lodash.memoize: 4.1.2 From 13a6f26cff67b3a4c04c52894b435e136e115bd5 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Sun, 6 Nov 2022 00:20:37 +0800 Subject: [PATCH 09/19] chore: upgrade got --- packages/cli/package.json | 2 +- packages/core/package.json | 2 +- packages/integration-tests/package.json | 2 +- pnpm-lock.yaml | 29 +++++-------------------- 4 files changed, 9 insertions(+), 26 deletions(-) diff --git a/packages/cli/package.json b/packages/cli/package.json index e96ac48b6..de9625cb1 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -47,7 +47,7 @@ "decamelize": "^5.0.0", "dotenv": "^16.0.0", "fs-extra": "^10.1.0", - "got": "^11.8.2", + "got": "^11.8.5", "hpagent": "^1.0.0", "inquirer": "^8.2.2", "nanoid": "^3.3.4", diff --git a/packages/core/package.json b/packages/core/package.json index 5d2209b99..6b76aa0b7 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -38,7 +38,7 @@ "etag": "^1.8.1", "find-up": "^5.0.0", "fs-extra": "^10.1.0", - "got": "^11.8.2", + "got": "^11.8.5", "hash-wasm": "^4.9.0", "i18next": "^21.8.16", "iconv-lite": "0.6.3", diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index 1b6c75726..9abf959e9 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -27,7 +27,7 @@ "@types/node": "^16.0.0", "dotenv": "^16.0.0", "eslint": "^8.21.0", - "got": "^11.8.2", + "got": "^11.8.5", "jest": "^29.1.2", "jest-puppeteer": "^6.1.1", "node-fetch": "^2.6.7", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d3676d15b..d8b44c9fa 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -41,7 +41,7 @@ importers: dotenv: ^16.0.0 eslint: ^8.21.0 fs-extra: ^10.1.0 - got: ^11.8.2 + got: ^11.8.5 hpagent: ^1.0.0 inquirer: ^8.2.2 jest: ^29.1.2 @@ -69,7 +69,7 @@ importers: decamelize: 5.0.1 dotenv: 16.0.0 fs-extra: 10.1.0 - got: 11.8.3 + got: 11.8.5 hpagent: 1.0.0 inquirer: 8.2.2 nanoid: 3.3.4 @@ -280,7 +280,7 @@ importers: etag: ^1.8.1 find-up: ^5.0.0 fs-extra: ^10.1.0 - got: ^11.8.2 + got: ^11.8.5 hash-wasm: ^4.9.0 http-errors: ^1.6.3 i18next: ^21.8.16 @@ -337,7 +337,7 @@ importers: etag: 1.8.1 find-up: 5.0.0 fs-extra: 10.1.0 - got: 11.8.3 + got: 11.8.5 hash-wasm: 4.9.0 i18next: 21.8.16 iconv-lite: 0.6.3 @@ -474,7 +474,7 @@ importers: '@types/node': ^16.0.0 dotenv: ^16.0.0 eslint: ^8.21.0 - got: ^11.8.2 + got: ^11.8.5 jest: ^29.1.2 jest-puppeteer: ^6.1.1 node-fetch: ^2.6.7 @@ -499,7 +499,7 @@ importers: '@types/node': 16.11.12 dotenv: 16.0.0 eslint: 8.21.0 - got: 11.8.3 + got: 11.8.5 jest: 29.1.2_k5ytkvaprncdyzidqqws5bqksq jest-puppeteer: 6.1.1_puppeteer@19.2.2 node-fetch: 2.6.7 @@ -7268,22 +7268,6 @@ packages: csstype: 3.0.11 dev: true - /got/11.8.3: - resolution: {integrity: sha512-7gtQ5KiPh1RtGS9/Jbv1ofDpBFuq42gyfEib+ejaRBJuj/3tQFeR5+gw57e4ipaU8c/rCjvX6fkQz2lyDlGAOg==} - engines: {node: '>=10.19.0'} - dependencies: - '@sindresorhus/is': 4.2.0 - '@szmarczak/http-timer': 4.0.6 - '@types/cacheable-request': 6.0.2 - '@types/responselike': 1.0.0 - cacheable-lookup: 5.0.4 - cacheable-request: 7.0.2 - decompress-response: 6.0.0 - http2-wrapper: 1.0.3 - lowercase-keys: 2.0.0 - p-cancelable: 2.1.1 - responselike: 2.0.0 - /got/11.8.5: resolution: {integrity: sha512-o0Je4NvQObAuZPHLFoRSkdG2lTgtcynqymzg2Vupdx6PorhaT5MCbIyXG6d4D94kk8ZG57QeosgdiqfJWhEhlQ==} engines: {node: '>=10.19.0'} @@ -7299,7 +7283,6 @@ packages: lowercase-keys: 2.0.0 p-cancelable: 2.1.1 responselike: 2.0.0 - dev: false /graceful-fs/4.2.10: resolution: {integrity: sha512-9ByhssR2fPVsNZj478qUUbKfmL0+t5BDVyjShtyZZLiK7ZDAArFFfopyOTj0M05wE2tJPisA4iTnnXl2YoPvOA==} From 15bb084b6eee0d1a851a4cd63e2da7d6cb263281 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 7 Nov 2022 14:33:47 +0800 Subject: [PATCH 10/19] refactor: replace dayjs with date-fns --- packages/console/package.json | 6 +- .../console/src/components/DateTime/index.tsx | 8 +-- .../src/pages/AuditLogDetails/index.tsx | 3 +- .../console/src/pages/Dashboard/index.tsx | 4 +- .../SignInExperience/components/Preview.tsx | 4 +- packages/core/package.json | 2 +- packages/core/src/oidc/adapter.test.ts | 7 +- packages/core/src/oidc/adapter.ts | 4 +- .../core/src/queries/oidc-model-instance.ts | 4 +- packages/core/src/routes/dashboard.test.ts | 63 +++++++++--------- packages/core/src/routes/dashboard.ts | 45 +++++++------ .../routes/session/forgot-password.test.ts | 16 +++-- .../src/routes/session/passwordless.test.ts | 65 ++++++++++--------- packages/core/src/routes/session/utils.ts | 7 +- packages/integration-tests/package.json | 1 + .../integration-tests/src/client/index.ts | 8 ++- .../src/include.d/node-fetch.d.ts | 4 ++ .../tests/api/get-access-token.test.ts | 44 ++++++++++++- packages/shared/package.json | 1 - packages/shared/src/database/utils.test.ts | 3 +- packages/shared/src/database/utils.ts | 4 +- pnpm-lock.yaml | 23 ++++--- 22 files changed, 193 insertions(+), 133 deletions(-) create mode 100644 packages/integration-tests/src/include.d/node-fetch.d.ts diff --git a/packages/console/package.json b/packages/console/package.json index 0eb6f0e5b..98ddfd5ae 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -47,7 +47,6 @@ "clean-deep": "^3.4.0", "cross-env": "^7.0.3", "csstype": "^3.0.11", - "dayjs": "^1.10.5", "deepmerge": "^4.2.2", "dnd-core": "^16.0.0", "eslint": "^8.21.0", @@ -97,5 +96,8 @@ "stylelint": { "extends": "@silverhand/eslint-config-react/.stylelintrc" }, - "prettier": "@silverhand/eslint-config/.prettierrc" + "prettier": "@silverhand/eslint-config/.prettierrc", + "dependencies": { + "date-fns": "^2.29.3" + } } diff --git a/packages/console/src/components/DateTime/index.tsx b/packages/console/src/components/DateTime/index.tsx index 0bc850197..4c20a2473 100644 --- a/packages/console/src/components/DateTime/index.tsx +++ b/packages/console/src/components/DateTime/index.tsx @@ -1,18 +1,18 @@ import type { Nullable } from '@silverhand/essentials'; -import dayjs from 'dayjs'; +import { isValid } from 'date-fns'; type Props = { children: Nullable; }; const DateTime = ({ children }: Props) => { - const date = dayjs(children); + const date = children && new Date(children); - if (!children || !date.isValid()) { + if (!date || !isValid(date)) { return -; } - return {date.toDate().toLocaleDateString()}; + return {date.toLocaleDateString()}; }; export default DateTime; diff --git a/packages/console/src/pages/AuditLogDetails/index.tsx b/packages/console/src/pages/AuditLogDetails/index.tsx index 1a5c8f7ad..173c49b6c 100644 --- a/packages/console/src/pages/AuditLogDetails/index.tsx +++ b/packages/console/src/pages/AuditLogDetails/index.tsx @@ -1,6 +1,5 @@ import type { LogDto, User } from '@logto/schemas'; import classNames from 'classnames'; -import dayjs from 'dayjs'; import { useTranslation } from 'react-i18next'; import { useLocation, useParams } from 'react-router-dom'; import useSWR from 'swr'; @@ -85,7 +84,7 @@ const AuditLogDetails = () => {
{t('log_details.time')}
-
{dayjs(data.createdAt).toDate().toLocaleString()}
+
{new Date(data.createdAt).toLocaleString()}
diff --git a/packages/console/src/pages/Dashboard/index.tsx b/packages/console/src/pages/Dashboard/index.tsx index db727d9e8..4d4c8500b 100644 --- a/packages/console/src/pages/Dashboard/index.tsx +++ b/packages/console/src/pages/Dashboard/index.tsx @@ -1,4 +1,4 @@ -import dayjs from 'dayjs'; +import { format } from 'date-fns'; import type { ChangeEventHandler } from 'react'; import { useState } from 'react'; import { useTranslation } from 'react-i18next'; @@ -36,7 +36,7 @@ const tickFormatter = new Intl.NumberFormat('en-US', { }); const Dashboard = () => { - const [date, setDate] = useState(dayjs().format('YYYY-MM-DD')); + const [date, setDate] = useState(format(Date.now(), 'yyyy-MM-dd')); const { data: totalData, error: totalError } = useSWR( '/api/dashboard/users/total' ); diff --git a/packages/console/src/pages/SignInExperience/components/Preview.tsx b/packages/console/src/pages/SignInExperience/components/Preview.tsx index 137e467ec..dfee63676 100644 --- a/packages/console/src/pages/SignInExperience/components/Preview.tsx +++ b/packages/console/src/pages/SignInExperience/components/Preview.tsx @@ -4,7 +4,7 @@ import type { ConnectorResponse, ConnectorMetadata, SignInExperience } from '@lo import { AppearanceMode } from '@logto/schemas'; import { conditional } from '@silverhand/essentials'; import classNames from 'classnames'; -import dayjs from 'dayjs'; +import { format } from 'date-fns'; import { useEffect, useMemo, useState, useRef, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; import useSWR from 'swr'; @@ -195,7 +195,7 @@ const Preview = ({ signInExperience, className }: Props) => {
{platform !== 'desktopWeb' && (
-
{dayjs().format('HH:mm')}
+
{format(Date.now(), 'HH:mm')}
)} diff --git a/packages/core/package.json b/packages/core/package.json index 40a987b77..aeaf3ea8f 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -30,7 +30,7 @@ "@silverhand/essentials": "^1.3.0", "chalk": "^4", "clean-deep": "^3.4.0", - "dayjs": "^1.10.5", + "date-fns": "^2.29.3", "debug": "^4.3.4", "decamelize": "^5.0.0", "deepmerge": "^4.2.2", diff --git a/packages/core/src/oidc/adapter.test.ts b/packages/core/src/oidc/adapter.test.ts index 7cb9c54c4..7cefde551 100644 --- a/packages/core/src/oidc/adapter.test.ts +++ b/packages/core/src/oidc/adapter.test.ts @@ -35,10 +35,9 @@ jest.mock('@logto/shared', () => ({ const now = Date.now(); jest.mock( - 'dayjs', - // eslint-disable-next-line unicorn/consistent-function-scoping - jest.fn(() => () => ({ - add: jest.fn((delta: number) => new Date(now + delta * 1000)), + 'date-fns', + jest.fn(() => ({ + add: jest.fn((_: Date, { seconds }: { seconds: number }) => new Date(now + seconds * 1000)), })) ); diff --git a/packages/core/src/oidc/adapter.ts b/packages/core/src/oidc/adapter.ts index 5c8426268..8c72ba604 100644 --- a/packages/core/src/oidc/adapter.ts +++ b/packages/core/src/oidc/adapter.ts @@ -1,7 +1,7 @@ import type { CreateApplication, OidcClientMetadata } from '@logto/schemas'; import { ApplicationType } from '@logto/schemas'; import { adminConsoleApplicationId, demoAppApplicationId } from '@logto/schemas/lib/seeds'; -import dayjs from 'dayjs'; +import { add } from 'date-fns'; import type { AdapterFactory, AllClientMetadata } from 'oidc-provider'; import snakecaseKeys from 'snakecase-keys'; @@ -99,7 +99,7 @@ export default function postgresAdapter(modelName: string): ReturnType findPayloadById(modelName, id), findByUserCode: async (userCode) => findPayloadByPayloadField(modelName, 'userCode', userCode), diff --git a/packages/core/src/queries/oidc-model-instance.ts b/packages/core/src/queries/oidc-model-instance.ts index fccbe0058..319118756 100644 --- a/packages/core/src/queries/oidc-model-instance.ts +++ b/packages/core/src/queries/oidc-model-instance.ts @@ -7,7 +7,7 @@ import { OidcModelInstances } from '@logto/schemas'; import { convertToIdentifiers, convertToTimestamp } from '@logto/shared'; import type { Nullable } from '@silverhand/essentials'; import { conditional } from '@silverhand/essentials'; -import dayjs from 'dayjs'; +import { add, isBefore } from 'date-fns'; import type { ValueExpression } from 'slonik'; import { sql } from 'slonik'; @@ -30,7 +30,7 @@ const isConsumed = (modelName: string, consumedAt: Nullable): boolean => return Boolean(consumedAt); } - return dayjs(consumedAt).add(refreshTokenReuseInterval, 'seconds').isBefore(dayjs()); + return isBefore(add(consumedAt, { seconds: refreshTokenReuseInterval }), Date.now()); }; const withConsumed = ( diff --git a/packages/core/src/routes/dashboard.test.ts b/packages/core/src/routes/dashboard.test.ts index 89d75af4d..7e960ab5b 100644 --- a/packages/core/src/routes/dashboard.test.ts +++ b/packages/core/src/routes/dashboard.test.ts @@ -1,4 +1,8 @@ -import dayjs from 'dayjs'; +// The FP version works better for `format()` +/* eslint-disable import/no-duplicates */ +import { endOfDay, subDays } from 'date-fns'; +import { format } from 'date-fns/fp'; +/* eslint-enable import/no-duplicates */ import dashboardRoutes from '@/routes/dashboard'; import { createRequester } from '@/utils/test-utils'; @@ -8,6 +12,7 @@ const countUsers = jest.fn(async () => ({ count: totalUserCount })); const getDailyNewUserCountsByTimeInterval = jest.fn( async (startTimeExclusive: number, endTimeInclusive: number) => mockDailyNewUserCounts ); +const formatToQueryDate = format('yyyy-MM-dd'); jest.mock('@/queries/user', () => ({ countUsers: async () => countUsers(), @@ -83,8 +88,8 @@ describe('dashboardRoutes', () => { it('should call getDailyNewUserCountsByTimeInterval with the time interval (14 days ago 23:59:59.999, today 23:59:59.999]', async () => { await logRequest.get('/dashboard/users/new'); expect(getDailyNewUserCountsByTimeInterval).toHaveBeenCalledWith( - dayjs().endOf('day').subtract(14, 'day').valueOf(), - dayjs().endOf('day').valueOf() + subDays(endOfDay(Date.now()), 14).valueOf(), + endOfDay(Date.now()).valueOf() ); }); @@ -105,10 +110,10 @@ describe('dashboardRoutes', () => { }); describe('GET /dashboard/users/active', () => { - const mockToday = '2022-05-30'; + const mockToday = new Date(2022, 4, 30); beforeEach(() => { - jest.useFakeTimers().setSystemTime(new Date(mockToday)); + jest.useFakeTimers().setSystemTime(mockToday); }); it('should fail when the parameter `date` does not match the date regex', async () => { @@ -117,44 +122,44 @@ describe('dashboardRoutes', () => { }); it('should call getDailyActiveUserCountsByTimeInterval with the time interval (2022-05-31, 2022-06-30] when the parameter `date` is 2022-06-30', async () => { - const targetDate = '2022-06-30'; - await logRequest.get(`/dashboard/users/active?date=${targetDate}`); + const targetDate = new Date(2022, 5, 30); + await logRequest.get(`/dashboard/users/active?date=${formatToQueryDate(targetDate)}`); expect(getDailyActiveUserCountsByTimeInterval).toHaveBeenCalledWith( - dayjs('2022-05-31').endOf('day').valueOf(), - dayjs(targetDate).endOf('day').valueOf() + endOfDay(new Date(2022, 4, 31)).valueOf(), + endOfDay(targetDate).valueOf() ); }); it('should call getDailyActiveUserCountsByTimeInterval with the time interval (30 days ago, tomorrow] when there is no parameter `date`', async () => { await logRequest.get('/dashboard/users/active'); expect(getDailyActiveUserCountsByTimeInterval).toHaveBeenCalledWith( - dayjs('2022-04-30').endOf('day').valueOf(), - dayjs(mockToday).endOf('day').valueOf() + endOfDay(new Date(2022, 3, 30)).valueOf(), + endOfDay(mockToday).valueOf() ); }); it('should call countActiveUsersByTimeInterval with correct parameters when the parameter `date` is 2022-06-30', async () => { - const targetDate = '2022-06-30'; - await logRequest.get(`/dashboard/users/active?date=${targetDate}`); + const targetDate = new Date(2022, 5, 30); + await logRequest.get(`/dashboard/users/active?date=${formatToQueryDate(targetDate)}`); expect(countActiveUsersByTimeInterval).toHaveBeenNthCalledWith( 1, - dayjs('2022-06-16').endOf('day').valueOf(), - dayjs('2022-06-23').endOf('day').valueOf() + endOfDay(new Date(2022, 5, 16)).valueOf(), + endOfDay(new Date(2022, 5, 23)).valueOf() ); expect(countActiveUsersByTimeInterval).toHaveBeenNthCalledWith( 2, - dayjs('2022-06-23').endOf('day').valueOf(), - dayjs(targetDate).endOf('day').valueOf() + endOfDay(new Date(2022, 5, 23)).valueOf(), + endOfDay(targetDate).valueOf() ); expect(countActiveUsersByTimeInterval).toHaveBeenNthCalledWith( 3, - dayjs('2022-05-01').endOf('day').valueOf(), - dayjs('2022-05-31').endOf('day').valueOf() + endOfDay(new Date(2022, 4, 1)).valueOf(), + endOfDay(new Date(2022, 4, 31)).valueOf() ); expect(countActiveUsersByTimeInterval).toHaveBeenNthCalledWith( 4, - dayjs('2022-05-31').endOf('day').valueOf(), - dayjs(targetDate).endOf('day').valueOf() + endOfDay(new Date(2022, 4, 31)).valueOf(), + endOfDay(targetDate).valueOf() ); }); @@ -162,23 +167,23 @@ describe('dashboardRoutes', () => { await logRequest.get('/dashboard/users/active'); expect(countActiveUsersByTimeInterval).toHaveBeenNthCalledWith( 1, - dayjs('2022-05-16').endOf('day').valueOf(), - dayjs('2022-05-23').endOf('day').valueOf() + endOfDay(new Date(2022, 4, 16)).valueOf(), + endOfDay(new Date(2022, 4, 23)).valueOf() ); expect(countActiveUsersByTimeInterval).toHaveBeenNthCalledWith( 2, - dayjs('2022-05-23').endOf('day').valueOf(), - dayjs(mockToday).endOf('day').valueOf() + endOfDay(new Date(2022, 4, 23)).valueOf(), + endOfDay(mockToday).valueOf() ); expect(countActiveUsersByTimeInterval).toHaveBeenNthCalledWith( 3, - dayjs('2022-03-31').endOf('day').valueOf(), - dayjs('2022-04-30').endOf('day').valueOf() + endOfDay(new Date(2022, 2, 31)).valueOf(), + endOfDay(new Date(2022, 3, 30)).valueOf() ); expect(countActiveUsersByTimeInterval).toHaveBeenNthCalledWith( 4, - dayjs('2022-04-30').endOf('day').valueOf(), - dayjs(mockToday).endOf('day').valueOf() + endOfDay(new Date(2022, 3, 30)).valueOf(), + endOfDay(mockToday).valueOf() ); }); diff --git a/packages/core/src/routes/dashboard.ts b/packages/core/src/routes/dashboard.ts index c708fb060..c26475857 100644 --- a/packages/core/src/routes/dashboard.ts +++ b/packages/core/src/routes/dashboard.ts @@ -1,6 +1,5 @@ import { dateRegex } from '@logto/core-kit'; -import type { Dayjs } from 'dayjs'; -import dayjs from 'dayjs'; +import { endOfDay, format, parse, startOfDay, subDays } from 'date-fns'; import { object, string } from 'zod'; import koaGuard from '@/middleware/koa-guard'; @@ -12,11 +11,11 @@ import { countUsers, getDailyNewUserCountsByTimeInterval } from '@/queries/user' import type { AuthedRouter } from './types'; -const getDateString = (day: Dayjs) => day.format('YYYY-MM-DD'); +const getDateString = (date: Date | number) => format(date, 'yyyy-MM-dd'); const indices = (length: number) => [...Array.from({ length }).keys()]; -const lastTimestampOfDay = (day: Dayjs) => day.endOf('day').valueOf(); +const getEndOfDayTimestamp = (date: Date | number) => endOfDay(date).valueOf(); export default function dashboardRoutes(router: T) { router.get('/dashboard/users/total', async (ctx, next) => { @@ -27,11 +26,11 @@ export default function dashboardRoutes(router: T) { }); router.get('/dashboard/users/new', async (ctx, next) => { - const today = dayjs(); + const today = Date.now(); const dailyNewUserCounts = await getDailyNewUserCountsByTimeInterval( // (14 days ago 23:59:59.999, today 23:59:59.999] - lastTimestampOfDay(today.subtract(14, 'day')), - lastTimestampOfDay(today) + getEndOfDayTimestamp(subDays(today, 14)), + getEndOfDayTimestamp(today) ); const last14DaysNewUserCounts = new Map( @@ -39,15 +38,15 @@ export default function dashboardRoutes(router: T) { ); const todayNewUserCount = last14DaysNewUserCounts.get(getDateString(today)) ?? 0; - const yesterday = today.subtract(1, 'day'); + const yesterday = subDays(today, 1); const yesterdayNewUserCount = last14DaysNewUserCounts.get(getDateString(yesterday)) ?? 0; const todayDelta = todayNewUserCount - yesterdayNewUserCount; const last7DaysNewUserCount = indices(7) - .map((index) => getDateString(today.subtract(index, 'day'))) + .map((index) => getDateString(subDays(today, index))) .reduce((sum, date) => sum + (last14DaysNewUserCounts.get(date) ?? 0), 0); const newUserCountFrom13DaysAgoTo7DaysAgo = indices(7) - .map((index) => getDateString(today.subtract(7 + index, 'day'))) + .map((index) => getDateString(subDays(today, index + 7))) .reduce((sum, date) => sum + (last14DaysNewUserCounts.get(date) ?? 0), 0); const last7DaysDelta = last7DaysNewUserCount - newUserCountFrom13DaysAgoTo7DaysAgo; @@ -75,7 +74,7 @@ export default function dashboardRoutes(router: T) { query: { date }, } = ctx.guard; - const targetDay = date ? dayjs(date) : dayjs(); // Defaults to today + const targetDay = date ? parse(date, 'yyyy-MM-dd', startOfDay(Date.now())) : Date.now(); // Defaults to today const [ // DAU: Daily Active User last30DauCounts, @@ -88,39 +87,39 @@ export default function dashboardRoutes(router: T) { ] = await Promise.all([ getDailyActiveUserCountsByTimeInterval( // (30 days ago 23:59:59.999, target day 23:59:59.999] - lastTimestampOfDay(targetDay.subtract(30, 'day')), - lastTimestampOfDay(targetDay) + getEndOfDayTimestamp(subDays(targetDay, 30)), + getEndOfDayTimestamp(targetDay) ), countActiveUsersByTimeInterval( // (14 days ago 23:59:59.999, 7 days ago 23:59:59.999] - lastTimestampOfDay(targetDay.subtract(14, 'day')), - lastTimestampOfDay(targetDay.subtract(7, 'day')) + getEndOfDayTimestamp(subDays(targetDay, 14)), + getEndOfDayTimestamp(subDays(targetDay, 7)) ), countActiveUsersByTimeInterval( // (7 days ago 23:59:59.999, target day 23:59:59.999] - lastTimestampOfDay(targetDay.subtract(7, 'day')), - lastTimestampOfDay(targetDay) + getEndOfDayTimestamp(subDays(targetDay, 7)), + getEndOfDayTimestamp(targetDay) ), countActiveUsersByTimeInterval( // (60 days ago 23:59:59.999, 30 days ago 23:59:59.999] - lastTimestampOfDay(targetDay.subtract(60, 'day')), - lastTimestampOfDay(targetDay.subtract(30, 'day')) + getEndOfDayTimestamp(subDays(targetDay, 60)), + getEndOfDayTimestamp(subDays(targetDay, 30)) ), countActiveUsersByTimeInterval( // (30 days ago 23:59:59.999, target day 23:59:59.999] - lastTimestampOfDay(targetDay.subtract(30, 'day')), - lastTimestampOfDay(targetDay) + getEndOfDayTimestamp(subDays(targetDay, 30)), + getEndOfDayTimestamp(targetDay) ), ]); - const previousDate = getDateString(targetDay.subtract(1, 'day')); + const previousDate = getDateString(subDays(targetDay, 1)); const targetDate = getDateString(targetDay); const previousDAU = last30DauCounts.find(({ date }) => date === previousDate)?.count ?? 0; const dau = last30DauCounts.find(({ date }) => date === targetDate)?.count ?? 0; const dauCurve = indices(30).map((index) => { - const dateString = getDateString(targetDay.subtract(29 - index, 'day')); + const dateString = getDateString(subDays(targetDay, 29 - index)); const count = last30DauCounts.find(({ date }) => date === dateString)?.count ?? 0; return { date: dateString, count }; diff --git a/packages/core/src/routes/session/forgot-password.test.ts b/packages/core/src/routes/session/forgot-password.test.ts index 3182843c7..59c355de8 100644 --- a/packages/core/src/routes/session/forgot-password.test.ts +++ b/packages/core/src/routes/session/forgot-password.test.ts @@ -1,6 +1,6 @@ import type { User } from '@logto/schemas'; import { PasscodeType } from '@logto/schemas'; -import dayjs from 'dayjs'; +import { addDays, subDays } from 'date-fns'; import { Provider } from 'oidc-provider'; import { mockPasswordEncrypted, mockUserWithPassword } from '@/__mocks__'; @@ -15,6 +15,8 @@ const encryptUserPassword = jest.fn(async (password: string) => ({ })); const findUserById = jest.fn(async (): Promise => mockUserWithPassword); const updateUserById = jest.fn(async (..._args: unknown[]) => ({ userId: 'id' })); +const getYesterdayDate = () => subDays(Date.now(), 1); +const getTomorrowDate = () => addDays(Date.now(), 1); jest.mock('@/lib/user', () => ({ ...jest.requireActual('@/lib/user'), @@ -84,7 +86,7 @@ describe('session -> forgotPasswordRoutes', () => { result: { verification: { userId: 'id', - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowDate().toISOString(), flow: PasscodeType.ForgotPassword, }, }, @@ -105,7 +107,7 @@ describe('session -> forgotPasswordRoutes', () => { interactionDetails.mockResolvedValueOnce({ result: { verification: { - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowDate().toISOString(), flow: PasscodeType.ForgotPassword, }, }, @@ -121,7 +123,7 @@ describe('session -> forgotPasswordRoutes', () => { result: { verification: { userId: 'id', - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowDate().toISOString(), flow: PasscodeType.SignIn, }, }, @@ -165,7 +167,7 @@ describe('session -> forgotPasswordRoutes', () => { result: { verification: { userId: 'id', - expiresAt: dayjs().subtract(1, 'day').toISOString(), + expiresAt: getYesterdayDate().toISOString(), flow: PasscodeType.ForgotPassword, }, }, @@ -181,7 +183,7 @@ describe('session -> forgotPasswordRoutes', () => { result: { verification: { userId: 'id', - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowDate().toISOString(), flow: PasscodeType.ForgotPassword, }, }, @@ -198,7 +200,7 @@ describe('session -> forgotPasswordRoutes', () => { result: { verification: { userId: 'id', - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowDate().toISOString(), flow: PasscodeType.ForgotPassword, }, }, diff --git a/packages/core/src/routes/session/passwordless.test.ts b/packages/core/src/routes/session/passwordless.test.ts index b0c2688ef..a49fcd19a 100644 --- a/packages/core/src/routes/session/passwordless.test.ts +++ b/packages/core/src/routes/session/passwordless.test.ts @@ -1,7 +1,7 @@ /* eslint-disable max-lines */ import type { User } from '@logto/schemas'; import { PasscodeType } from '@logto/schemas'; -import dayjs from 'dayjs'; +import { addDays, addSeconds, subDays } from 'date-fns'; import { Provider } from 'oidc-provider'; import { mockUser } from '@/__mocks__'; @@ -15,6 +15,7 @@ import passwordlessRoutes, { registerRoute, signInRoute } from './passwordless'; const insertUser = jest.fn(async (..._args: unknown[]) => ({ id: 'id' })); const findUserById = jest.fn(async (): Promise => mockUser); const updateUserById = jest.fn(async (..._args: unknown[]) => ({ id: 'id' })); +const getTomorrowIsoString = () => addDays(Date.now(), 1).toISOString(); jest.mock('@/lib/user', () => ({ generateUserId: () => 'user1', @@ -200,7 +201,7 @@ describe('session -> passwordlessRoutes', () => { verification: { flow: PasscodeType.SignIn, phone: '13000000000', - expiresAt: dayjs(fakeTime).add(verificationTimeout, 'second').toISOString(), + expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(), }, }) ); @@ -224,7 +225,7 @@ describe('session -> passwordlessRoutes', () => { verification: { flow: PasscodeType.Register, phone: '13000000000', - expiresAt: dayjs(fakeTime).add(verificationTimeout, 'second').toISOString(), + expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(), }, }) ); @@ -248,7 +249,7 @@ describe('session -> passwordlessRoutes', () => { expect.objectContaining({ verification: { userId: 'id', - expiresAt: dayjs(fakeTime).add(verificationTimeout, 'second').toISOString(), + expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(), flow: PasscodeType.ForgotPassword, }, }) @@ -299,7 +300,7 @@ describe('session -> passwordlessRoutes', () => { verification: { flow: PasscodeType.SignIn, email: 'a@a.com', - expiresAt: dayjs(fakeTime).add(verificationTimeout, 'second').toISOString(), + expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(), }, }) ); @@ -322,7 +323,7 @@ describe('session -> passwordlessRoutes', () => { verification: { flow: PasscodeType.Register, email: 'a@a.com', - expiresAt: dayjs(fakeTime).add(verificationTimeout, 'second').toISOString(), + expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(), }, }) ); @@ -346,7 +347,7 @@ describe('session -> passwordlessRoutes', () => { expect.objectContaining({ verification: { userId: 'id', - expiresAt: dayjs(fakeTime).add(verificationTimeout, 'second').toISOString(), + expiresAt: addSeconds(fakeTime, verificationTimeout).toISOString(), flow: PasscodeType.ForgotPassword, }, }) @@ -382,7 +383,7 @@ describe('session -> passwordlessRoutes', () => { verification: { phone: '13000000000', flow: PasscodeType.SignIn, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -406,7 +407,7 @@ describe('session -> passwordlessRoutes', () => { verification: { phone: '13000000000', flow: PasscodeType.Register, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -427,7 +428,7 @@ describe('session -> passwordlessRoutes', () => { result: { verification: { phone: '13000000000', - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -441,7 +442,7 @@ describe('session -> passwordlessRoutes', () => { verification: { phone: '13000000000', flow: PasscodeType.ForgotPassword, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -469,7 +470,7 @@ describe('session -> passwordlessRoutes', () => { verification: { phone: '13000000000', flow: PasscodeType.SignIn, - expiresAt: dayjs().subtract(1, 'day').toISOString(), + expiresAt: subDays(Date.now(), 1).toISOString(), }, }, }); @@ -483,7 +484,7 @@ describe('session -> passwordlessRoutes', () => { verification: { email: 'XX@foo', flow: PasscodeType.SignIn, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -497,7 +498,7 @@ describe('session -> passwordlessRoutes', () => { verification: { phone: '13000000001', flow: PasscodeType.SignIn, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -517,7 +518,7 @@ describe('session -> passwordlessRoutes', () => { verification: { email: 'a@a.com', flow: PasscodeType.SignIn, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -541,7 +542,7 @@ describe('session -> passwordlessRoutes', () => { verification: { email: 'a@a.com', flow: PasscodeType.Register, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -564,7 +565,7 @@ describe('session -> passwordlessRoutes', () => { result: { verification: { email: 'a@a.com', - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -578,7 +579,7 @@ describe('session -> passwordlessRoutes', () => { verification: { email: 'a@a.com', flow: PasscodeType.ForgotPassword, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -591,7 +592,7 @@ describe('session -> passwordlessRoutes', () => { result: { verification: { flow: PasscodeType.SignIn, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -605,7 +606,7 @@ describe('session -> passwordlessRoutes', () => { verification: { email: 'b@a.com', flow: PasscodeType.SignIn, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -625,7 +626,7 @@ describe('session -> passwordlessRoutes', () => { verification: { phone: '13000000001', flow: PasscodeType.Register, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -647,7 +648,7 @@ describe('session -> passwordlessRoutes', () => { verification: { phone: '13000000001', flow: PasscodeType.SignIn, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -668,7 +669,7 @@ describe('session -> passwordlessRoutes', () => { result: { verification: { phone: '13000000001', - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -682,7 +683,7 @@ describe('session -> passwordlessRoutes', () => { verification: { phone: '13000000001', flow: PasscodeType.ForgotPassword, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -695,7 +696,7 @@ describe('session -> passwordlessRoutes', () => { result: { verification: { flow: PasscodeType.Register, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -709,7 +710,7 @@ describe('session -> passwordlessRoutes', () => { verification: { phone: '13000000000', flow: PasscodeType.Register, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -729,7 +730,7 @@ describe('session -> passwordlessRoutes', () => { verification: { email: 'b@a.com', flow: PasscodeType.Register, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -751,7 +752,7 @@ describe('session -> passwordlessRoutes', () => { verification: { email: 'b@a.com', flow: PasscodeType.SignIn, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -772,7 +773,7 @@ describe('session -> passwordlessRoutes', () => { result: { verification: { email: 'b@a.com', - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -786,7 +787,7 @@ describe('session -> passwordlessRoutes', () => { verification: { email: 'b@a.com', flow: PasscodeType.ForgotPassword, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -799,7 +800,7 @@ describe('session -> passwordlessRoutes', () => { result: { verification: { flow: PasscodeType.Register, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); @@ -813,7 +814,7 @@ describe('session -> passwordlessRoutes', () => { verification: { email: 'a@a.com', flow: PasscodeType.Register, - expiresAt: dayjs().add(1, 'day').toISOString(), + expiresAt: getTomorrowIsoString(), }, }, }); diff --git a/packages/core/src/routes/session/utils.ts b/packages/core/src/routes/session/utils.ts index 8f15038b5..baa70d546 100644 --- a/packages/core/src/routes/session/utils.ts +++ b/packages/core/src/routes/session/utils.ts @@ -1,7 +1,7 @@ import type { LogType, PasscodeType } from '@logto/schemas'; import { logTypeGuard } from '@logto/schemas'; import type { Truthy } from '@silverhand/essentials'; -import dayjs from 'dayjs'; +import { addSeconds, isAfter, isValid, parseISO } from 'date-fns'; import type { Context } from 'koa'; import type { Provider } from 'oidc-provider'; import type { ZodType } from 'zod'; @@ -60,8 +60,9 @@ export const getVerificationStorageFromInteraction = async { + const parsed = parseISO(expiresAt); assertThat( - dayjs(expiresAt).isValid() && dayjs(expiresAt).isAfter(dayjs()), + isValid(parsed) && isAfter(parsed, Date.now()), new RequestError({ code: 'session.verification_expired', status: 401 }) ); }; @@ -75,7 +76,7 @@ export const assignVerificationResult = async ( ) => { const verification: VerificationStorage = { ...verificationData, - expiresAt: dayjs().add(verificationTimeout, 'second').toISOString(), + expiresAt: addSeconds(Date.now(), verificationTimeout).toISOString(), }; await provider.interactionResult(ctx.req, ctx.res, { diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index 1b6c75726..57e726479 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -15,6 +15,7 @@ }, "devDependencies": { "@jest/types": "^29.1.2", + "@logto/js": "1.0.0-beta.11", "@logto/node": "1.0.0-beta.12", "@logto/schemas": "workspace:^", "@peculiar/webcrypto": "^1.3.3", diff --git a/packages/integration-tests/src/client/index.ts b/packages/integration-tests/src/client/index.ts index 75dfe7047..e5129e839 100644 --- a/packages/integration-tests/src/client/index.ts +++ b/packages/integration-tests/src/client/index.ts @@ -10,7 +10,7 @@ import { extractCookie } from '@/utils'; import { MemoryStorage } from './storage'; -const defaultConfig = { +export const defaultConfig = { endpoint: logtoUrl, appId: demoAppApplicationId, persistAccessToken: false, @@ -18,8 +18,8 @@ const defaultConfig = { export default class MockClient { public interactionCookie?: string; - private navigateUrl?: string; + private navigateUrl?: string; private readonly storage: MemoryStorage; private readonly logto: LogtoClient; @@ -88,6 +88,10 @@ export default class MockClient { return this.logto.getAccessToken(resource); } + public async getRefreshToken() { + return this.logto.getRefreshToken(); + } + public async signOut(postSignOutRedirectUri?: string) { return this.logto.signOut(postSignOutRedirectUri); } diff --git a/packages/integration-tests/src/include.d/node-fetch.d.ts b/packages/integration-tests/src/include.d/node-fetch.d.ts new file mode 100644 index 000000000..dd1a8efbe --- /dev/null +++ b/packages/integration-tests/src/include.d/node-fetch.d.ts @@ -0,0 +1,4 @@ +declare module 'node-fetch' { + const nodeFetch: typeof fetch; + export = nodeFetch; +} diff --git a/packages/integration-tests/tests/api/get-access-token.test.ts b/packages/integration-tests/tests/api/get-access-token.test.ts index 94e10e720..da220cdf4 100644 --- a/packages/integration-tests/tests/api/get-access-token.test.ts +++ b/packages/integration-tests/tests/api/get-access-token.test.ts @@ -1,8 +1,13 @@ +import path from 'path'; + +import { fetchTokenByRefreshToken } from '@logto/js'; import { managementResource } from '@logto/schemas/lib/seeds'; import { assert } from '@silverhand/essentials'; +import fetch from 'node-fetch'; import { signInWithUsernameAndPassword } from '@/api'; -import MockClient from '@/client'; +import MockClient, { defaultConfig } from '@/client'; +import { logtoUrl } from '@/constants'; import { createUserByAdmin } from '@/helpers'; import { generateUsername, generatePassword } from '@/utils'; @@ -36,4 +41,41 @@ describe('get access token', () => { // Request for invalid resource should throw void expect(client.getAccessToken('api.foo.com')).rejects.toThrow(); }); + + it('sign-in and get multiple Access Token by the same Refresh Token within refreshTokenReuseInterval', async () => { + const client = new MockClient({ resources: [managementResource.indicator] }); + await client.initSession(); + assert(client.interactionCookie, new Error('Session not found')); + + const { redirectTo } = await signInWithUsernameAndPassword( + username, + password, + client.interactionCookie + ); + + await client.processSession(redirectTo); + assert(client.isAuthenticated, new Error('Sign in get get access token failed')); + + const refreshToken = await client.getRefreshToken(); + assert(refreshToken, new Error('No Refresh Token found')); + + const getAccessTokenByRefreshToken = async () => + fetchTokenByRefreshToken( + { + clientId: defaultConfig.appId, + tokenEndpoint: path.join(logtoUrl, '/oidc/token'), + refreshToken, + resource: managementResource.indicator, + }, + async (...args: Parameters): Promise => { + const response = await fetch(...args); + assert(response.ok, new Error('Request error')); + + return response.json(); + } + ); + + // Allow to use the same refresh token to fetch access token within short time period + await Promise.all([getAccessTokenByRefreshToken(), getAccessTokenByRefreshToken()]); + }); }); diff --git a/packages/shared/package.json b/packages/shared/package.json index c44c5ab15..cf5fe89a6 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -45,7 +45,6 @@ "dependencies": { "@logto/schemas": "workspace:^", "@silverhand/essentials": "^1.3.0", - "dayjs": "^1.10.5", "find-up": "^5.0.0", "nanoid": "^3.3.4", "slonik": "^30.0.0" diff --git a/packages/shared/src/database/utils.test.ts b/packages/shared/src/database/utils.test.ts index 396fd981b..79653f147 100644 --- a/packages/shared/src/database/utils.test.ts +++ b/packages/shared/src/database/utils.test.ts @@ -1,4 +1,3 @@ -import dayjs from 'dayjs'; import { sql } from 'slonik'; import { SqlToken } from 'slonik/dist/src/tokens.js'; @@ -124,7 +123,7 @@ describe('convertToTimestamp()', () => { }); it('converts to sql per time parameter', () => { - const time = dayjs(123_123_123); + const time = new Date(123_123_123); expect(convertToTimestamp(time)).toEqual({ sql: 'to_timestamp($1)', diff --git a/packages/shared/src/database/utils.ts b/packages/shared/src/database/utils.ts index d18afdcf1..910e8e9b2 100644 --- a/packages/shared/src/database/utils.ts +++ b/packages/shared/src/database/utils.ts @@ -1,7 +1,6 @@ import type { SchemaValuePrimitive, SchemaValue } from '@logto/schemas'; import type { Falsy } from '@silverhand/essentials'; import { notFalsy } from '@silverhand/essentials'; -import dayjs from 'dayjs'; import type { SqlSqlToken, SqlToken, QueryResult, IdentifierSqlToken } from 'slonik'; import { sql } from 'slonik'; @@ -76,7 +75,8 @@ export const convertToIdentifiers = ({ table, fields }: T, with }; }; -export const convertToTimestamp = (time = dayjs()) => sql`to_timestamp(${time.valueOf() / 1000})`; +export const convertToTimestamp = (time = new Date()) => + sql`to_timestamp(${time.valueOf() / 1000})`; export const manyRows = async (query: Promise>): Promise => { const { rows } = await query; diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index ba76cd4de..e95443cba 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -134,7 +134,7 @@ importers: clean-deep: ^3.4.0 cross-env: ^7.0.3 csstype: ^3.0.11 - dayjs: ^1.10.5 + date-fns: ^2.29.3 deepmerge: ^4.2.2 dnd-core: ^16.0.0 eslint: ^8.21.0 @@ -170,6 +170,8 @@ importers: swr: ^1.3.0 typescript: ^4.7.4 zod: ^3.19.1 + dependencies: + date-fns: 2.29.3 devDependencies: '@fontsource/roboto-mono': 4.5.7 '@logto/core-kit': 1.0.0-beta.20 @@ -201,7 +203,6 @@ importers: clean-deep: 3.4.0 cross-env: 7.0.3 csstype: 3.0.11 - dayjs: 1.10.7 deepmerge: 4.2.2 dnd-core: 16.0.0 eslint: 8.21.0 @@ -271,7 +272,7 @@ importers: chalk: ^4 clean-deep: ^3.4.0 copyfiles: ^2.4.1 - dayjs: ^1.10.5 + date-fns: ^2.29.3 debug: ^4.3.4 decamelize: ^5.0.0 deepmerge: ^4.2.2 @@ -329,7 +330,7 @@ importers: '@silverhand/essentials': 1.3.0 chalk: 4.1.2 clean-deep: 3.4.0 - dayjs: 1.10.7 + date-fns: 2.29.3 debug: 4.3.4 decamelize: 5.0.1 deepmerge: 4.2.2 @@ -462,6 +463,7 @@ importers: packages/integration-tests: specifiers: '@jest/types': ^29.1.2 + '@logto/js': 1.0.0-beta.11 '@logto/node': 1.0.0-beta.12 '@logto/schemas': workspace:^ '@peculiar/webcrypto': ^1.3.3 @@ -487,6 +489,7 @@ importers: typescript: ^4.7.4 devDependencies: '@jest/types': 29.1.2 + '@logto/js': 1.0.0-beta.11 '@logto/node': 1.0.0-beta.12 '@logto/schemas': link:../schemas '@peculiar/webcrypto': 1.3.3 @@ -623,7 +626,6 @@ importers: '@silverhand/ts-config': 1.2.1 '@types/jest': ^29.1.2 '@types/node': ^16.0.0 - dayjs: ^1.10.5 eslint: ^8.21.0 find-up: ^5.0.0 jest: ^29.1.2 @@ -635,7 +637,6 @@ importers: dependencies: '@logto/schemas': link:../schemas '@silverhand/essentials': 1.3.0 - dayjs: 1.10.7 find-up: 5.0.0 nanoid: 3.3.4 slonik: 30.1.2 @@ -3467,7 +3468,7 @@ packages: '@jest/types': 29.1.2 deepmerge: 4.2.2 identity-obj-proxy: 3.0.0 - jest: 29.1.2_k5ytkvaprncdyzidqqws5bqksq + jest: 29.1.2_@types+node@16.11.12 jest-matcher-specific-error: 1.0.0 jest-transform-stub: 2.0.0 ts-jest: 29.0.3_37jxomqt5oevoqzq6g3r6n3ili @@ -5648,8 +5649,10 @@ packages: whatwg-url: 11.0.0 dev: true - /dayjs/1.10.7: - resolution: {integrity: sha512-P6twpd70BcPK34K26uJ1KT3wlhpuOAPoMwJzpsIWUxHZ7wpmbdZL/hQqBDfz7hGurYSa5PhzdhDHtt319hL3ig==} + /date-fns/2.29.3: + resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} + engines: {node: '>=0.11'} + dev: false /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} @@ -13451,7 +13454,7 @@ packages: '@jest/types': 29.1.2 bs-logger: 0.2.6 fast-json-stable-stringify: 2.1.0 - jest: 29.1.2_k5ytkvaprncdyzidqqws5bqksq + jest: 29.1.2_@types+node@16.11.12 jest-util: 29.2.1 json5: 2.2.1 lodash.memoize: 4.1.2 From ca126026e9552189f9053f67833dfb904f60357a Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 7 Nov 2022 14:36:05 +0800 Subject: [PATCH 11/19] chore: fix dep in console --- packages/console/package.json | 6 ++---- pnpm-lock.yaml | 4 +--- 2 files changed, 3 insertions(+), 7 deletions(-) diff --git a/packages/console/package.json b/packages/console/package.json index 98ddfd5ae..fc985ec34 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -47,6 +47,7 @@ "clean-deep": "^3.4.0", "cross-env": "^7.0.3", "csstype": "^3.0.11", + "date-fns": "^2.29.3", "deepmerge": "^4.2.2", "dnd-core": "^16.0.0", "eslint": "^8.21.0", @@ -96,8 +97,5 @@ "stylelint": { "extends": "@silverhand/eslint-config-react/.stylelintrc" }, - "prettier": "@silverhand/eslint-config/.prettierrc", - "dependencies": { - "date-fns": "^2.29.3" - } + "prettier": "@silverhand/eslint-config/.prettierrc" } diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index e95443cba..c25c6f77a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -170,8 +170,6 @@ importers: swr: ^1.3.0 typescript: ^4.7.4 zod: ^3.19.1 - dependencies: - date-fns: 2.29.3 devDependencies: '@fontsource/roboto-mono': 4.5.7 '@logto/core-kit': 1.0.0-beta.20 @@ -203,6 +201,7 @@ importers: clean-deep: 3.4.0 cross-env: 7.0.3 csstype: 3.0.11 + date-fns: 2.29.3 deepmerge: 4.2.2 dnd-core: 16.0.0 eslint: 8.21.0 @@ -5652,7 +5651,6 @@ packages: /date-fns/2.29.3: resolution: {integrity: sha512-dDCnyH2WnnKusqvZZ6+jA1O51Ibt8ZMRNkDZdyAyK4YfbDwa/cEmuztzG5pk6hqlp9aSBPYcjOlktquahGwGeA==} engines: {node: '>=0.11'} - dev: false /debug/2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} From 931750f4687b1bdada3aca600642847a05553eb3 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 7 Nov 2022 14:44:40 +0800 Subject: [PATCH 12/19] refactor: replace `parse()` with native Date --- packages/core/src/oidc/adapter.test.ts | 2 +- packages/core/src/oidc/adapter.ts | 4 ++-- packages/core/src/queries/oidc-model-instance.ts | 4 ++-- packages/core/src/routes/dashboard.ts | 4 ++-- packages/core/src/routes/session/utils.ts | 4 ++-- 5 files changed, 9 insertions(+), 9 deletions(-) diff --git a/packages/core/src/oidc/adapter.test.ts b/packages/core/src/oidc/adapter.test.ts index 7cefde551..8ee40b08e 100644 --- a/packages/core/src/oidc/adapter.test.ts +++ b/packages/core/src/oidc/adapter.test.ts @@ -37,7 +37,7 @@ const now = Date.now(); jest.mock( 'date-fns', jest.fn(() => ({ - add: jest.fn((_: Date, { seconds }: { seconds: number }) => new Date(now + seconds * 1000)), + addSeconds: jest.fn((_: Date, seconds: number) => new Date(now + seconds * 1000)), })) ); diff --git a/packages/core/src/oidc/adapter.ts b/packages/core/src/oidc/adapter.ts index 8c72ba604..dc401c715 100644 --- a/packages/core/src/oidc/adapter.ts +++ b/packages/core/src/oidc/adapter.ts @@ -1,7 +1,7 @@ import type { CreateApplication, OidcClientMetadata } from '@logto/schemas'; import { ApplicationType } from '@logto/schemas'; import { adminConsoleApplicationId, demoAppApplicationId } from '@logto/schemas/lib/seeds'; -import { add } from 'date-fns'; +import { addSeconds } from 'date-fns'; import type { AdapterFactory, AllClientMetadata } from 'oidc-provider'; import snakecaseKeys from 'snakecase-keys'; @@ -99,7 +99,7 @@ export default function postgresAdapter(modelName: string): ReturnType findPayloadById(modelName, id), findByUserCode: async (userCode) => findPayloadByPayloadField(modelName, 'userCode', userCode), diff --git a/packages/core/src/queries/oidc-model-instance.ts b/packages/core/src/queries/oidc-model-instance.ts index 319118756..d7dedfba6 100644 --- a/packages/core/src/queries/oidc-model-instance.ts +++ b/packages/core/src/queries/oidc-model-instance.ts @@ -7,7 +7,7 @@ import { OidcModelInstances } from '@logto/schemas'; import { convertToIdentifiers, convertToTimestamp } from '@logto/shared'; import type { Nullable } from '@silverhand/essentials'; import { conditional } from '@silverhand/essentials'; -import { add, isBefore } from 'date-fns'; +import { addSeconds, isBefore } from 'date-fns'; import type { ValueExpression } from 'slonik'; import { sql } from 'slonik'; @@ -30,7 +30,7 @@ const isConsumed = (modelName: string, consumedAt: Nullable): boolean => return Boolean(consumedAt); } - return isBefore(add(consumedAt, { seconds: refreshTokenReuseInterval }), Date.now()); + return isBefore(addSeconds(consumedAt, refreshTokenReuseInterval), Date.now()); }; const withConsumed = ( diff --git a/packages/core/src/routes/dashboard.ts b/packages/core/src/routes/dashboard.ts index c26475857..e89247929 100644 --- a/packages/core/src/routes/dashboard.ts +++ b/packages/core/src/routes/dashboard.ts @@ -1,5 +1,5 @@ import { dateRegex } from '@logto/core-kit'; -import { endOfDay, format, parse, startOfDay, subDays } from 'date-fns'; +import { endOfDay, format, subDays } from 'date-fns'; import { object, string } from 'zod'; import koaGuard from '@/middleware/koa-guard'; @@ -74,7 +74,7 @@ export default function dashboardRoutes(router: T) { query: { date }, } = ctx.guard; - const targetDay = date ? parse(date, 'yyyy-MM-dd', startOfDay(Date.now())) : Date.now(); // Defaults to today + const targetDay = date ? new Date(date) : new Date(); // Defaults to today const [ // DAU: Daily Active User last30DauCounts, diff --git a/packages/core/src/routes/session/utils.ts b/packages/core/src/routes/session/utils.ts index baa70d546..93b6fecd8 100644 --- a/packages/core/src/routes/session/utils.ts +++ b/packages/core/src/routes/session/utils.ts @@ -1,7 +1,7 @@ import type { LogType, PasscodeType } from '@logto/schemas'; import { logTypeGuard } from '@logto/schemas'; import type { Truthy } from '@silverhand/essentials'; -import { addSeconds, isAfter, isValid, parseISO } from 'date-fns'; +import { addSeconds, isAfter, isValid } from 'date-fns'; import type { Context } from 'koa'; import type { Provider } from 'oidc-provider'; import type { ZodType } from 'zod'; @@ -60,7 +60,7 @@ export const getVerificationStorageFromInteraction = async { - const parsed = parseISO(expiresAt); + const parsed = new Date(expiresAt); assertThat( isValid(parsed) && isAfter(parsed, Date.now()), new RequestError({ code: 'session.verification_expired', status: 401 }) From d42a19133daec7f233f9e6b31cefd1868ed7b07f Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 7 Nov 2022 19:28:34 +0800 Subject: [PATCH 13/19] chore: optimize Dockerfile (#2334) --- Dockerfile | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/Dockerfile b/Dockerfile index 81641a922..5301427af 100644 --- a/Dockerfile +++ b/Dockerfile @@ -2,13 +2,14 @@ FROM node:16-alpine as builder WORKDIR /etc/logto ENV CI=true -COPY . . # Install toolchain -RUN npm add --location=global pnpm@^7.2.1 +RUN npm add --location=global pnpm@^7.14.0 # https://github.com/nodejs/docker-node/blob/main/docs/BestPractices.md#node-gyp-alpine RUN apk add --no-cache python3 make g++ +COPY . . + # Install dependencies and build RUN pnpm i RUN pnpm -r build From 494c4ae483c3887b54ce17b08a50401a5850345d Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 7 Nov 2022 19:29:19 +0800 Subject: [PATCH 14/19] refactor(core): optimize translation strictly partial check (#2333) --- .../core/src/routes/custom-phrase.test.ts | 12 ++--- packages/core/src/routes/custom-phrase.ts | 4 +- packages/core/src/utils/translation.test.ts | 12 ++--- packages/core/src/utils/translation.ts | 45 +++++++------------ 4 files changed, 30 insertions(+), 43 deletions(-) diff --git a/packages/core/src/routes/custom-phrase.test.ts b/packages/core/src/routes/custom-phrase.test.ts index e137ea7b1..007df147b 100644 --- a/packages/core/src/routes/custom-phrase.test.ts +++ b/packages/core/src/routes/custom-phrase.test.ts @@ -40,13 +40,13 @@ jest.mock('@/queries/custom-phrase', () => ({ upsertCustomPhrase: async (customPhrase: CustomPhrase) => upsertCustomPhrase(customPhrase), })); -const isValidStructure = jest.fn( +const isStrictlyPartial = jest.fn( (fullTranslation: Translation, partialTranslation: Partial) => true ); jest.mock('@/utils/translation', () => ({ - isValidStructure: (fullTranslation: Translation, partialTranslation: Translation) => - isValidStructure(fullTranslation, partialTranslation), + isStrictlyPartial: (fullTranslation: Translation, partialTranslation: Translation) => + isStrictlyPartial(fullTranslation, partialTranslation), })); const mockFallbackLanguage = trTrTag; @@ -130,13 +130,13 @@ describe('customPhraseRoutes', () => { }); }); - it('should call isValidStructure', async () => { + it('should call isStrictlyPartial', async () => { await customPhraseRequest.put(`/custom-phrases/${mockLanguageTag}`).send(translation); - expect(isValidStructure).toBeCalledWith(en.translation, translation); + expect(isStrictlyPartial).toBeCalledWith(en.translation, translation); }); it('should fail when the input translation structure is invalid', async () => { - isValidStructure.mockReturnValueOnce(false); + isStrictlyPartial.mockReturnValueOnce(false); const response = await customPhraseRequest .put(`/custom-phrases/${mockLanguageTag}`) .send(translation); diff --git a/packages/core/src/routes/custom-phrase.ts b/packages/core/src/routes/custom-phrase.ts index c32404d89..95c344f94 100644 --- a/packages/core/src/routes/custom-phrase.ts +++ b/packages/core/src/routes/custom-phrase.ts @@ -15,7 +15,7 @@ import { } from '@/queries/custom-phrase'; import { findDefaultSignInExperience } from '@/queries/sign-in-experience'; import assertThat from '@/utils/assert-that'; -import { isValidStructure } from '@/utils/translation'; +import { isStrictlyPartial } from '@/utils/translation'; import type { AuthedRouter } from './types'; @@ -70,7 +70,7 @@ export default function customPhraseRoutes(router: T) { const translation = cleanDeepTranslation(body); assertThat( - isValidStructure(resource.en.translation, translation), + isStrictlyPartial(resource.en.translation, translation), new RequestError('localization.invalid_translation_structure') ); diff --git a/packages/core/src/utils/translation.test.ts b/packages/core/src/utils/translation.test.ts index c492cb099..d9bb27671 100644 --- a/packages/core/src/utils/translation.test.ts +++ b/packages/core/src/utils/translation.test.ts @@ -1,7 +1,7 @@ import en from '@logto/phrases-ui/lib/locales/en'; import fr from '@logto/phrases-ui/lib/locales/fr'; -import { isValidStructure } from '@/utils/translation'; +import { isStrictlyPartial } from '@/utils/translation'; const customizedFrTranslation = { secondary: { @@ -10,15 +10,15 @@ const customizedFrTranslation = { }, }; -describe('isValidStructure', () => { +describe('isStrictlyPartial', () => { it('should be true when its structure is valid', () => { - expect(isValidStructure(en.translation, fr.translation)).toBeTruthy(); - expect(isValidStructure(en.translation, customizedFrTranslation)).toBeTruthy(); + expect(isStrictlyPartial(en.translation, fr.translation)).toBeTruthy(); + expect(isStrictlyPartial(en.translation, customizedFrTranslation)).toBeTruthy(); }); it('should be true when the structure is partial and the existing key-value pairs are correct', () => { expect( - isValidStructure(en.translation, { + isStrictlyPartial(en.translation, { secondary: { sign_in_with: 'Se connecter avec {{methods, list(type: disjunction;)}}', // Missing 'secondary.social_bind_with' key-value pair @@ -29,7 +29,7 @@ describe('isValidStructure', () => { it('should be false when there is an unexpected key-value pair', () => { expect( - isValidStructure(en.translation, { + isStrictlyPartial(en.translation, { secondary: { sign_in_with: 'Se connecter avec {{methods, list(type: disjunction;)}}', social_bind_with: diff --git a/packages/core/src/utils/translation.ts b/packages/core/src/utils/translation.ts index 4801531d7..73932c99d 100644 --- a/packages/core/src/utils/translation.ts +++ b/packages/core/src/utils/translation.ts @@ -1,38 +1,25 @@ import type { Translation } from '@logto/schemas'; -// LOG-4385: Refactor me -// eslint-disable-next-line complexity -export const isValidStructure = (fullTranslation: Translation, partialTranslation: Translation) => { - const fullKeys = new Set(Object.keys(fullTranslation)); - const partialKeys = Object.keys(partialTranslation); - - if (fullKeys.size === 0 || partialKeys.length === 0) { - return true; - } - - if (partialKeys.some((key) => !fullKeys.has(key))) { - return false; - } - - for (const [key, value] of Object.entries(fullTranslation)) { - const targetValue = partialTranslation[key]; - - if (targetValue === undefined) { - continue; - } - - if (typeof value === 'string') { - if (typeof targetValue === 'string') { - continue; - } +/** + * @param fullTranslation The translation with full keys + * @param partialTranslation The translation to check + * @returns If the flatten keys of `partialTranslation` is a subset of `fullTranslation` + */ +export const isStrictlyPartial = ( + fullTranslation: Translation, + partialTranslation: Translation +): boolean => { + return Object.entries(partialTranslation).every(([key, value]) => { + const fullValue = fullTranslation[key]; + if (!fullValue) { return false; } - if (typeof targetValue === 'string' || !isValidStructure(value, targetValue)) { - return false; + if (typeof fullValue === 'object' && typeof value === 'object') { + return isStrictlyPartial(fullValue, value); } - } - return true; + return typeof fullValue === typeof value; + }); }; From cbf75359c82b6ef9ce276a5d9df578e9975e3508 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Sun, 6 Nov 2022 00:29:28 +0800 Subject: [PATCH 15/19] chore: enable Node 18 --- .github/workflows/integration-test.yml | 2 ++ .github/workflows/main.yml | 6 ++++++ package.json | 4 ++-- packages/cli/package.json | 2 +- packages/console/package.json | 3 +++ packages/core/package.json | 2 +- packages/create/package.json | 2 +- packages/demo-app/package.json | 3 +++ packages/integration-tests/package.json | 3 +++ packages/phrases-ui/package.json | 3 +++ packages/phrases/package.json | 2 +- packages/schemas/package.json | 2 +- packages/shared/package.json | 2 +- packages/ui/package.json | 3 +++ 14 files changed, 31 insertions(+), 8 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index f2483f27d..80eafac28 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -46,6 +46,7 @@ jobs: strategy: matrix: os: [ubuntu-latest] + node_version: [16, 18] runs-on: ${{ matrix.os }} @@ -69,6 +70,7 @@ jobs: - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v2 with: + node-version: ${{ matrix.node_version }} run-install: false # Setup integration test diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index dffec17c5..af5765f0d 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -47,11 +47,17 @@ jobs: main-test: runs-on: ubuntu-latest + strategy: + matrix: + node_version: [16, 18] + steps: - uses: actions/checkout@v3 - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v2 + with: + node-version: ${{ matrix.node_version }} - name: Prepack run: pnpm prepack diff --git a/package.json b/package.json index 291afbab8..d4e93b575 100644 --- a/package.json +++ b/package.json @@ -33,8 +33,8 @@ ] }, "engines": { - "node": ">=14.15.0", - "pnpm": ">=6" + "node": "^16.13.0 || ^18.12.0", + "pnpm": "^7.14.0" }, "alias": { "html-parse-stringify": "html-parse-stringify/dist/html-parse-stringify.module.js", diff --git a/packages/cli/package.json b/packages/cli/package.json index de9625cb1..a34330050 100644 --- a/packages/cli/package.json +++ b/packages/cli/package.json @@ -34,7 +34,7 @@ "prepack": "pnpm build" }, "engines": { - "node": "^16.0.0" + "node": "^16.13.0 || ^18.12.0" }, "bugs": { "url": "https://github.com/logto-io/logto/issues" diff --git a/packages/console/package.json b/packages/console/package.json index 0eb6f0e5b..e0de9a9d7 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -84,6 +84,9 @@ "typescript": "^4.7.4", "zod": "^3.19.1" }, + "engines": { + "node": "^16.13.0 || ^18.12.0" + }, "alias": { "@/*": "./src/$1", "@mdx/components/*": "./src/mdx-components/$1" diff --git a/packages/core/package.json b/packages/core/package.json index 6b76aa0b7..f182c9653 100644 --- a/packages/core/package.json +++ b/packages/core/package.json @@ -100,7 +100,7 @@ "typescript": "^4.7.4" }, "engines": { - "node": "^16.0.0" + "node": "^16.13.0 || ^18.12.0" }, "_moduleAliases": { "@": "./build" diff --git a/packages/create/package.json b/packages/create/package.json index a950e218f..82161724c 100644 --- a/packages/create/package.json +++ b/packages/create/package.json @@ -11,7 +11,7 @@ }, "scripts": {}, "engines": { - "node": "^16.0.0" + "node": "^16.13.0 || ^18.12.0" }, "dependencies": { "@logto/cli": "workspace:^" diff --git a/packages/demo-app/package.json b/packages/demo-app/package.json index 245754ce1..c03ab536f 100644 --- a/packages/demo-app/package.json +++ b/packages/demo-app/package.json @@ -44,6 +44,9 @@ "stylelint": "^14.9.1", "typescript": "^4.7.4" }, + "engines": { + "node": "^16.13.0 || ^18.12.0" + }, "alias": { "@/*": "./src/$1" }, diff --git a/packages/integration-tests/package.json b/packages/integration-tests/package.json index 9abf959e9..228b5f5f7 100644 --- a/packages/integration-tests/package.json +++ b/packages/integration-tests/package.json @@ -39,6 +39,9 @@ "ts-node": "^10.9.1", "typescript": "^4.7.4" }, + "engines": { + "node": "^16.13.0 || ^18.12.0" + }, "eslintConfig": { "extends": "@silverhand" }, diff --git a/packages/phrases-ui/package.json b/packages/phrases-ui/package.json index df0a50a77..0b690b2a2 100644 --- a/packages/phrases-ui/package.json +++ b/packages/phrases-ui/package.json @@ -44,6 +44,9 @@ "prettier": "^2.7.1", "typescript": "^4.7.4" }, + "engines": { + "node": "^16.13.0 || ^18.12.0" + }, "eslintConfig": { "extends": "@silverhand" }, diff --git a/packages/phrases/package.json b/packages/phrases/package.json index f79eef4b7..0eef2125d 100644 --- a/packages/phrases/package.json +++ b/packages/phrases/package.json @@ -25,7 +25,7 @@ "prepack": "pnpm build" }, "engines": { - "node": "^16.0.0" + "node": "^16.13.0 || ^18.12.0" }, "bugs": { "url": "https://github.com/logto-io/logto/issues" diff --git a/packages/schemas/package.json b/packages/schemas/package.json index c561267c8..91258e648 100644 --- a/packages/schemas/package.json +++ b/packages/schemas/package.json @@ -27,7 +27,7 @@ "test:ci": "jest" }, "engines": { - "node": "^16.0.0" + "node": "^16.13.0 || ^18.12.0" }, "devDependencies": { "@silverhand/eslint-config": "1.3.0", diff --git a/packages/shared/package.json b/packages/shared/package.json index c44c5ab15..ab3ab05bf 100644 --- a/packages/shared/package.json +++ b/packages/shared/package.json @@ -33,7 +33,7 @@ "typescript": "^4.7.4" }, "engines": { - "node": "^16.0.0" + "node": "^16.13.0 || ^18.12.0" }, "eslintConfig": { "extends": "@silverhand", diff --git a/packages/ui/package.json b/packages/ui/package.json index 881351cc7..6e4021263 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -71,6 +71,9 @@ "typescript": "^4.7.4", "use-debounced-loader": "^0.1.1" }, + "engines": { + "node": "^16.13.0 || ^18.12.0" + }, "alias": { "@/*": "./src/$1" }, From 33fd811beee092367c15631c0c60c828ef36d3e2 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Sun, 6 Nov 2022 00:48:00 +0800 Subject: [PATCH 16/19] refactor(cli): update node version check --- packages/cli/src/commands/install/utils.ts | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/packages/cli/src/commands/install/utils.ts b/packages/cli/src/commands/install/utils.ts index e21d7ee0e..529d562f8 100644 --- a/packages/cli/src/commands/install/utils.ts +++ b/packages/cli/src/commands/install/utils.ts @@ -27,16 +27,17 @@ export const defaultPath = path.join(os.homedir(), 'logto'); const pgRequired = new semver.SemVer('14.0.0'); export const validateNodeVersion = () => { - const required = new semver.SemVer('16.0.0'); + const required = [new semver.SemVer('16.13.0'), new semver.SemVer('18.12.0')]; + const requiredVersionString = required.map((version) => '^' + version.version).join(' || '); const current = new semver.SemVer(execSync('node -v', { encoding: 'utf8', stdio: 'pipe' })); - if (required.compare(current) > 0) { - log.error(`Logto requires NodeJS >=${required.version}, but ${current.version} found.`); + if (required.every((version) => version.major !== current.major)) { + log.error(`Logto requires NodeJS ${requiredVersionString}, but ${current.version} found.`); } - if (current.major > required.major) { + if (required.some((version) => version.major === current.major && version.compare(current) > 0)) { log.warn( - `Logto is tested under NodeJS ^${required.version}, but version ${current.version} found.` + `Logto is tested under NodeJS ${requiredVersionString}, but version ${current.version} found.` ); } }; From 117b50af7a35986dad039210c550f372c6610101 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 7 Nov 2022 21:40:09 +0800 Subject: [PATCH 17/19] chore: fix parcel engines issue See https://github.com/parcel-bundler/parcel/issues/7636 --- packages/console/package.json | 8 ++++++++ packages/demo-app/package.json | 8 ++++++++ packages/ui/package.json | 8 ++++++++ 3 files changed, 24 insertions(+) diff --git a/packages/console/package.json b/packages/console/package.json index e0de9a9d7..1951295f3 100644 --- a/packages/console/package.json +++ b/packages/console/package.json @@ -87,6 +87,14 @@ "engines": { "node": "^16.13.0 || ^18.12.0" }, + "//": "https://github.com/parcel-bundler/parcel/issues/7636", + "targets": { + "default": { + "engines": { + "browsers": "defaults" + } + } + }, "alias": { "@/*": "./src/$1", "@mdx/components/*": "./src/mdx-components/$1" diff --git a/packages/demo-app/package.json b/packages/demo-app/package.json index c03ab536f..8e310b50b 100644 --- a/packages/demo-app/package.json +++ b/packages/demo-app/package.json @@ -47,6 +47,14 @@ "engines": { "node": "^16.13.0 || ^18.12.0" }, + "//": "https://github.com/parcel-bundler/parcel/issues/7636", + "targets": { + "default": { + "engines": { + "browsers": "defaults" + } + } + }, "alias": { "@/*": "./src/$1" }, diff --git a/packages/ui/package.json b/packages/ui/package.json index 6e4021263..738397014 100644 --- a/packages/ui/package.json +++ b/packages/ui/package.json @@ -74,6 +74,14 @@ "engines": { "node": "^16.13.0 || ^18.12.0" }, + "//": "https://github.com/parcel-bundler/parcel/issues/7636", + "targets": { + "default": { + "engines": { + "browsers": "defaults" + } + } + }, "alias": { "@/*": "./src/$1" }, From 3a0df40fc171586e770869cd5c718a5d0aee8800 Mon Sep 17 00:00:00 2001 From: Gao Sun Date: Mon, 7 Nov 2022 23:11:21 +0800 Subject: [PATCH 18/19] chore: manually install Chromium before integration test --- .github/workflows/integration-test.yml | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-) diff --git a/.github/workflows/integration-test.yml b/.github/workflows/integration-test.yml index 80eafac28..165c7139b 100644 --- a/.github/workflows/integration-test.yml +++ b/.github/workflows/integration-test.yml @@ -18,13 +18,6 @@ jobs: steps: - uses: actions/checkout@v3 - - name: Cache Puppeteer - uses: actions/cache@v3 - with: - # https://pptr.dev/guides/configuration/#changing-the-default-cache-directory - path: ~/.cache/puppeteer - key: ${{ runner.os }}-pptr-${{ hashFiles('packages/integration-tests/package.json') }} - - name: Setup Node and pnpm uses: silverhand-io/actions-node-pnpm-run-steps@v2 @@ -45,23 +38,15 @@ jobs: strategy: matrix: - os: [ubuntu-latest] node_version: [16, 18] - runs-on: ${{ matrix.os }} + runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 with: path: tests - - name: Cache Puppeteer - uses: actions/cache@v3 - with: - # https://pptr.dev/guides/configuration/#changing-the-default-cache-directory - path: ~/.cache/puppeteer - key: ${{ runner.os }}-pptr-${{ hashFiles('tests/packages/integration-tests/package.json') }} - - name: Copy lockfile run: | cp tests/pnpm-lock.yaml ./ @@ -79,6 +64,9 @@ jobs: cd tests pnpm i pnpm prepack + # Install Chromium + cd packages/integration-tests/node_modules/puppeteer + pnpm postinstall # Setup environment - name: Setup Postgres From b137daeb129e73d802949d13ddb0a2cc7bddd1e4 Mon Sep 17 00:00:00 2001 From: Charles Zhao Date: Tue, 8 Nov 2022 16:57:11 +0800 Subject: [PATCH 19/19] chore(console): update default avatars (#2341) --- .../console/src/assets/avatars/avatar-002.png | Bin 6320 -> 6206 bytes .../console/src/assets/avatars/avatar-005.png | Bin 8028 -> 2900 bytes .../console/src/assets/avatars/avatar-010.png | Bin 6206 -> 0 bytes packages/console/src/consts/avatars.ts | 2 -- 4 files changed, 2 deletions(-) delete mode 100644 packages/console/src/assets/avatars/avatar-010.png diff --git a/packages/console/src/assets/avatars/avatar-002.png b/packages/console/src/assets/avatars/avatar-002.png index fb2862be37ccce04175eefb4f0f23d6ef0abd4af..46dea241dd9f2100b54097eb3f48351d8d7e3d9c 100644 GIT binary patch delta 3340 zcmcImc~nzp7SDS;F)0FJpRz~PsRBX5($BFoJ=5B0&*_=>&pY=!_uYHH`+mRs zyR}=|tZM^R&{aKNZZ3gLXljU>v-Y-za<`F79+?sx-ASf~?We-uwLDec)~U(1&0~AK z`Bu~!Lhe^5Xm3uoyVY%SFx`4-yyISA(xL6GSJm5x^GoxjTvnnVW$53Xjqo5XEGuo5oJ`P8Vz$x3a{PZiX$vX?%>j~Rh(mJLbc+4U%2Yz*`!WI zIwOiP$_aD4eto^n)O+|{_Eiut=Ja)F zIKeIRES@P0FMNDfPBz~dq2~B7pFSKCQ_Y%wmeXs@&*o?3cILK@Xff~bgAs2cG42x^ z^Ao&$jF5X1wa=oFAjndn>`wk0D0_=-q=xw#3eT*cO@t4?u%k$10h@tpm)WY3#qy=E z4>>P<^tP>yaaz9Yn(cAexm|n^X01S&HQXVRqZx(g_oMwqUKj)oPaI8x{lL9}aouEqX(sQIq9qW}#TyC-y9W)T6Fsmc$3)aW29ks)i0UFp|-fPJu;-9od zJk^4PFEsfX;$!!IH*S!DxAX1{P)r@pGJ>( zM502Jr5e|0nr{Z(ze$y%bMenI8}hP5jdc|{y>fX5sx^z0B$fwf@RUJsuvj0s4ndfo zT|pCxN62KM>eCx*t$k=%q}SeGd%SdL8Z>0~jzBr0*3xk282V`2=5VJJg-9e=nC085 z8=mgv_NP45VhTm^Z{QmNM9Q?rDb^GUPl@ik#^0TWRVKI^A<7^jfxiK%006k)do`Vh zVFY!QZGVcUgWtc4^I3g^`vrrnz7!^ZSKp&{ttMZqKv!WcMlfE-fbnf0Y`NaXHF1D# z>gVinnh^w5-&eUnwgX(u=qRGGb1*{R*eP$Kp)TEdrHzz2_}pxLzPi;1X<`!R)+0+K z072|dJ-CGQ5{WYX$QH7v23e?$?#|K-GNtgMi>6#DpwgW|o4q5lF+xrJ4HaA)f_y({ zFvs74;opz&*8-rRhQAi!j{@K}sPV%Q$af4Ka35KgjTSbb%R>`|x4VvaYt2=m#fhPL z002JqkK9Xk(Xg)m;J!pa$Tqja&?mtwkh!XVInbZibU$eR@!8{np0iHeH1AL@Yw?<0 zwyqqB?Xf7+oC^@v`w8j3`HKe?nh*OL;WOxTIO3eT_+ScdYu1nFBojgAOL+65Wm^kI zc=dU=$l9pa7{vrRLW-&=mGE!IGPE(zy6!u6K3v zvY?HV!c@plmL{T3lO&GFss8^0c1w9{_l8VT*7lLQ)P%~*BR(k!snU^6LK3HMM1qun ztCpj4Mejw_UjusvK0o8&lZtxk5 z@X8i$jT5XhT6`~P`mOU9EQF+@RY#KHi!fYtEjkA70Pk1!l(UitgZosj6uEydYagXx zV!jbmd{OfAKt+EuQQ3=;!h6l9vYub8i({yr7m-p3--VC@fi@jB+M$jsfiAx~u$zh$ z(w!Fgw;Pw!s=7`-h~>wH={j9f0lbeCIOT>FL z?Dk-hJNqQ)5|GOo zS0IJ;E*i)!5bw8p#>+JWw_yl1_i{Ix6v($T1Wy;aA=jtTW$N)zf#P!VQdJhWUz+z) zCB;Fn)4)FzN$Zs*r&se?mv7RimpTqnIs1ad+@%*XefhB6ggnuMWmvp5snh_VIqAeG zq7QDHzHY-Al(v?_J9GM%gWtFFm8=fm6G!Ce-wh3SF59guG3a?AkuH0F8QJ^2hxm?Q zu<5&(BHUYizz8+~O;BpyOu7R&7JRmMO|1(Jvt<|SjQ8it8<+b5@urqq=0$)S9K4fzgXc55u(6=fopHl*YHlX4 zbj0GFMd{*_c;u+WV6}yfG&{|BCRmy=nUV}=B(>=gd%)5(PYqau`_r&@^{vQP!B#bc zvaYzopJRlKx5Fs@;WTVQ?s*Dvg&?&k4vpQ$tGAa0i(5THnqr(%>bv(#ZH-q)f4u(p eIPiyvT+n;usw3XesFOtikC(fz8&d5WapEV0LA`DO delta 3454 zcmb`JX;c(f7RS4aLK@J}4FZ8cQz8Q*0vaR`WGO{90a-;*2$0DLE5(L{>$*YZ4Qq5do2X=^|u6Wa(C9k*()>CZ94hXYyg{+pF`=z3<)kzrX(# z?yTKa>#vM&a(3Il*FO=O8TRDs++}a*xVoz;l2UHd8s97^U=%!@U>6tMUx1P~oD45+ z-*tYAsehOHAvcYST6^tlzMf0hO1`R>aUvl|B1~Riz9?g(-hOn9<<9|@5G>PVg-Iat zI~WdbK6}6jrA8q5b9tnhJ9qscMzqQyO3F+wK00n(KroUNn42|N^mlE3HW0M%9&6hU zl=?icEFOlZby4p?j8L}nnnaMkJy>xq!O)B@e5S~(_rOO(GF9T8jg=P;0g&wkyuWh^#YV6+Qv%NI+QM0yC*cPpA`u2-U$9Kbi@<`(LrgZlECMfl1yUWgD6+{ZHH?)vcCgjC% zj^Rt29^I4+pdCHT^t1dhB5uLy5b~ZPQ@X`all_x1jfi~OFo!SY-O*lph-%RzsdB>9l^#SKEf7 zlzi^3{qR+S;qu|THEkiK4I5^s8fV4)?Y!r4g0){?)J>HyU!Du0l%_p@FJJ0T5h+O7 zSJb8?s&e=e=gjYVxl$q4YlLNQe3!i7ZUkvQ^65p;x={(wZc zL9{%*>~dMJt#@6zZFF!fkc?Tec1IfsMp^WgUzkHcFN5|^Rb7FQZVw8q;U;-xsqso3 z;tPuNa$y^vih>~F%-9a{IlMqh>K~>`aNT0Mer=R-Od4(?4fFnx!bV|NZ#y_i1hQqM!rDqs2uFRAs$9Wm- z^eA49pnX&ql3d(II1ksQQAIs<0d&BwUNu((l*-J#xf!kk;@duc4$j08#M;N=`o7{r z7;*H6U@sJu)#$`|UuL}$lUsRXO3^^IFIulJHKwG=%UDG@kkm8W%^>FxWXU$k%TNkn z;NTI-fG2>W&Mp*s&;SUjH#!)|Q#By-X}cWidl+8bc@tvh8`TcmOV2(pOm?Rh{}wa( zVB#C<+shU>@(k2wS;IIB1IPhC{=m9VfiqOX6Rqv~>_KE`{7b!Ylm( z=&FIJJC)!#Cv+`~st_cxG9hpJ1PtFl;?fpj0zo4c!-g%n1f!1LZ~7`;RT{Dx&FOWieDFk@ zgZF6HB@S(wz?lJbeu|Ge=?Ji#@yH1|4RrTZSbl-p0;v4pSAF ze$isxxp+Y^C9xgH+a`U+T;?xn%REON-m^_weQ~!%w+WW?#Lk5rz=-Sp;$SZrugj05q|Z1*~l`0QF~hm;>&#ZjO)X_ zJ}Ws@Ar(SdQ0aQPsB@)b;NkY(qhw|LfdZtO$&{*ZPG|Z90Blj6=5%dH zFYzL({AyljHl6uoB{)WYq^$SYy<&o4-skU!54d2&;$%aP*|v9>i*%5Vm8mE<#)^zv z@81{MO!llhOCELqU5!%@8=boF1ye_zMGJhZw`O@`gxW_=ZU|p#$BNd{Hmq%GTHG@| zxKvR^jd@;n4FfIaC0Ib=G2l=4Z?hFW)TCO8+6@YAtc-$jLf6O} zqm+V+-7MTM2`7GC9IYS_OQ;RChBnjBVj1@9P4s z6UAF<(xWfpO?^5%$VhSXRSIc*ZL@(Zx|XTC`D-Jth7+JWf76zU zRORc)AL{gR-E&ts!fmhdMEVDXTG)Iftm`Nk40>m4`c2JH>Y`QOn;s2t@|pGAkTUGc zwQv(|MB1=3nntKwJ8D)xr<=rwy>-rQ4UKn*9l-+#9++O8^`mwuu(HD_-wc;53K_2U;Wb zJ{)MT2aej@ZFCP8HiWi>08RX%7)+_}%8On$hH7%ze50r`4cLjEEP2m7q!?ah`6*T4} z?Ghc>6znef#}W7uFtZ@X>yE`vz|87{-O(IiW+yXFGwYd5?!~W8DjKL+N9kEF4|cwY z@w|4|GJ7rpuMO3nsrkr(eq^GMX(GD;W z=|)Cx$pX>q;`iwyHlRD@+Dwr+s3+<-y0G5|gNMNB zvP)PA=)MOF+h76czWVZ4OpnbhIDU9_Zb;~^wmAi5&3XL>dGp5VdrVCN6YwVI+ z5}6Uw47m#FZwE5OWqBToc8^y1@PR`vEA9m09$a6wfvMt)1-w_)QA{+BLD3m__3Q z5Qzieiw^*Ju?;#bwc?PeSn$co&cy=mWxzZ-+{ajaUoz74c(^fhxG~E>TLYz}fZn7a z)`I&>huK-^O^SSWRy*UqDoS2b0!Sf%=?;jf1*~+z4@hA7BTz*tqBkkEmlX2rtB32V zhU=?gUKjkn6Yl9iDQz^++Bwqjdhu;L{En-)LzBxWl7JxPjf!n0g>V-K?s@}vb4F^J za77XPq5yvJbg`@uF3E-IdCKx~Xa#wcyqw-P4KDpzTS5#!Gif+8iTmI-N=XT3&Q68Po{r=^GSJwHQji~hT?u!$Ew(km+!h#yUE_GW#gRaMwpQl0!7{%)i6`sB ztdE`pVB6l623b5b^bs?Wq=WVr$j>rT3X+;>=35wIHTQ$&`&};djHg{Z-eIaxM^>Kv zJGXL|^oAI87~130c3s^KUMv{t?86O=dd^Mq=+PSg8J-PAmsdC;m~JjK_T&56Y|-nnB_Bl*JvKx?$qGN~zKUVL8&qkX zm}g~!fKg-~%w1px0ZhOI(g4m8P>MU6dGaPGQGvH#cCiA0#8h+(sLn>KRfR12=)+dr z!%P#MUkEDA@V#}xUoqR!1Qi2e+a^lEvUBY3D=|ycJlCo8!mg6IqXhmatj`JzY53TF z4OKo8YLjxm5+j(2?wCxvJXL4atml7>O5aPl@^}=Z>q_9Oi};zR=z=-+m&8Y=Uder} zvzPMfUe5uyBi;4%3W*iy6$^!K4|G3H%}I=p7RewD#Ng}c2fCR^uG09 z=NCEx9uhWb`;|(4;9LIDuSYKx`la@>qU}Nh=6@Y``5*+Tw<8Om`)L9R4ItrjXSx+( zB8y9^%rKFEoAPL~Wbx6HT!P1@_F(pqB!f(>P^h0He3|vISo9r`c}zH=OWq$jmYE(> z4=b{Ub-&2VcqiKG3y>-((OzXk#nq%Kfa4&JEs_)w9O}_AR2-V-(TDAT!?(;IXp{ep zSP?CJ7ZGTkwWbb!`s;{5Oh3fo<)vx2>0}}}k=2UOk}JwbGZTuNntgg*Ikbek!s+7jF1*rZVH))}p@`F*%>UUCGl@%#B~lLaYL>s}evl zR0SY;P~0`|T-XmfZr=I6W5(bUO6IzQNxLw`jCiK})K}7;ldO5fCzRa{hccHH=6N>r zUSL6oQ0DtC9F?e4aq+u#!&NRWl|ZJEOy`E4eDnQh$PJrPY$#a#37e=!G};=ni^sF> zwM>50-z1Zbj3blE7jVkaO>N(f$3|3ugI~|+wP z`n6Ms?^0YSqJu++TQM2OjV@D;&Iu8#Fo_yf+gVoA(Z^`Ksa7zW->0~Q4w}BW19nq; zQA{52HrbOsTch?2>3(kJE+5=++%eDkSoTjhda(T2o}3kllzY_7-M63|&RM><@bkz8 zW8!bUt_`mjpog<-D@fDSrF42!^3t7D6U>NgYulx3TSjd zcii=eo{C1N)yng!5m1oqX`ANFje8>oCb!QdV2EfVhS<|~-_C*u=yv}IDAGYud zJ{egq!F$)M%AIH>)@XaYCa)A81@Hv2-uDqXR9$J;b?fzG;^uRG*Amv-;cxY*_-Wf% zJdLrvX*yBK&Mqmtrfb;V!Fd>ycrs`E9UeKsJ{M1I4?aODtQ*^1et+Mpn;O8f_x?{> zRVPex@*|J)6jXnG&?F3EoM}<>%PJ>Wa#aPL<;E8{IckTDj+MQ zj2(mV(=@h(pi$rTm01wIc%Umj*WX(e zs#jQZ+3u!@od;ciqpF`!0zVl?>x^q_d->FoubzyUiDp3eg$W6p&h_~uc`SK*f>-_+ zk&c^^OqxIDdzwB=;|ehXVYHwkzsGym)~cArjAw9Ww`=EeL>o9VgrqE`M|vucW6`oc zQ|MS#88JeXXR-gb@8(A!T#LMvh&2W!m(!TkI0x%5YE^9>#IpqJoZ3jajC+Cl^z6%E z?dEI^xOr3BZi<(^_u1k*EpgZ zqTf#HR9(%)1{yoC)YN%`jb_ZN0GnUCfJimnx>|g3dbEa%fhQl$-lahCgTElZj=o4J z!N1YY>5o>sz;Br4-Wp_4#&xP5r?Xm{P2qiJ`=&WlBa`2*w6Un?jWt7=mqpqaz3?NB zRHZ1C#yeA@UI`nlrM3^SmoYCNn?9u+0C8h*@ot{pwz8Ldc8IP4jdyS+9Oy0;HkU&v zca#RsGtGVvKtK>|W9tyD`qcFW=hx_iz7Jr|QFWR2ov{7_E2|T(za0SI;gt0!X1)#0*?7r_ zJu$RaI>k#^&!BB=Z(OmOxe*}#?b=DQa3`JcC7s0kN1PN7zzAn#WMF7$fHQG1G{NJH r@w<)na5y{;S6h&w`F{qXXHNtNkpJ6&F{P3&HUI}L9Lx(3_+0rP`Vu2q literal 8028 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 K)qbyviTN*%RK$t^ diff --git a/packages/console/src/assets/avatars/avatar-010.png b/packages/console/src/assets/avatars/avatar-010.png deleted file mode 100644 index 46dea241dd9f2100b54097eb3f48351d8d7e3d9c..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 6206 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 P`p?nVG19Kka*X~jTdy{7 diff --git a/packages/console/src/consts/avatars.ts b/packages/console/src/consts/avatars.ts index ce6258de9..32b79b63c 100644 --- a/packages/console/src/consts/avatars.ts +++ b/packages/console/src/consts/avatars.ts @@ -7,7 +7,6 @@ import avatar006 from '@/assets/avatars/avatar-006.png'; import avatar007 from '@/assets/avatars/avatar-007.png'; import avatar008 from '@/assets/avatars/avatar-008.png'; import avatar009 from '@/assets/avatars/avatar-009.png'; -import avatar010 from '@/assets/avatars/avatar-010.png'; export const Avatars = [ avatar001, @@ -19,7 +18,6 @@ export const Avatars = [ avatar007, avatar008, avatar009, - avatar010, ]; export const generateAvatarPlaceHolderById = (id: string) =>