feat: move scripting code editors to use Monaco (#5191)
Replaces CodeMirror with Monaco for scripting editors under the experimental scripting sandbox. The legacy CodeMirror-based editors are preserved for backwards compatibility and will continue to power the legacy scripting sandbox. This introduces improved type support, IntelliSense, and JSDoc hinting via Monaco, with the backing for pre-request and post-request scripts in tabbed views. Type definitions are isolated per editor to avoid variable leakage.
This commit is contained in:
parent
cfa2caa1db
commit
40aca4d35b
11 changed files with 416 additions and 58 deletions
|
|
@ -34,6 +34,7 @@
|
|||
"@codemirror/search": "6.5.6",
|
||||
"@codemirror/state": "6.4.1",
|
||||
"@codemirror/view": "6.25.1",
|
||||
"@guolao/vue-monaco-editor": "1.5.5",
|
||||
"@hoppscotch/codemirror-lang-graphql": "workspace:^",
|
||||
"@hoppscotch/data": "workspace:^",
|
||||
"@hoppscotch/httpsnippet": "3.0.9",
|
||||
|
|
@ -79,6 +80,7 @@
|
|||
"lossless-json": "4.0.2",
|
||||
"markdown-it": "14.1.0",
|
||||
"minisearch": "7.1.0",
|
||||
"monaco-editor": "0.52.2",
|
||||
"nprogress": "0.2.0",
|
||||
"paho-mqtt": "1.1.0",
|
||||
"path": "0.12.7",
|
||||
|
|
|
|||
196
packages/hoppscotch-common/src/components/MonacoScriptEditor.vue
Normal file
196
packages/hoppscotch-common/src/components/MonacoScriptEditor.vue
Normal file
|
|
@ -0,0 +1,196 @@
|
|||
<template>
|
||||
<vue-monaco-editor
|
||||
v-model:value="value"
|
||||
:theme="monacoEditorTheme"
|
||||
language="typescript"
|
||||
:options="MONACO_EDITOR_OPTIONS"
|
||||
:model="editorModel"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import { VueMonacoEditor } from "@guolao/vue-monaco-editor"
|
||||
import { watchDebounced } from "@vueuse/core"
|
||||
import * as monaco from "monaco-editor"
|
||||
import { v4 as uuidv4 } from "uuid"
|
||||
import { computed, onMounted, ref } from "vue"
|
||||
|
||||
import { useColorMode } from "~/composables/theming"
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
modelValue: string
|
||||
type: "pre-request" | "post-request"
|
||||
}>(),
|
||||
{
|
||||
modelValue: "",
|
||||
}
|
||||
)
|
||||
|
||||
const theme = useColorMode()
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "update:modelValue", value: string): void
|
||||
}>()
|
||||
|
||||
const editorModel = ref<monaco.editor.ITextModel | null>(null)
|
||||
|
||||
const MONACO_EDITOR_OPTIONS: Readonly<monaco.editor.IStandaloneEditorConstructionOptions> =
|
||||
{
|
||||
automaticLayout: true,
|
||||
formatOnType: true,
|
||||
formatOnPaste: true,
|
||||
}
|
||||
|
||||
// Static imports: import X from "URL"
|
||||
const staticImportRegex =
|
||||
/import\s+(?:[\w*\s{},]+?\s+from\s+)?["']([^"']+)["']/g
|
||||
|
||||
// Dynamic imports: import("URL")
|
||||
const dynamicImportRegex = /import\(\s*["']([^"']+)["']\s*\)/g
|
||||
|
||||
const typeDefCache = new Map<string, string>()
|
||||
|
||||
const extraLibRefs = new Map<string, monaco.IDisposable>()
|
||||
|
||||
const MODULE_PREFIX = "export {};\n" as const
|
||||
|
||||
const ensureCompilerOptions = (() => {
|
||||
let applied = false
|
||||
|
||||
return () => {
|
||||
if (applied) {
|
||||
return
|
||||
}
|
||||
|
||||
monaco.languages.typescript.typescriptDefaults.setCompilerOptions({
|
||||
allowJs: true,
|
||||
checkJs: true,
|
||||
allowSyntheticDefaultImports: true,
|
||||
esModuleInterop: true,
|
||||
moduleResolution: monaco.languages.typescript.ModuleResolutionKind.NodeJs,
|
||||
module: monaco.languages.typescript.ModuleKind.ESNext,
|
||||
noEmit: true,
|
||||
target: monaco.languages.typescript.ScriptTarget.ES2020,
|
||||
allowNonTsExtensions: true,
|
||||
})
|
||||
|
||||
monaco.languages.typescript.typescriptDefaults.setDiagnosticsOptions({
|
||||
noSemanticValidation: false,
|
||||
noSyntaxValidation: false,
|
||||
})
|
||||
|
||||
// Disable Cmd/Ctrl+Enter key binding
|
||||
monaco.editor.addKeybindingRule({
|
||||
keybinding: monaco.KeyMod.CtrlCmd | monaco.KeyCode.Enter,
|
||||
command: null,
|
||||
})
|
||||
|
||||
applied = true
|
||||
}
|
||||
})()
|
||||
|
||||
onMounted(() => {
|
||||
ensureCompilerOptions()
|
||||
|
||||
const uuid = uuidv4()
|
||||
const scriptFileURI = monaco.Uri.parse(
|
||||
`inmemory://model/${uuid}.${props.type}.ts`
|
||||
)
|
||||
|
||||
// Add `export {}` to make it a module and isolate scope
|
||||
const initialValue = value.value
|
||||
? `${MODULE_PREFIX}${value.value}`
|
||||
: MODULE_PREFIX
|
||||
|
||||
editorModel.value = monaco.editor.createModel(
|
||||
initialValue,
|
||||
"typescript",
|
||||
scriptFileURI
|
||||
)
|
||||
})
|
||||
|
||||
const value = computed({
|
||||
get: () => {
|
||||
const modelValue = props.modelValue
|
||||
return modelValue.startsWith(MODULE_PREFIX)
|
||||
? modelValue.slice(MODULE_PREFIX.length) // Remove the prefix for display
|
||||
: modelValue
|
||||
},
|
||||
set: (newValue) => {
|
||||
// Always ensure the export prefix exists
|
||||
const finalValue = newValue.startsWith(MODULE_PREFIX.trim())
|
||||
? newValue
|
||||
: `${MODULE_PREFIX}${newValue}`
|
||||
emit("update:modelValue", finalValue)
|
||||
},
|
||||
})
|
||||
|
||||
const resolveAndAddDTS = async (url: string) => {
|
||||
if (
|
||||
typeDefCache.has(url) ||
|
||||
url.includes("?no-dts") ||
|
||||
!url.includes("esm.sh")
|
||||
) {
|
||||
return
|
||||
}
|
||||
|
||||
const headResp = await fetch(url, { method: "HEAD" }).catch(() => null)
|
||||
const typesHeader = headResp?.headers.get("X-TypeScript-Types")
|
||||
const dtsURL = typesHeader ? new URL(typesHeader, url).href : `${url}.d.ts`
|
||||
|
||||
const dtsResp = await fetch(dtsURL).catch(() => null)
|
||||
if (!dtsResp?.ok) {
|
||||
return
|
||||
}
|
||||
|
||||
let dtsText = await dtsResp.text()
|
||||
|
||||
if (!/declare\s+module\s+["']/.test(dtsText)) {
|
||||
dtsText = `declare module "${url}" {\n${dtsText}\n}`
|
||||
}
|
||||
|
||||
typeDefCache.set(url, dtsURL)
|
||||
|
||||
const libUri = `inmemory://lib/${encodeURIComponent(url)}.d.ts`
|
||||
const disposable = monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
||||
dtsText,
|
||||
libUri
|
||||
)
|
||||
|
||||
// Clean up old one if already tracked
|
||||
extraLibRefs.get(url)?.dispose()
|
||||
extraLibRefs.set(url, disposable)
|
||||
}
|
||||
|
||||
// Dispose libs no longer used
|
||||
const updateExtraLibs = (newValue: string) => {
|
||||
const found = new Set<string>()
|
||||
|
||||
const staticMatches = newValue.matchAll(staticImportRegex)
|
||||
const dynamicMatches = newValue.matchAll(dynamicImportRegex)
|
||||
|
||||
for (const match of staticMatches) found.add(match[1])
|
||||
for (const match of dynamicMatches) found.add(match[1])
|
||||
|
||||
// Remove stale imports
|
||||
for (const oldUrl of extraLibRefs.keys()) {
|
||||
if (!found.has(oldUrl)) {
|
||||
extraLibRefs.get(oldUrl)?.dispose()
|
||||
extraLibRefs.delete(oldUrl)
|
||||
}
|
||||
}
|
||||
|
||||
// Resolve new ones
|
||||
found.forEach(resolveAndAddDTS)
|
||||
}
|
||||
|
||||
watchDebounced(() => props.modelValue, updateExtraLibs, {
|
||||
debounce: 500,
|
||||
immediate: true,
|
||||
})
|
||||
|
||||
const monacoEditorTheme = computed(() =>
|
||||
["dark", "black"].includes(theme.value) ? "vs-dark" : "vs"
|
||||
)
|
||||
</script>
|
||||
|
|
@ -38,7 +38,18 @@
|
|||
</div>
|
||||
<div class="flex flex-1 border-b border-dividerLight">
|
||||
<div class="w-2/3 border-r border-dividerLight h-full relative">
|
||||
<div ref="preRequestEditor" class="h-full absolute inset-0"></div>
|
||||
<MonacoScriptEditor
|
||||
v-if="EXPERIMENTAL_SCRIPTING_SANDBOX && props.isActive"
|
||||
v-model="preRequestScript"
|
||||
:is-active="props.isActive"
|
||||
type="pre-request"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-else
|
||||
ref="preRequestEditor"
|
||||
class="h-full absolute inset-0"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
class="z-[9] sticky top-upperTertiaryStickyFold h-full min-w-[12rem] max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4"
|
||||
|
|
@ -76,31 +87,33 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||
import IconWrapText from "~icons/lucide/wrap-text"
|
||||
import IconTrash2 from "~icons/lucide/trash-2"
|
||||
import IconSparkles from "~icons/lucide/sparkles"
|
||||
import { reactive, ref, computed } from "vue"
|
||||
import snippets from "@helpers/preRequestScriptSnippets"
|
||||
import { useCodemirror } from "@composables/codemirror"
|
||||
import linter from "~/helpers/editor/linting/preRequest"
|
||||
import completer from "~/helpers/editor/completion/preRequest"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { useVModel } from "@vueuse/core"
|
||||
import { useNestedSetting } from "~/composables/settings"
|
||||
import { toggleNestedSetting } from "~/newstore/settings"
|
||||
import { useAIExperiments } from "~/composables/ai-experiments"
|
||||
import { useService } from "dioc/vue"
|
||||
import { RESTTabService } from "~/services/tab/rest"
|
||||
import { platform } from "~/platform"
|
||||
import { useReadonlyStream } from "~/composables/stream"
|
||||
import AiexperimentsModifyPreRequestModal from "@components/aiexperiments/ModifyPreRequestModal.vue"
|
||||
import { useCodemirror } from "@composables/codemirror"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import snippets from "@helpers/preRequestScriptSnippets"
|
||||
import { useVModel } from "@vueuse/core"
|
||||
import { useService } from "dioc/vue"
|
||||
import { computed, reactive, ref } from "vue"
|
||||
|
||||
import { useAIExperiments } from "~/composables/ai-experiments"
|
||||
import { useNestedSetting, useSetting } from "~/composables/settings"
|
||||
import { useReadonlyStream } from "~/composables/stream"
|
||||
import { invokeAction } from "~/helpers/actions"
|
||||
import completer from "~/helpers/editor/completion/preRequest"
|
||||
import linter from "~/helpers/editor/linting/preRequest"
|
||||
import { toggleNestedSetting } from "~/newstore/settings"
|
||||
import { platform } from "~/platform"
|
||||
import { RESTTabService } from "~/services/tab/rest"
|
||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||
import IconSparkles from "~icons/lucide/sparkles"
|
||||
import IconTrash2 from "~icons/lucide/trash-2"
|
||||
import IconWrapText from "~icons/lucide/wrap-text"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string
|
||||
isActive?: boolean
|
||||
}>()
|
||||
const emit = defineEmits<{
|
||||
(e: "update:modelValue", value: string): void
|
||||
|
|
@ -127,6 +140,10 @@ useCodemirror(
|
|||
})
|
||||
)
|
||||
|
||||
const EXPERIMENTAL_SCRIPTING_SANDBOX = useSetting(
|
||||
"EXPERIMENTAL_SCRIPTING_SANDBOX"
|
||||
)
|
||||
|
||||
const useSnippet = (script: string) => {
|
||||
preRequestScript.value += script
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,6 +64,7 @@
|
|||
<HttpPreRequestScript
|
||||
v-if="'preRequestScript' in request"
|
||||
v-model="request.preRequestScript"
|
||||
:is-active="selectedOptionTab === 'preRequestScript'"
|
||||
/>
|
||||
</HoppSmartTab>
|
||||
<HoppSmartTab
|
||||
|
|
@ -78,7 +79,11 @@
|
|||
: false
|
||||
"
|
||||
>
|
||||
<HttpTests v-if="'testScript' in request" v-model="request.testScript" />
|
||||
<HttpTests
|
||||
v-if="'testScript' in request"
|
||||
v-model="request.testScript"
|
||||
:is-active="selectedOptionTab === 'tests'"
|
||||
/>
|
||||
</HoppSmartTab>
|
||||
<HoppSmartTab
|
||||
v-if="properties?.includes('requestVariables') ?? true"
|
||||
|
|
@ -99,11 +104,16 @@ import {
|
|||
HoppRESTResponseOriginalRequest,
|
||||
} from "@hoppscotch/data"
|
||||
import { useVModel } from "@vueuse/core"
|
||||
import { computed } from "vue"
|
||||
import * as monaco from "monaco-editor"
|
||||
import { computed, onUnmounted, watch } from "vue"
|
||||
|
||||
import { defineActionHandler } from "~/helpers/actions"
|
||||
import { HoppInheritedProperty } from "~/helpers/types/HoppInheritedProperties"
|
||||
import { AggregateEnvironment } from "~/newstore/environments"
|
||||
|
||||
import postRequestPWModDefn from "~/types/post-request.d.ts?raw"
|
||||
import preRequestPWModDefn from "~/types/pre-request.d.ts?raw"
|
||||
|
||||
const VALID_OPTION_TABS = [
|
||||
"params",
|
||||
"bodyParams",
|
||||
|
|
@ -140,6 +150,36 @@ const emit = defineEmits<{
|
|||
const request = useVModel(props, "modelValue", emit)
|
||||
const selectedOptionTab = useVModel(props, "optionTab", emit)
|
||||
|
||||
let extraLibRef: monaco.IDisposable | null = null
|
||||
|
||||
const libDefs = {
|
||||
"pre-request": preRequestPWModDefn,
|
||||
"post-request": postRequestPWModDefn,
|
||||
}
|
||||
|
||||
const scriptEditorTabs = ["preRequestScript", "tests"]
|
||||
|
||||
onUnmounted(() => extraLibRef?.dispose())
|
||||
|
||||
watch(
|
||||
() => selectedOptionTab.value,
|
||||
(newTab) => {
|
||||
if (!scriptEditorTabs.includes(newTab)) {
|
||||
return
|
||||
}
|
||||
|
||||
extraLibRef?.dispose()
|
||||
|
||||
monaco.languages.typescript.typescriptDefaults.setExtraLibs([])
|
||||
|
||||
extraLibRef = monaco.languages.typescript.typescriptDefaults.addExtraLib(
|
||||
libDefs[newTab === "preRequestScript" ? "pre-request" : "post-request"],
|
||||
`inmemory://lib/pw-${newTab}.d.ts`
|
||||
)
|
||||
},
|
||||
{ immediate: true }
|
||||
)
|
||||
|
||||
const showPreRequestScriptTab = computed(() => {
|
||||
return (
|
||||
props.properties?.includes("preRequestScript") ??
|
||||
|
|
|
|||
|
|
@ -38,7 +38,18 @@
|
|||
</div>
|
||||
<div class="flex flex-1 border-b border-dividerLight">
|
||||
<div class="w-2/3 border-r border-dividerLight h-full relative">
|
||||
<div ref="testScriptEditor" class="h-full absolute inset-0"></div>
|
||||
<MonacoScriptEditor
|
||||
v-if="EXPERIMENTAL_SCRIPTING_SANDBOX && props.isActive"
|
||||
v-model="testScript"
|
||||
:is-active="props.isActive"
|
||||
type="post-request"
|
||||
/>
|
||||
|
||||
<div
|
||||
v-else
|
||||
ref="testScriptEditor"
|
||||
class="h-full absolute inset-0"
|
||||
></div>
|
||||
</div>
|
||||
<div
|
||||
class="z-[9] sticky top-upperTertiaryStickyFold h-full min-w-[12rem] max-w-1/3 flex-shrink-0 overflow-auto overflow-x-auto bg-primary p-4"
|
||||
|
|
@ -76,31 +87,32 @@
|
|||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||
import IconWrapText from "~icons/lucide/wrap-text"
|
||||
import IconTrash2 from "~icons/lucide/trash-2"
|
||||
import IconSparkles from "~icons/lucide/sparkles"
|
||||
import { reactive, ref, computed } from "vue"
|
||||
import testSnippets from "~/helpers/testSnippets"
|
||||
import AiexperimentsModifyTestScriptModal from "@components/aiexperiments/ModifyTestScriptModal.vue"
|
||||
import { useCodemirror } from "@composables/codemirror"
|
||||
import linter from "~/helpers/editor/linting/testScript"
|
||||
import completer from "~/helpers/editor/completion/testScript"
|
||||
import { useI18n } from "@composables/i18n"
|
||||
import { useVModel } from "@vueuse/core"
|
||||
import { useNestedSetting } from "~/composables/settings"
|
||||
import { toggleNestedSetting } from "~/newstore/settings"
|
||||
import { useAIExperiments } from "~/composables/ai-experiments"
|
||||
import { useService } from "dioc/vue"
|
||||
import { RESTTabService } from "~/services/tab/rest"
|
||||
import { platform } from "~/platform"
|
||||
import { computed, reactive, ref } from "vue"
|
||||
import { useAIExperiments } from "~/composables/ai-experiments"
|
||||
import { useNestedSetting, useSetting } from "~/composables/settings"
|
||||
import { useReadonlyStream } from "~/composables/stream"
|
||||
import AiexperimentsModifyTestScriptModal from "@components/aiexperiments/ModifyTestScriptModal.vue"
|
||||
import { invokeAction } from "~/helpers/actions"
|
||||
import completer from "~/helpers/editor/completion/testScript"
|
||||
import linter from "~/helpers/editor/linting/testScript"
|
||||
import testSnippets from "~/helpers/testSnippets"
|
||||
import { toggleNestedSetting } from "~/newstore/settings"
|
||||
import { platform } from "~/platform"
|
||||
import { RESTTabService } from "~/services/tab/rest"
|
||||
import IconHelpCircle from "~icons/lucide/help-circle"
|
||||
import IconSparkles from "~icons/lucide/sparkles"
|
||||
import IconTrash2 from "~icons/lucide/trash-2"
|
||||
import IconWrapText from "~icons/lucide/wrap-text"
|
||||
|
||||
const t = useI18n()
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: string
|
||||
isActive?: boolean
|
||||
}>()
|
||||
const emit = defineEmits(["update:modelValue"])
|
||||
const testScript = useVModel(props, "modelValue", emit)
|
||||
|
|
@ -123,6 +135,10 @@ useCodemirror(
|
|||
})
|
||||
)
|
||||
|
||||
const EXPERIMENTAL_SCRIPTING_SANDBOX = useSetting(
|
||||
"EXPERIMENTAL_SCRIPTING_SANDBOX"
|
||||
)
|
||||
|
||||
const useSnippet = (script: string) => {
|
||||
testScript.value += script
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,12 +1,18 @@
|
|||
import { getKernelMode, initKernel } from "@hoppscotch/kernel"
|
||||
import { HOPP_MODULES } from "@modules/."
|
||||
import { createApp } from "vue"
|
||||
import { PlatformDef, setPlatformDef } from "./platform"
|
||||
import { initKernel, getKernelMode } from "@hoppscotch/kernel"
|
||||
|
||||
import { loader } from "@guolao/vue-monaco-editor"
|
||||
import * as monaco from "monaco-editor"
|
||||
import editorWorker from "monaco-editor/esm/vs/editor/editor.worker?worker"
|
||||
import tsWorker from "monaco-editor/esm/vs/language/typescript/ts.worker?worker"
|
||||
|
||||
import { PlatformDef, setPlatformDef } from "./platform"
|
||||
|
||||
import "nprogress/nprogress.css"
|
||||
import "../assets/scss/styles.scss"
|
||||
import "../assets/scss/tailwind.scss"
|
||||
import "../assets/themes/themes.scss"
|
||||
import "../assets/scss/styles.scss"
|
||||
import "nprogress/nprogress.css"
|
||||
|
||||
import "unfonts.css"
|
||||
|
||||
|
|
@ -36,6 +42,18 @@ export async function createHoppApp(
|
|||
)
|
||||
}
|
||||
|
||||
self.MonacoEnvironment = {
|
||||
getWorker(_, label) {
|
||||
if (label === "typescript") {
|
||||
return new tsWorker()
|
||||
}
|
||||
|
||||
return new editorWorker()
|
||||
},
|
||||
}
|
||||
|
||||
loader.config({ monaco })
|
||||
|
||||
HOPP_MODULES.forEach((mod) => mod.onVueAppInit?.(app))
|
||||
platformDef.addedHoppModules?.forEach((mod) => mod.onVueAppInit?.(app))
|
||||
|
||||
|
|
|
|||
35
packages/hoppscotch-common/src/types/post-request.d.ts
vendored
Normal file
35
packages/hoppscotch-common/src/types/post-request.d.ts
vendored
Normal file
|
|
@ -0,0 +1,35 @@
|
|||
declare namespace pw {
|
||||
function test(name: string, func: () => void): void
|
||||
function expect(value: any): Expectation
|
||||
|
||||
const response: {
|
||||
status: number
|
||||
headers: any
|
||||
body: any
|
||||
}
|
||||
|
||||
namespace env {
|
||||
function set(key: string, value: string): void
|
||||
function unset(key: string): void
|
||||
function get(key: string): string
|
||||
function getResolve(key: string): string
|
||||
function resolve(value: string): string
|
||||
}
|
||||
}
|
||||
|
||||
interface Expectation extends ExpectationMethods {
|
||||
not: BaseExpectation
|
||||
}
|
||||
|
||||
interface BaseExpectation extends ExpectationMethods {}
|
||||
|
||||
interface ExpectationMethods {
|
||||
toBe(value: any): void
|
||||
toBeLevel2xx(): void
|
||||
toBeLevel3xx(): void
|
||||
toBeLevel4xx(): void
|
||||
toBeLevel5xx(): void
|
||||
toBeType(type: string): void
|
||||
toHaveLength(length: number): void
|
||||
toInclude(value: any): void
|
||||
}
|
||||
9
packages/hoppscotch-common/src/types/pre-request.d.ts
vendored
Normal file
9
packages/hoppscotch-common/src/types/pre-request.d.ts
vendored
Normal file
|
|
@ -0,0 +1,9 @@
|
|||
declare const pw: {
|
||||
env: {
|
||||
get(key: string): string
|
||||
set(key: string, value: string): void
|
||||
unset(key: string): void
|
||||
getResolve(key: string): string
|
||||
resolve(value: string): string
|
||||
}
|
||||
}
|
||||
|
|
@ -7,7 +7,7 @@
|
|||
"dev:vite": "vite",
|
||||
"dev:gql-codegen": "graphql-codegen --require dotenv/config --config gql-codegen.yml dotenv_config_path=\"../../.env\" --watch",
|
||||
"dev": "pnpm exec npm-run-all -p -l dev:*",
|
||||
"build": "node --max_old_space_size=4096 ./node_modules/vite/bin/vite.js build",
|
||||
"build": "node --max_old_space_size=8192 ./node_modules/vite/bin/vite.js build",
|
||||
"preview": "vite preview",
|
||||
"lint": "eslint src --ext .ts,.js,.vue --ignore-path .gitignore .",
|
||||
"lint:ts": "vue-tsc --noEmit",
|
||||
|
|
|
|||
|
|
@ -214,7 +214,7 @@ export default defineConfig({
|
|||
registerType: "prompt",
|
||||
workbox: {
|
||||
cleanupOutdatedCaches: true,
|
||||
maximumFileSizeToCacheInBytes: 10485760,
|
||||
maximumFileSizeToCacheInBytes: 15728640, // 15 MB,
|
||||
navigateFallbackDenylist: [
|
||||
/robots.txt/,
|
||||
/sitemap.xml/,
|
||||
|
|
|
|||
|
|
@ -509,6 +509,9 @@ importers:
|
|||
'@codemirror/view':
|
||||
specifier: 6.25.1
|
||||
version: 6.25.1
|
||||
'@guolao/vue-monaco-editor':
|
||||
specifier: 1.5.5
|
||||
version: 1.5.5(monaco-editor@0.52.2)(vue@3.5.12(typescript@5.8.3))
|
||||
'@hoppscotch/codemirror-lang-graphql':
|
||||
specifier: workspace:^
|
||||
version: link:../codemirror-lang-graphql
|
||||
|
|
@ -644,6 +647,9 @@ importers:
|
|||
minisearch:
|
||||
specifier: 7.1.0
|
||||
version: 7.1.0
|
||||
monaco-editor:
|
||||
specifier: 0.52.2
|
||||
version: 0.52.2
|
||||
nprogress:
|
||||
specifier: 0.2.0
|
||||
version: 0.2.0
|
||||
|
|
@ -4575,6 +4581,16 @@ packages:
|
|||
peerDependencies:
|
||||
graphql: ^0.8.0 || ^0.9.0 || ^0.10.0 || ^0.11.0 || ^0.12.0 || ^0.13.0 || ^14.0.0 || ^15.0.0 || ^16.0.0 || ^17.0.0
|
||||
|
||||
'@guolao/vue-monaco-editor@1.5.5':
|
||||
resolution: {integrity: sha512-NFGImQ8dBYj6ehIxy1DngPRkctB9b6GbxvCm6aXZztNsgm/TtM4u+YM9ZwZHQPlXt7a4IODXoKCcTYEVycBSyA==}
|
||||
peerDependencies:
|
||||
'@vue/composition-api': ^1.7.1
|
||||
monaco-editor: '>=0.43.0'
|
||||
vue: 3.5.12
|
||||
peerDependenciesMeta:
|
||||
'@vue/composition-api':
|
||||
optional: true
|
||||
|
||||
'@hapi/b64@5.0.0':
|
||||
resolution: {integrity: sha512-ngu0tSEmrezoiIaNGG6rRvKOUkUuDdf4XTPnONHGYfSGRmDqPZX5oJL6HAdKTo1UQHECbdB4OzhWrfgVppjHUw==}
|
||||
|
||||
|
|
@ -5071,6 +5087,9 @@ packages:
|
|||
'@microsoft/tsdoc@0.15.1':
|
||||
resolution: {integrity: sha512-4aErSrCR/On/e5G2hDP0wjooqDdauzEbIq8hIkIe5pXV0rtWJZvdCEKL0ykZxex+IxIwBp0eGeV48hQN07dXtw==}
|
||||
|
||||
'@monaco-editor/loader@1.5.0':
|
||||
resolution: {integrity: sha512-hKoGSM+7aAc7eRTRjpqAZucPmoNOC4UUbknb/VNoTkEIkCPhqV8LfbsgM1webRM7S/z21eHEx9Fkwx8Z/C/+Xw==}
|
||||
|
||||
'@nestjs-modules/mailer@2.0.2':
|
||||
resolution: {integrity: sha512-+z4mADQasg0H1ZaGu4zZTuKv2pu+XdErqx99PLFPzCDNTN/q9U59WPgkxVaHnsvKHNopLj5Xap7G4ZpptduoYw==}
|
||||
peerDependencies:
|
||||
|
|
@ -10959,6 +10978,9 @@ packages:
|
|||
engines: {node: '>= 12.0.0'}
|
||||
hasBin: true
|
||||
|
||||
monaco-editor@0.52.2:
|
||||
resolution: {integrity: sha512-GEQWEZmfkOGLdd3XK8ryrfWz3AIP8YymVXiPHEdewrUq7mh0qrKrfHLNCXcbB6sTnMLnOZ3ztSiKcciFUkIJwQ==}
|
||||
|
||||
mrmime@2.0.0:
|
||||
resolution: {integrity: sha512-eu38+hdgojoyq63s+yTpN4XMBdt5l8HhMhc4VKLO9KM5caLIBvUm4thi7fFaxyTmCKeNnXZ5pAlBwCUnhA09uw==}
|
||||
engines: {node: '>=10'}
|
||||
|
|
@ -12655,6 +12677,9 @@ packages:
|
|||
standard-as-callback@2.1.0:
|
||||
resolution: {integrity: sha512-qoRRSyROncaz1z0mvYqIE4lCd9p2R90i6GxW3uZv5ucSu8tU7B5HXUP1gG8pVZsYNVaXjk8ClXHPttLyxAL48A==}
|
||||
|
||||
state-local@1.0.7:
|
||||
resolution: {integrity: sha512-HTEHMNieakEnoe33shBYcZ7NX83ACUjCu8c40iOGEZsngj9zRnkqS9j1pqQPXwobB0ZcVTk27REb7COQ0UR59w==}
|
||||
|
||||
statuses@2.0.1:
|
||||
resolution: {integrity: sha512-RwNA9Z/7PrK06rYLIzFMlaF+l73iwpzsqRIFgbMLbTcLD6cOao82TaWefPXQvB2fOC4AjuYSEndS7N/mTCbkdQ==}
|
||||
engines: {node: '>= 0.8'}
|
||||
|
|
@ -13998,17 +14023,6 @@ packages:
|
|||
'@vue/composition-api':
|
||||
optional: true
|
||||
|
||||
vue-demi@0.14.7:
|
||||
resolution: {integrity: sha512-EOG8KXDQNwkJILkx/gPcoL/7vH+hORoBaKgGe+6W7VFMvCYJfmF2dGbvgDroVnI8LU7/kTu8mbjRZGBU1z9NTA==}
|
||||
engines: {node: '>=12'}
|
||||
hasBin: true
|
||||
peerDependencies:
|
||||
'@vue/composition-api': ^1.0.0-rc.1
|
||||
vue: 3.5.12
|
||||
peerDependenciesMeta:
|
||||
'@vue/composition-api':
|
||||
optional: true
|
||||
|
||||
vue-eslint-parser@9.4.3:
|
||||
resolution: {integrity: sha512-2rYRLWlIpaiN8xbPiDyXZXRgLGOtWxERV7ND5fFAv5qo1D2N9Fu9MNajBNc6o13lZ+24DAWCkQCvj4klgmcITg==}
|
||||
engines: {node: ^14.17.0 || >=16.0.0}
|
||||
|
|
@ -18500,6 +18514,13 @@ snapshots:
|
|||
dependencies:
|
||||
graphql: 16.9.0
|
||||
|
||||
'@guolao/vue-monaco-editor@1.5.5(monaco-editor@0.52.2)(vue@3.5.12(typescript@5.8.3))':
|
||||
dependencies:
|
||||
'@monaco-editor/loader': 1.5.0
|
||||
monaco-editor: 0.52.2
|
||||
vue: 3.5.12(typescript@5.8.3)
|
||||
vue-demi: 0.14.10(vue@3.5.12(typescript@5.8.3))
|
||||
|
||||
'@hapi/b64@5.0.0':
|
||||
dependencies:
|
||||
'@hapi/hoek': 9.3.0
|
||||
|
|
@ -19324,6 +19345,10 @@ snapshots:
|
|||
|
||||
'@microsoft/tsdoc@0.15.1': {}
|
||||
|
||||
'@monaco-editor/loader@1.5.0':
|
||||
dependencies:
|
||||
state-local: 1.0.7
|
||||
|
||||
'@nestjs-modules/mailer@2.0.2(@nestjs/common@11.1.1(class-transformer@0.5.1)(class-validator@0.14.2)(reflect-metadata@0.2.2)(rxjs@7.8.2))(@nestjs/core@11.1.1)(nodemailer@7.0.3)(relateurl@0.2.7)(svgo@3.3.2)(terser@5.39.2)(typescript@5.8.3)':
|
||||
dependencies:
|
||||
'@css-inline/css-inline': 0.14.1
|
||||
|
|
@ -21420,7 +21445,7 @@ snapshots:
|
|||
|
||||
'@vueuse/shared@8.9.4(vue@3.5.12(typescript@5.8.3))':
|
||||
dependencies:
|
||||
vue-demi: 0.14.7(vue@3.5.12(typescript@5.8.3))
|
||||
vue-demi: 0.14.10(vue@3.5.12(typescript@5.8.3))
|
||||
optionalDependencies:
|
||||
vue: 3.5.12(typescript@5.8.3)
|
||||
|
||||
|
|
@ -26942,6 +26967,8 @@ snapshots:
|
|||
yargs-parser: 20.2.4
|
||||
yargs-unparser: 2.0.0
|
||||
|
||||
monaco-editor@0.52.2: {}
|
||||
|
||||
mrmime@2.0.0: {}
|
||||
|
||||
ms@2.0.0: {}
|
||||
|
|
@ -28844,6 +28871,8 @@ snapshots:
|
|||
standard-as-callback@2.1.0:
|
||||
optional: true
|
||||
|
||||
state-local@1.0.7: {}
|
||||
|
||||
statuses@2.0.1: {}
|
||||
|
||||
std-env@3.7.0: {}
|
||||
|
|
@ -30630,10 +30659,6 @@ snapshots:
|
|||
dependencies:
|
||||
vue: 3.5.12(typescript@5.8.3)
|
||||
|
||||
vue-demi@0.14.7(vue@3.5.12(typescript@5.8.3)):
|
||||
dependencies:
|
||||
vue: 3.5.12(typescript@5.8.3)
|
||||
|
||||
vue-eslint-parser@9.4.3(eslint@8.47.0):
|
||||
dependencies:
|
||||
debug: 4.4.1
|
||||
|
|
|
|||
Loading…
Reference in a new issue