mirror of
https://github.com/windmill-labs/windmill.git
synced 2026-09-11 08:07:15 +00:00
* feat: give dbt its own editor with an explicitly refreshed model graph Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: bump ee ref for the agent-worker dbt editor graph Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: scope editor graph retention by principal, carry parse context, honor nlang Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: bump ee ref Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep the dbt editor's model graph and log panel mounted across tabs Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: keep the dbt_edge to dbt_node joins on an index-usable equality Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: poll a parse until the job ends, resolve the project key, correct the docs Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: surface a slow parse's job, bound poll failures, drop banned bindable defaults Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: hide the dbt Generated UI content, not only its tab Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: honor disabled Triggers in the dbt tab fallback, record permissioned_as Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: one dbt pane with the run drawn on the models, and a full-height script graph Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: move the dbt build arguments behind the Build button Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: trim the dbt editor toolbar and stop the graph asserting a cause it lacks Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: mark dbt as alpha in the language picker and announce it once Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: trim the dbt alpha notice Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * feat: give a selected dbt model the whole detail section, with a close that deselects Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: close the dbt detail panel by clicking away, and make its close obvious Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: cache the agent-worker dbt query, which needs the private feature to compile Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: never fall back to a settings tab the embedder disabled Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix: preview dbt rows from the same project the graph was parsed from * feat: hide the script-kind selector for dbt projects * fix: pin a dbt row preview to the project its graph was parsed from * fix: pin a dbt row preview to the arguments its graph was parsed under * fix: keep dbt preview placeholders live while its vars stay pinned * fix: report a warehouse-less dbt parse's counts and flag stale preview args * fix: tell the pinned-vars case apart from a stale placeholder * chore: update ee-repo-ref to 59044635769f18f8ff5073236cfc7b5f41e917cc This commit updates the EE repository reference after PR #707 was merged in windmill-ee-private. Previous ee-repo-ref: 7e424384cdd4cef8653b55b04f17ad3f801bc50c New ee-repo-ref: 59044635769f18f8ff5073236cfc7b5f41e917cc Automated by sync-ee-ref workflow. --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com> Co-authored-by: windmill-internal-app[bot] <windmill-internal-app[bot]@users.noreply.github.com>
73 lines
3.2 KiB
TypeScript
73 lines
3.2 KiB
TypeScript
import { describe, expect, it } from 'vitest'
|
||
import type { ScriptModule } from '$lib/gen'
|
||
import { dbtModelSelector, dbtModulePath, dbtProjectFileKey } from './projectFiles'
|
||
|
||
const mod = (content: string): ScriptModule => ({ content, language: 'dbt' as any })
|
||
|
||
const PROJECT = `name: jaffle
|
||
model-paths: ["models"]
|
||
`
|
||
|
||
describe('dbtModulePath', () => {
|
||
// The worker resolves `.` and `//` away when it materialises the bundle, so a
|
||
// redundant spelling is a second key for one file on disk and walks straight
|
||
// past a check that compares the typed string.
|
||
it('canonicalises before the reserved-name and duplicate checks', () => {
|
||
expect(dbtModulePath('./models//x.sql', {})).toEqual({ path: 'models/x.sql' })
|
||
expect(dbtModulePath('./wm_dbt.yaml', {})).toEqual({
|
||
error: expect.stringContaining('is the descriptor')
|
||
})
|
||
const bundle = { './models/x.sql': mod('select 1') }
|
||
expect(dbtModulePath('models/x.sql', bundle)).toEqual({
|
||
error: expect.stringContaining('./models/x.sql already exists')
|
||
})
|
||
})
|
||
|
||
// A path outside the bundle has no canonical form inside it, and the worker
|
||
// drops it — which would read as a file that was added and never written.
|
||
it('refuses a path that escapes the bundle', () => {
|
||
expect(dbtModulePath('../secrets.sql', {})).toEqual({ error: expect.stringContaining('..') })
|
||
expect(dbtModulePath('/etc/x.sql', {})).toEqual({ error: expect.stringContaining('relative') })
|
||
})
|
||
|
||
it('refuses an extension dbt does not read', () => {
|
||
expect(dbtModulePath('models/x.txt', {})).toEqual({
|
||
error: expect.stringContaining('must end with')
|
||
})
|
||
})
|
||
})
|
||
|
||
// Every write path canonicalises, so a read that compares the constant exactly
|
||
// would neither find a project imported under a redundant spelling nor protect
|
||
// it from deletion.
|
||
it('resolves the key a bundle actually holds the project file under', () => {
|
||
expect(dbtProjectFileKey({ './dbt_project.yml': mod(PROJECT) })).toBe('./dbt_project.yml')
|
||
expect(dbtProjectFileKey({})).toBeUndefined()
|
||
})
|
||
|
||
describe('dbtModelSelector', () => {
|
||
// Package-qualified, because a bare leaf name also matches a dependency
|
||
// package's model of the same name.
|
||
it('selects a model under the project’s own model-paths', () => {
|
||
const bundle = { 'dbt_project.yml': mod(PROJECT), 'models/orders.sql': mod('select 1') }
|
||
expect(dbtModelSelector(bundle, 'models/orders.sql')).toBe('orders,package:jaffle')
|
||
})
|
||
|
||
// A project may put its models anywhere; a macro or singular test is `.sql`
|
||
// too and is not selectable by name, so those fall back to the whole project.
|
||
it('honours a custom model-paths and skips what is not a model', () => {
|
||
const bundle = {
|
||
'dbt_project.yml': mod('name: jaffle\nmodel-paths: ["transform"]\n'),
|
||
'transform/orders.sql': mod('select 1'),
|
||
'macros/cents.sql': mod('{% macro cents() %}{% endmacro %}')
|
||
}
|
||
expect(dbtModelSelector(bundle, 'transform/orders.sql')).toBe('orders,package:jaffle')
|
||
expect(dbtModelSelector(bundle, 'macros/cents.sql')).toBeUndefined()
|
||
})
|
||
|
||
it('finds the project file under a redundant spelling', () => {
|
||
const bundle = { './dbt_project.yml': mod(PROJECT), 'models/orders.sql': mod('select 1') }
|
||
expect(dbtModelSelector(bundle, 'models/orders.sql')).toBe('orders,package:jaffle')
|
||
})
|
||
})
|