mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-08-19 00:02:03 +00:00
refactor(editor): extract typescript extra-libs registration
Headless linting must register the same rt.d.ts resource-type namespace and custom windmill-client declarations as a mounted editor, since diagnostics depend on them. Move the apply bodies to lint/typescriptExtraLibs.ts; the editor keeps its reactive resource() wrapper around the fetch. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -43,13 +43,7 @@
|
||||
import { editorFontSize } from '$lib/editorFontSize.svelte'
|
||||
import { workspaceStore } from '$lib/stores'
|
||||
import DdlMigrationGuard from './DdlMigrationGuard.svelte'
|
||||
import {
|
||||
type Preview,
|
||||
ResourceService,
|
||||
type ScriptLang,
|
||||
UserService,
|
||||
WorkspaceService
|
||||
} from '$lib/gen'
|
||||
import { type Preview, type ScriptLang, UserService } from '$lib/gen'
|
||||
import type { Text } from 'yjs'
|
||||
import {
|
||||
initializeVscode,
|
||||
@@ -104,12 +98,16 @@
|
||||
import GlobalReviewButtons from './copilot/chat/GlobalReviewButtons.svelte'
|
||||
import AIChatInlineWidget from './copilot/chat/AIChatInlineWidget.svelte'
|
||||
import { writable } from 'svelte/store'
|
||||
import { formatResourceTypes } from './copilot/chat/script/core'
|
||||
import type { ScriptLintResult } from './copilot/chat/shared'
|
||||
import FakeMonacoPlaceHolder from './FakeMonacoPlaceHolder.svelte'
|
||||
import { editorPositionMap } from '$lib/utils'
|
||||
import { extToLang } from '$lib/editorLangUtils'
|
||||
import { computeModelPath, computeModelUri } from './lint/monacoUri'
|
||||
import {
|
||||
applyCustomWmillTypes,
|
||||
ensureResourceTypeNamespace,
|
||||
fetchCustomWmillTypesData
|
||||
} from './lint/typescriptExtraLibs'
|
||||
import { aiChatManager } from './copilot/chat/AIChatManager.svelte'
|
||||
import type { Selection } from 'monaco-editor'
|
||||
import { canHavePreprocessor, getPreprocessorModuleCode } from '$lib/script_helpers'
|
||||
@@ -1733,61 +1731,16 @@
|
||||
|
||||
let customTsTypesData = resource([() => lang], async () => {
|
||||
if (lang !== 'typescript') return undefined
|
||||
let datatables = (
|
||||
await WorkspaceService.listDataTables({ workspace: $workspaceStore ?? '' })
|
||||
).map((d) => d.name)
|
||||
let ducklakes = await WorkspaceService.listDucklakes({ workspace: $workspaceStore ?? '' })
|
||||
return { datatables, ducklakes }
|
||||
return await fetchCustomWmillTypesData($workspaceStore ?? '')
|
||||
})
|
||||
function setTypescriptCustomTypes() {
|
||||
if (!customTsTypesData.current) return
|
||||
if (lang !== 'typescript') return
|
||||
|
||||
const ducklakeNames = customTsTypesData.current.ducklakes
|
||||
const datatableNames = customTsTypesData.current.datatables
|
||||
|
||||
const ducklakeNameType = ducklakeNames.length
|
||||
? ducklakeNames.map((name) => JSON.stringify(name)).join(' | ')
|
||||
: 'string'
|
||||
const datatableNameType = datatableNames.length
|
||||
? datatableNames.map((name) => JSON.stringify(name)).join(' | ')
|
||||
: 'string'
|
||||
const isDucklakeOptional = ducklakeNames.includes('main')
|
||||
const isDataTableOptional = datatableNames.includes('main')
|
||||
|
||||
let disposeTs = typescriptDefaults.addExtraLib(
|
||||
`export {};
|
||||
declare module 'windmill-client' {
|
||||
import { type DatatableSqlTemplateFunction, type SqlTemplateFunction } from 'windmill-client';
|
||||
export function ducklake(name${isDucklakeOptional ? '?' : ''}: ${ducklakeNameType}): SqlTemplateFunction;
|
||||
export function datatable(name${isDataTableOptional ? '?' : ''}: ${datatableNameType}): DatatableSqlTemplateFunction;
|
||||
}`,
|
||||
'file:///custom_wmill_types.d.ts'
|
||||
)
|
||||
return () => {
|
||||
disposeTs.dispose()
|
||||
}
|
||||
return applyCustomWmillTypes(customTsTypesData.current)
|
||||
}
|
||||
|
||||
async function setTypescriptRTNamespace() {
|
||||
if (
|
||||
scriptLang &&
|
||||
(scriptLang === 'bun' ||
|
||||
scriptLang === 'deno' ||
|
||||
scriptLang === 'bunnative' ||
|
||||
scriptLang === 'nativets')
|
||||
) {
|
||||
const resourceTypes = await ResourceService.listResourceType({
|
||||
workspace: $workspaceStore ?? ''
|
||||
})
|
||||
|
||||
const namespace = formatResourceTypes(
|
||||
resourceTypes,
|
||||
scriptLang === 'bunnative' ? 'bun' : scriptLang
|
||||
)
|
||||
|
||||
typescriptDefaults.addExtraLib(namespace, 'rt.d.ts')
|
||||
}
|
||||
await ensureResourceTypeNamespace($workspaceStore ?? '', scriptLang)
|
||||
}
|
||||
|
||||
async function setTypescriptExtraLibs() {
|
||||
|
||||
@@ -0,0 +1,64 @@
|
||||
import { typescriptDefaults } from '@codingame/monaco-vscode-standalone-typescript-language-features'
|
||||
import { ResourceService, WorkspaceService } from '$lib/gen'
|
||||
import { formatResourceTypes } from '../copilot/chat/script/core'
|
||||
|
||||
// Extra libs that shape TypeScript diagnostics for Windmill code. They are registered
|
||||
// under fixed URIs in the global typescriptDefaults, so a headless linter and a mounted
|
||||
// editor necessarily see the same declarations — as long as both go through here.
|
||||
|
||||
const RESOURCE_TYPE_LANGS = ['bun', 'deno', 'bunnative', 'nativets'] as const
|
||||
type ResourceTypeLang = (typeof RESOURCE_TYPE_LANGS)[number]
|
||||
|
||||
export async function ensureResourceTypeNamespace(
|
||||
workspace: string,
|
||||
scriptLang: string | undefined
|
||||
): Promise<void> {
|
||||
if (!RESOURCE_TYPE_LANGS.includes(scriptLang as ResourceTypeLang)) {
|
||||
return
|
||||
}
|
||||
const lang = scriptLang as ResourceTypeLang
|
||||
const resourceTypes = await ResourceService.listResourceType({ workspace })
|
||||
const namespace = formatResourceTypes(resourceTypes, lang === 'bunnative' ? 'bun' : lang)
|
||||
typescriptDefaults.addExtraLib(namespace, 'rt.d.ts')
|
||||
}
|
||||
|
||||
export interface CustomWmillTypesData {
|
||||
datatables: string[]
|
||||
ducklakes: string[]
|
||||
}
|
||||
|
||||
export async function fetchCustomWmillTypesData(workspace: string): Promise<CustomWmillTypesData> {
|
||||
const datatables = (await WorkspaceService.listDataTables({ workspace })).map((d) => d.name)
|
||||
const ducklakes = await WorkspaceService.listDucklakes({ workspace })
|
||||
return { datatables, ducklakes }
|
||||
}
|
||||
|
||||
export function applyCustomWmillTypes(data: CustomWmillTypesData): () => void {
|
||||
const { datatables: datatableNames, ducklakes: ducklakeNames } = data
|
||||
|
||||
const ducklakeNameType = ducklakeNames.length
|
||||
? ducklakeNames.map((name) => JSON.stringify(name)).join(' | ')
|
||||
: 'string'
|
||||
const datatableNameType = datatableNames.length
|
||||
? datatableNames.map((name) => JSON.stringify(name)).join(' | ')
|
||||
: 'string'
|
||||
const isDucklakeOptional = ducklakeNames.includes('main')
|
||||
const isDataTableOptional = datatableNames.includes('main')
|
||||
|
||||
const disposeTs = typescriptDefaults.addExtraLib(
|
||||
`export {};
|
||||
declare module 'windmill-client' {
|
||||
import { type DatatableSqlTemplateFunction, type SqlTemplateFunction } from 'windmill-client';
|
||||
export function ducklake(name${isDucklakeOptional ? '?' : ''}: ${ducklakeNameType}): SqlTemplateFunction;
|
||||
export function datatable(name${isDataTableOptional ? '?' : ''}: ${datatableNameType}): DatatableSqlTemplateFunction;
|
||||
}`,
|
||||
'file:///custom_wmill_types.d.ts'
|
||||
)
|
||||
return () => {
|
||||
disposeTs.dispose()
|
||||
}
|
||||
}
|
||||
|
||||
export async function ensureCustomWmillTypes(workspace: string): Promise<() => void> {
|
||||
return applyCustomWmillTypes(await fetchCustomWmillTypesData(workspace))
|
||||
}
|
||||
Reference in New Issue
Block a user