Browse Source

chore: merge hoppscotch/release/2023.8.3 into hoppscotch/release/2023.12.0

Andrew Bastin 1 year ago
parent
commit
6daa043a1b

+ 3 - 3
packages/codemirror-lang-graphql/package.json

@@ -17,12 +17,12 @@
   "types": "dist/index.d.ts",
   "sideEffects": false,
   "dependencies": {
-    "@codemirror/language": "^6.9.0",
+    "@codemirror/language": "^6.9.1",
     "@lezer/highlight": "^1.1.6",
-    "@lezer/lr": "^1.3.10"
+    "@lezer/lr": "^1.3.13"
   },
   "devDependencies": {
-    "@lezer/generator": "^1.5.0",
+    "@lezer/generator": "^1.5.1",
     "mocha": "^9.2.2",
     "rollup": "^3.29.3",
     "rollup-plugin-dts": "^6.0.2",

+ 10 - 11
packages/hoppscotch-common/package.json

@@ -17,22 +17,22 @@
     "postinstall": "pnpm run gql-codegen",
     "do-test": "pnpm run test",
     "do-lint": "pnpm run prod-lint",
-    "do-typecheck": "pnpm run lint",
+    "do-typecheck": "node type-check.mjs",
     "do-lintfix": "pnpm run lintfix"
   },
   "dependencies": {
     "@apidevtools/swagger-parser": "^10.1.0",
-    "@codemirror/autocomplete": "^6.9.0",
-    "@codemirror/commands": "^6.2.4",
-    "@codemirror/lang-javascript": "^6.1.9",
+    "@codemirror/autocomplete": "^6.10.2",
+    "@codemirror/commands": "^6.3.0",
+    "@codemirror/lang-javascript": "^6.2.1",
     "@codemirror/lang-json": "^6.0.1",
     "@codemirror/lang-xml": "^6.0.2",
-    "@codemirror/language": "^6.9.0",
+    "@codemirror/language": "^6.9.1",
     "@codemirror/legacy-modes": "^6.3.3",
-    "@codemirror/lint": "^6.4.0",
-    "@codemirror/search": "^6.5.1",
-    "@codemirror/state": "^6.2.1",
-    "@codemirror/view": "^6.16.0",
+    "@codemirror/lint": "^6.4.2",
+    "@codemirror/search": "^6.5.4",
+    "@codemirror/state": "^6.3.1",
+    "@codemirror/view": "^6.21.3",
     "@fontsource-variable/inter": "^5.0.8",
     "@fontsource-variable/material-symbols-rounded": "^5.0.7",
     "@fontsource-variable/roboto-mono": "^5.0.9",
@@ -42,8 +42,6 @@
     "@hoppscotch/ui": "workspace:^",
     "@hoppscotch/vue-toasted": "^0.1.0",
     "@lezer/highlight": "^1.1.6",
-    "@sentry/tracing": "^7.64.0",
-    "@sentry/vue": "^7.64.0",
     "@urql/core": "^4.1.1",
     "@urql/devtools": "^2.0.3",
     "@urql/exchange-auth": "^2.1.6",
@@ -139,6 +137,7 @@
     "eslint": "^8.47.0",
     "eslint-plugin-prettier": "^5.0.0",
     "eslint-plugin-vue": "^9.17.0",
+    "glob": "^10.3.10",
     "npm-run-all": "^4.1.5",
     "postcss": "^8.4.23",
     "prettier-plugin-tailwindcss": "^0.5.6",

+ 7 - 2
packages/hoppscotch-common/src/modules/i18n.ts

@@ -58,7 +58,13 @@ export const FALLBACK_LANG = pipe(
 )
 
 // A reference to the i18n instance
-let i18nInstance: I18n<any, any, any> | null = null
+let i18nInstance: I18n<
+  Record<string, unknown>,
+  Record<string, unknown>,
+  Record<string, unknown>,
+  string,
+  true
+> | null = null
 
 const resolveCurrentLocale = () =>
   pipe(
@@ -119,7 +125,6 @@ export const changeAppLanguage = async (locale: string) => {
  * Returns the i18n instance
  */
 export function getI18n() {
-  // @ts-expect-error Something weird with the i18n errors
   return i18nInstance!.global.t
 }
 

+ 0 - 200
packages/hoppscotch-common/src/modules/sentry.ts

@@ -1,200 +0,0 @@
-import { HoppModule } from "."
-import * as Sentry from "@sentry/vue"
-import { BrowserTracing } from "@sentry/tracing"
-import { Route } from "@sentry/vue/types/router"
-import { RouteLocationNormalized, Router } from "vue-router"
-import { settingsStore } from "~/newstore/settings"
-import { App } from "vue"
-import { APP_IS_IN_DEV_MODE } from "~/helpers/dev"
-import { gqlClientError$ } from "~/helpers/backend/GQLClient"
-import { platform } from "~/platform"
-
-/**
- * The tag names we allow giving to Sentry
- */
-type SentryTag = "BACKEND_OPERATIONS"
-
-interface SentryVueRouter {
-  onError: (fn: (err: Error) => void) => void
-  beforeEach: (fn: (to: Route, from: Route, next: () => void) => void) => void
-}
-
-function normalizedRouteToSentryRoute(route: RouteLocationNormalized): Route {
-  return {
-    matched: route.matched,
-    // route.params' type translates just to a fancy version of this, hence assertion
-    params: route.params as Route["params"],
-    path: route.path,
-    // route.query's type translates just to a fancy version of this, hence assertion
-    query: route.query as Route["query"],
-    name: route.name,
-  }
-}
-
-function getInstrumentationVueRouter(router: Router): SentryVueRouter {
-  return <SentryVueRouter>{
-    onError: router.onError,
-    beforeEach(func) {
-      router.beforeEach((to, from, next) => {
-        func(
-          normalizedRouteToSentryRoute(to),
-          normalizedRouteToSentryRoute(from),
-          next
-        )
-      })
-    },
-  }
-}
-
-let sentryActive = false
-
-function initSentry(dsn: string, router: Router, app: App) {
-  Sentry.init({
-    app,
-    dsn,
-    release: import.meta.env.VITE_SENTRY_RELEASE_TAG ?? undefined,
-    environment: APP_IS_IN_DEV_MODE
-      ? "dev"
-      : import.meta.env.VITE_SENTRY_ENVIRONMENT,
-    integrations: [
-      new BrowserTracing({
-        routingInstrumentation: Sentry.vueRouterInstrumentation(
-          getInstrumentationVueRouter(router)
-        ),
-        // TODO: We may want to limit this later on
-        tracingOrigins: [new URL(import.meta.env.VITE_BACKEND_GQL_URL).origin],
-      }),
-    ],
-    tracesSampleRate: 0.8,
-  })
-  sentryActive = true
-}
-
-function deinitSentry() {
-  Sentry.close()
-  sentryActive = false
-}
-
-/**
- * Reports a set of related errors to Sentry
- * @param errs The errors to report
- * @param tag The tag for the errord
- * @param extraTags Additional tag data to add
- * @param extras Extra information to attach
- */
-function reportErrors(
-  errs: Error[],
-  tag: SentryTag,
-  extraTags: Record<string, string | number | boolean> | null = null,
-  extras: any = undefined
-) {
-  if (sentryActive) {
-    Sentry.withScope((scope) => {
-      scope.setTag("tag", tag)
-      if (extraTags) {
-        Object.entries(extraTags).forEach(([key, value]) => {
-          scope.setTag(key, value)
-        })
-      }
-      if (extras !== null && extras === undefined) scope.setExtras(extras)
-
-      scope.addAttachment({
-        filename: "extras-dump.json",
-        data: JSON.stringify(extras),
-        contentType: "application/json",
-      })
-
-      errs.forEach((err) => Sentry.captureException(err))
-    })
-  }
-}
-
-/**
- * Reports a specific error to Sentry
- * @param err The error to report
- * @param tag The tag for the error
- * @param extraTags Additional tag data to add
- * @param extras Extra information to attach
- */
-function reportError(
-  err: Error,
-  tag: SentryTag,
-  extraTags: Record<string, string | number | boolean> | null = null,
-  extras: any = undefined
-) {
-  reportErrors([err], tag, extraTags, extras)
-}
-
-/**
- * Subscribes to events occuring in various subsystems in the app
- * for personalized error reporting
- */
-function subscribeToAppEventsForReporting() {
-  gqlClientError$.subscribe((ev) => {
-    switch (ev.type) {
-      case "SUBSCRIPTION_CONN_CALLBACK_ERR_REPORT":
-        reportErrors(ev.errors, "BACKEND_OPERATIONS", { from: ev.type })
-        break
-
-      case "CLIENT_REPORTED_ERROR":
-        reportError(
-          ev.error,
-          "BACKEND_OPERATIONS",
-          { from: ev.type },
-          { op: ev.op }
-        )
-        break
-
-      case "GQL_CLIENT_REPORTED_ERROR":
-        reportError(
-          new Error("Backend Query Failed"),
-          "BACKEND_OPERATIONS",
-          { opType: ev.opType },
-          {
-            opResult: ev.opResult,
-          }
-        )
-        break
-    }
-  })
-}
-
-/**
- * Subscribe to app system events for adding
- * additional data tags for the error reporting
- */
-function subscribeForAppDataTags() {
-  const currentUser$ = platform.auth.getCurrentUserStream()
-
-  currentUser$.subscribe((user) => {
-    if (sentryActive) {
-      Sentry.setTag("user_logged_in", !!user)
-    }
-  })
-}
-
-export default <HoppModule>{
-  onRouterInit(app, router) {
-    if (!import.meta.env.VITE_SENTRY_DSN) {
-      console.log(
-        "Sentry tracing is not enabled because 'VITE_SENTRY_DSN' env is not defined"
-      )
-      return
-    }
-
-    if (settingsStore.value.TELEMETRY_ENABLED) {
-      initSentry(import.meta.env.VITE_SENTRY_DSN, router, app)
-    }
-
-    settingsStore.subject$.subscribe(({ TELEMETRY_ENABLED }) => {
-      if (!TELEMETRY_ENABLED && sentryActive) {
-        deinitSentry()
-      } else if (TELEMETRY_ENABLED && !sentryActive) {
-        initSentry(import.meta.env.VITE_SENTRY_DSN!, router, app)
-      }
-    })
-
-    subscribeToAppEventsForReporting()
-    subscribeForAppDataTags()
-  },
-}

+ 4 - 0
packages/hoppscotch-common/src/pages/settings.vue

@@ -60,6 +60,7 @@
             <div class="space-y-4 py-4">
               <div class="flex items-center">
                 <HoppSmartToggle
+                  v-if="hasPlatformTelemetry"
                   :on="TELEMETRY_ENABLED"
                   @change="showConfirmModal"
                 >
@@ -134,6 +135,7 @@ import { InterceptorService } from "~/services/interceptor.service"
 import { pipe } from "fp-ts/function"
 import * as O from "fp-ts/Option"
 import * as A from "fp-ts/Array"
+import { platform } from "~/platform"
 
 const t = useI18n()
 const colorMode = useColorMode()
@@ -163,6 +165,8 @@ const TELEMETRY_ENABLED = useSetting("TELEMETRY_ENABLED")
 const EXPAND_NAVIGATION = useSetting("EXPAND_NAVIGATION")
 const SIDEBAR_ON_LEFT = useSetting("SIDEBAR_ON_LEFT")
 
+const hasPlatformTelemetry = Boolean(platform.platformFeatureFlags.hasTelemetry)
+
 const confirmRemove = ref(false)
 
 const proxySettings = computed(() => ({

+ 1 - 0
packages/hoppscotch-common/src/platform/index.ts

@@ -26,6 +26,7 @@ export type PlatformDef = {
   additionalInspectors?: InspectorsPlatformDef
   platformFeatureFlags: {
     exportAsGIST: boolean
+    hasTelemetry: boolean
   }
 }
 

+ 2 - 2
packages/hoppscotch-common/src/workers/regex.js

@@ -1,10 +1,10 @@
 function generateREForProtocol(protocol) {
   return [
     new RegExp(
-      `${protocol}(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])$`
+      `${protocol}(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5]).){3}([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])(:[0-9]+)?(\\/[^?#]*)?(\\?[^#]*)?(#.*)?$`
     ),
     new RegExp(
-      `${protocol}(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9/])$`
+      `${protocol}(([a-zA-Z0-9]|[a-zA-Z0-9][a-zA-Z0-9-]*[a-zA-Z0-9]).)*([A-Za-z0-9]|[A-Za-z0-9][A-Za-z0-9-]*[A-Za-z0-9/])(:[0-9]+)?(\\/[^?#]*)?(\\?[^#]*)?(#.*)?$`
     ),
   ]
 }

+ 92 - 0
packages/hoppscotch-common/type-check.mjs

@@ -0,0 +1,92 @@
+import fs from "fs"
+import { glob } from "glob"
+import path from "path"
+import ts from "typescript"
+import vueTsc from "vue-tsc"
+
+import { fileURLToPath } from "url"
+
+/**
+ * Helper function to find files to perform type check on
+ */
+const findFilesToPerformTypeCheck = (directoryPaths, filePatterns) => {
+  const files = []
+
+  directoryPaths.forEach((directoryPath) => {
+    if (!fs.existsSync(directoryPath)) {
+      console.error(`Directory not found: ${directoryPath}`)
+      process.exit(1)
+    }
+
+    files.push(
+      ...glob.sync(filePatterns, {
+        cwd: directoryPath,
+        ignore: ["**/__tests__/**", "**/*.d.ts"],
+        absolute: true,
+      })
+    )
+  })
+  return files
+}
+
+// Derive the current file's directory path `__dirname` from the URL of this module `__filename`
+const __filename = fileURLToPath(import.meta.url)
+const __dirname = path.dirname(__filename)
+
+// Define the directory paths and file patterns to perform type checks on
+const directoryPaths = [path.resolve(__dirname, "src", "services")]
+const filePatterns = ["**/*.ts"]
+
+const tsConfigFileName = path.resolve(__dirname, "tsconfig.json")
+const tsConfig = ts.readConfigFile(tsConfigFileName, ts.sys.readFile)
+const { options } = ts.parseJsonConfigFileContent(
+  tsConfig.config,
+  ts.sys,
+  __dirname
+)
+
+const files = findFilesToPerformTypeCheck(directoryPaths, filePatterns)
+
+const host = ts.createCompilerHost(options)
+const program = vueTsc.createProgram({
+  rootNames: files,
+  options: { ...options, noEmit: true },
+  host,
+})
+
+// Perform type checking
+const diagnostics = ts
+  .getPreEmitDiagnostics(program)
+  // Filter diagnostics to include only errors from files in the specified directory
+  .filter(({ file }) => {
+    if (!file) {
+      return false
+    }
+    return directoryPaths.some((directoryPath) =>
+      path.resolve(file.fileName).includes(directoryPath)
+    )
+  })
+
+if (!diagnostics.length) {
+  console.log("Type checking passed.")
+
+  // Success
+  process.exit(0)
+}
+
+console.log("TypeScript diagnostics:")
+
+const formatHost = {
+  getCanonicalFileName: (fileName) => fileName,
+  getCurrentDirectory: host.getCurrentDirectory,
+  getNewLine: () => ts.sys.newLine,
+}
+
+const formattedDiagnostics = ts.formatDiagnosticsWithColorAndContext(
+  diagnostics,
+  formatHost
+)
+console.error(formattedDiagnostics)
+
+// Failure
+process.exit(1)

+ 11 - 7
packages/hoppscotch-data/package.json

@@ -6,7 +6,9 @@
   "main": "dist/hoppscotch-data.cjs",
   "module": "dist/hoppscotch-data.js",
   "types": "./dist/index.d.ts",
-  "files": [ "dist/*" ],
+  "files": [
+    "dist/*"
+  ],
   "scripts": {
     "build:code": "vite build",
     "build:decl": "tsc --project tsconfig.decl.json",
@@ -32,14 +34,16 @@
   },
   "homepage": "https://github.com/hoppscotch/hoppscotch#readme",
   "devDependencies": {
-    "@types/lodash": "^4.14.181",
-    "typescript": "^4.6.3",
-    "vite": "^3.2.3"
+    "@types/lodash": "^4.14.200",
+    "typescript": "^5.2.2",
+    "vite": "^4.5.0"
   },
   "dependencies": {
-    "fp-ts": "^2.11.10",
-    "io-ts": "^2.2.16",
+    "fp-ts": "^2.16.1",
+    "io-ts": "^2.2.20",
     "lodash": "^4.17.21",
-    "parser-ts": "^0.6.16"
+    "parser-ts": "^0.7.0",
+    "verzod": "^0.1.1",
+    "zod": "^3.22.4"
   }
 }

+ 17 - 9
packages/hoppscotch-data/src/environment.ts → packages/hoppscotch-data/src/environment/index.ts

@@ -1,14 +1,22 @@
-import { pipe } from "fp-ts/function"
 import * as E from "fp-ts/Either"
+import { pipe } from "fp-ts/function"
+import { InferredEntity, createVersionedEntity } from "verzod"
 
-export type Environment = {
-  id?: string
-  name: string
-  variables: {
-    key: string
-    value: string
-  }[]
-}
+import V0_VERSION from "./v/0"
+
+export const Environment = createVersionedEntity({
+  latestVersion: 0,
+  versionMap: {
+    0: V0_VERSION
+  },
+  getVersion(x) {
+    return V0_VERSION.schema.safeParse(x).success
+      ? 0
+      : null
+  }
+})
+
+export type Environment = InferredEntity<typeof Environment>
 
 const REGEX_ENV_VAR = /<<([^>]*)>>/g // "<<myVariable>>"
 

Some files were not shown because too many files changed in this diff